Merge branch 'release-4.5'
diff --git a/.gitlab/ci/configure_windows_clang_ninja_novs.cmake b/.gitlab/ci/configure_windows_clang_ninja_novs.cmake index 564f96f..96fde34 100644 --- a/.gitlab/ci/configure_windows_clang_ninja_novs.cmake +++ b/.gitlab/ci/configure_windows_clang_ninja_novs.cmake
@@ -1,6 +1,3 @@ -# FindOpenMP works only in a VS development environment. -set(CMake_TEST_FindOpenMP "OFF" CACHE BOOL "") - # Microsoft Assembler discovery works only in a VS development environment. set(CMake_TEST_ASM_MASM "OFF" CACHE BOOL "") set(CMake_TEST_ASM_MARMASM "OFF" CACHE BOOL "")
diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst index ec9e51e..cc34707 100644 --- a/Help/command/add_custom_command.rst +++ b/Help/command/add_custom_command.rst
@@ -669,6 +669,10 @@ do for the :command:`add_custom_command(OUTPUT)` form of the command. At least one ``COMMAND`` must be given, see policy :policy:`CMP0175`. + If multiple custom commands are added to the same build event of the same + target, they are executed sequentially in the order of the calls to + ``add_custom_command``. + .. note:: Because generator expressions can be used in custom commands, it is possible to define ``COMMAND`` lines or whole custom commands
diff --git a/Help/command/cmake_parse_arguments.rst b/Help/command/cmake_parse_arguments.rst index e5505bc..5e9ddc4 100644 --- a/Help/command/cmake_parse_arguments.rst +++ b/Help/command/cmake_parse_arguments.rst
@@ -32,6 +32,7 @@ ``ARGV#`` variables of the calling function. The parsing starts with the ``<N>``-th argument, where ``<N>`` is an unsigned integer. This allows for the values to have special characters like ``;`` in them. + Arguments are numbered starting from 0. .. versionadded:: 4.4 The ``PARSE_ARGN`` signature is only for use in a :command:`function`
diff --git a/Help/command/ctest_start.rst b/Help/command/ctest_start.rst index 9184fac..30230b5 100644 --- a/Help/command/ctest_start.rst +++ b/Help/command/ctest_start.rst
@@ -58,6 +58,10 @@ in the first ``ctest_start()`` command, a warning will be issued, and the new model and group will be used. + .. versionadded:: 4.6 + The ``TAG`` file is read from, and written to, the output directory + selected by :variable:`CTEST_OUTPUT_DIRECTORY`. + ``QUIET`` .. versionadded:: 3.3
diff --git a/Help/command/ctest_test.rst b/Help/command/ctest_test.rst index 5a0a99c..2b75070 100644 --- a/Help/command/ctest_test.rst +++ b/Help/command/ctest_test.rst
@@ -214,8 +214,9 @@ .. versionadded:: 4.4 Specify the ``<tool>`` used for collecting coverage during the running - of the tests. See the CTest :ref:`CoverageTool <ctest-CoverageTool>` - setting for details. + of the tests. If not specified the :variable:`CTEST_TEST_COVERAGE_TOOL` + variable will be checked. See the CTest + :ref:`CoverageTool <ctest-CoverageTool>` setting for details. ``PRESET <preset>`` .. versionadded:: 4.4
diff --git a/Help/command/target_precompile_headers.rst b/Help/command/target_precompile_headers.rst index aa18024..ae6bd45 100644 --- a/Help/command/target_precompile_headers.rst +++ b/Help/command/target_precompile_headers.rst
@@ -126,6 +126,9 @@ * To prevent precompile headers from being used when compiling a specific source file, see the :prop_sf:`SKIP_PRECOMPILE_HEADERS` source file property. +* To get compiler warnings for the precompiled headers themselves, which are + suppressed by default, see the :prop_tgt:`PCH_WARNINGS` target property. + * :command:`target_compile_definitions` * :command:`target_compile_features` * :command:`target_compile_options`
diff --git a/Help/dev/experimental.rst b/Help/dev/experimental.rst index f2c6473..26e9d66 100644 --- a/Help/dev/experimental.rst +++ b/Help/dev/experimental.rst
@@ -86,7 +86,7 @@ In order to activate support for Rust, set * variable ``CMAKE_EXPERIMENTAL_RUST`` to -* value ``b6fdddce-bf66-41a5-bc5f-077f6fa4d2a1``. +* value ``628f8f9f-d7dc-4a06-9aaf-d4ede4426ddf``. 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
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 6b2f4ed..afca9a9 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst
@@ -36,10 +36,10 @@ .. code-block:: cmake - cmake_minimum_required(VERSION 3.10...4.4) + cmake_minimum_required(VERSION 3.10...4.5) This uses the ``<min>...<policy_max>`` syntax to enable the ``NEW`` behaviors -of policies introduced in CMake 4.4 and earlier while only requiring a +of policies introduced in CMake 4.5 and earlier while only requiring a minimum version of CMake 3.10. The project is expected to work with both the ``OLD`` and ``NEW`` behaviors of policies introduced between those versions.
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index abef499..bb7a520 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst
@@ -429,6 +429,7 @@ /prop_tgt/OUTPUT_NAME /prop_tgt/OUTPUT_NAME_CONFIG /prop_tgt/PCH_INSTANTIATE_TEMPLATES + /prop_tgt/PCH_WARNINGS /prop_tgt/PCH_WARN_INVALID /prop_tgt/PDB_NAME /prop_tgt/PDB_NAME_CONFIG
diff --git a/Help/manual/cmake-toolchains.7.rst b/Help/manual/cmake-toolchains.7.rst index 21363c7..875be7d 100644 --- a/Help/manual/cmake-toolchains.7.rst +++ b/Help/manual/cmake-toolchains.7.rst
@@ -348,6 +348,11 @@ :variable:`CMAKE_SYSTEM_NAME` variable to ``Android``. Further configuration is specific to the Android development environment to be used. +.. note:: + + This documentation may not reflect behavior of the CMake toolchain file + provided by the Android NDK, as it is maintained separately from CMake. + For :ref:`Visual Studio Generators`, CMake expects :ref:`NVIDIA Nsight Tegra Visual Studio Edition <Cross Compiling for Android with NVIDIA Nsight Tegra Visual Studio Edition>` or the :ref:`Visual Studio tools for Android
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 922f07b..c92d14f 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst
@@ -572,6 +572,7 @@ /variable/CMAKE_OSX_DEPLOYMENT_TARGET /variable/CMAKE_OSX_SYSROOT /variable/CMAKE_PCH_INSTANTIATE_TEMPLATES + /variable/CMAKE_PCH_WARNINGS /variable/CMAKE_PCH_WARN_INVALID /variable/CMAKE_PDB_OUTPUT_DIRECTORY /variable/CMAKE_PDB_OUTPUT_DIRECTORY_CONFIG @@ -799,6 +800,7 @@ /variable/CTEST_MEMORYCHECK_TYPE /variable/CTEST_NIGHTLY_START_TIME /variable/CTEST_NOTES_FILES + /variable/CTEST_OUTPUT_DIRECTORY /variable/CTEST_P4_CLIENT /variable/CTEST_P4_COMMAND /variable/CTEST_P4_OPTIONS
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index 3b590a4..d36cfd2 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst
@@ -1587,12 +1587,13 @@ .. deprecated:: 3.17 - Remove the file(s). The planned behavior was that if any of the - listed files already do not exist, the command returns a non-zero exit code, - but no message is logged. The ``-f`` option changes the behavior to return a - zero exit code (i.e. success) in such situations instead. - ``remove`` does not follow symlinks. That means it remove only symlinks - and not files it point to. + Remove the file(s). The planned behavior was that if any of the listed files + already do not exist, the command returns a non-zero exit code. The ``-f`` + option changes the behavior to return a zero exit code (i.e., success) in + such situations instead. + + ``remove`` does not follow symlinks (i.e., it removes only a symlink, not + what it points to). The implementation was buggy and always returned 0. It cannot be fixed without breaking backwards compatibility. Use ``rm`` instead.
diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst index 795bbcd..883e33f 100644 --- a/Help/manual/ctest.1.rst +++ b/Help/manual/ctest.1.rst
@@ -472,6 +472,27 @@ build directory. If not specified, the current directory is used. See also :ctest-dashboard-option:`--build-dir`. +.. option:: --output-dir <path> + + .. versionadded:: 4.6 + + Specify the directory in which to write output files. + + CTest writes the files it produces during a run, such as the ``TAG`` file, + the logs under ``Temporary``, and the XML files submitted to a dashboard, + into a single output directory. By default this is the ``Testing`` + directory under the build tree. This option writes them elsewhere; the + path may be outside the build tree, and a relative path is interpreted + with respect to the build directory. + + This makes it possible to run more than one :program:`ctest` process + against the same build tree, for example to run different subsets of the + tests with :ctest-option:`--tests-from-file`, without the processes + overwriting each other's output. + + When running a dashboard script, use the :variable:`CTEST_OUTPUT_DIRECTORY` + variable instead. + .. option:: --test-output-size-passed <size> .. versionadded:: 3.4 @@ -1180,6 +1201,25 @@ * `CTest Script`_ variable: :variable:`CTEST_SOURCE_DIRECTORY` * :module:`CTest` module variable: :variable:`PROJECT_SOURCE_DIR` +``BuildName`` + Describe the dashboard client platform with a short string. + (Operating system, compiler, etc.) + In a `CTest Script`_, :command:`ctest_start` initializes this setting + from :variable:`CTEST_BUILD_NAME`. + + * `CTest Script`_ variable: :variable:`CTEST_BUILD_NAME` + * :module:`CTest` module variable: ``BUILDNAME`` + +``Site`` + Describe the dashboard client host site with a short string. + (Hostname, domain, etc.) + In a `CTest Script`_, :command:`ctest_start` initializes this setting + from :variable:`CTEST_SITE`. + + * `CTest Script`_ variable: :variable:`CTEST_SITE` + * :module:`CTest` module variable: ``SITE``, + initialized by the :command:`site_name` command + ``CheckoutCommand`` Command-line to run before the start step to initialize the source directory, e.g. to perform an initial checkout from version control. @@ -1723,13 +1763,6 @@ Configuration settings include: -``BuildName`` - Describe the dashboard client platform with a short string. - (Operating system, compiler, etc.) - - * `CTest Script`_ variable: :variable:`CTEST_BUILD_NAME` - * :module:`CTest` module variable: ``BUILDNAME`` - ``CDashVersion`` Legacy option. Not used. @@ -1827,14 +1860,6 @@ * `CTest Script`_ variable: :variable:`CTEST_SCP_COMMAND` * :module:`CTest` module variable: ``SCPCOMMAND`` -``Site`` - Describe the dashboard client host site with a short string. - (Hostname, domain, etc.) - - * `CTest Script`_ variable: :variable:`CTEST_SITE` - * :module:`CTest` module variable: ``SITE``, - initialized by the :command:`site_name` command - ``SubmitURL`` The ``http`` or ``https`` URL of the dashboard server to send the submission to.
diff --git a/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst b/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst index 562367b..e7885d5 100644 --- a/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst +++ b/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst
@@ -4,7 +4,8 @@ .. versionadded:: 3.4 This property is implemented only when ``<LANG>`` is ``C``, ``CXX``, -``Fortran``, ``HIP``, ``ISPC``, ``OBJC``, ``OBJCXX``, ``CUDA``, or ``SYCL``. +``Fortran``, ``HIP``, ``ISPC``, ``OBJC``, ``OBJCXX``, ``CUDA``, ``SYCL``, or +``Rust``. .. versionchanged:: 4.5 Added support for ``SYCL``. @@ -12,6 +13,12 @@ .. note:: SYCL support is experimental and gated by ``CMAKE_EXPERIMENTAL_SYCL``. +.. versionchanged:: 4.6 + Added support for ``Rust``. + + .. note:: + Rust support is experimental and gated by ``CMAKE_EXPERIMENTAL_RUST``. + Specify a :ref:`semicolon-separated list <CMake Language Lists>` containing a command line for a compiler launching tool. The :ref:`Makefile Generators` and the :generator:`Ninja` generator will run this tool and pass the compiler and
diff --git a/Help/prop_tgt/PCH_WARNINGS.rst b/Help/prop_tgt/PCH_WARNINGS.rst new file mode 100644 index 0000000..7c30ad9 --- /dev/null +++ b/Help/prop_tgt/PCH_WARNINGS.rst
@@ -0,0 +1,27 @@ +PCH_WARNINGS +------------ + +.. versionadded:: 4.6 + +Enable compiler warnings for the headers listed in :prop_tgt:`PRECOMPILE_HEADERS`. + +By default CMake marks the generated precompiled header file as a system +header, which suppresses the diagnostics of every header it includes. This +means that enabling precompiled headers silently hides warnings that the same +build would produce without them. + +Set this property to true to omit the system header marker so that the headers +collected into the precompiled header are diagnosed as they would be in a +build without precompiled headers. The diagnostics are reported once, while +compiling the precompiled header itself, rather than once per source file. + +This property is initialized by the value of the :variable:`CMAKE_PCH_WARNINGS` +variable when the target is created. + +The :generator:`Xcode` generator never adds the system header marker, so this +property has no effect there. + +Targets that reuse a precompiled header through +:prop_tgt:`PRECOMPILE_HEADERS_REUSE_FROM` do not generate a precompiled header +of their own, so this property has no effect on them either. Set it on the +target named by :prop_tgt:`PRECOMPILE_HEADERS_REUSE_FROM` instead.
diff --git a/Help/release/dev/0-sample-topic.rst b/Help/release/dev/0-sample-topic.rst new file mode 100644 index 0000000..e4cc01e --- /dev/null +++ b/Help/release/dev/0-sample-topic.rst
@@ -0,0 +1,7 @@ +0-sample-topic +-------------- + +* This is a sample release note for the change in a topic. + Developers should add similar notes for each topic branch + making a noteworthy change. Each document should be named + and titled to match the topic name to avoid merge conflicts.
diff --git a/Help/release/dev/FindOpenMP-clang-libomp.rst b/Help/release/dev/FindOpenMP-clang-libomp.rst new file mode 100644 index 0000000..214951f --- /dev/null +++ b/Help/release/dev/FindOpenMP-clang-libomp.rst
@@ -0,0 +1,7 @@ +FindOpenMP-clang-libomp +----------------------- + +* The :module:`FindOpenMP` module, with Clang targeting the MSVC ABI, now + prefers the OpenMP runtime shipped with the compiler, e.g. ``libomp.dll``, + over the one shipped with MSVC. Set ``OpenMP_libomp_LIBRARY`` to select + a different library.
diff --git a/Help/release/dev/ctest-output-dir.rst b/Help/release/dev/ctest-output-dir.rst new file mode 100644 index 0000000..ee49cb8 --- /dev/null +++ b/Help/release/dev/ctest-output-dir.rst
@@ -0,0 +1,9 @@ +ctest-output-dir +---------------- + +* :manual:`ctest(1)` gained an :option:`--output-dir <ctest --output-dir>` + option, and the corresponding :variable:`CTEST_OUTPUT_DIRECTORY` variable + for :ref:`Dashboard Client` scripts, to specify the directory in which + CTest writes its output files. Previously these were always written to + the ``Testing`` directory under the build tree, which prevented running + more than one :program:`ctest` process against the same build tree.
diff --git a/Help/release/dev/pch-warnings.rst b/Help/release/dev/pch-warnings.rst new file mode 100644 index 0000000..a1d7994 --- /dev/null +++ b/Help/release/dev/pch-warnings.rst
@@ -0,0 +1,15 @@ +pch-warnings +------------ + +* The :prop_tgt:`PCH_WARNINGS` target property, and its initializing + :variable:`CMAKE_PCH_WARNINGS` variable, were added to enable compiler + warnings for the headers collected into a precompiled header. Previously + the generated precompiled header was always marked as a system header, + which suppressed those warnings. + + The system header marker now comes from an internal + ``CMAKE_PCH_SYSTEM_HEADER_PRAGMA`` variable instead of from + ``CMAKE_PCH_PROLOGUE``. Projects that cleared or replaced + ``CMAKE_PCH_PROLOGUE`` in order to drop the marker no longer affect it, + and must set :prop_tgt:`PCH_WARNINGS` or :variable:`CMAKE_PCH_WARNINGS` + instead.
diff --git a/Help/release/dev/try_compile-module-base-dirs.rst b/Help/release/dev/try_compile-module-base-dirs.rst new file mode 100644 index 0000000..7096e66 --- /dev/null +++ b/Help/release/dev/try_compile-module-base-dirs.rst
@@ -0,0 +1,7 @@ +try_compile-module-base-dirs +---------------------------- + +* The :command:`try_compile` and :command:`try_run` commands now accept + ``CXX_MODULE`` sources outside of the calling project's source directory, + including copies made by ``SOURCE_FROM_CONTENT``, ``SOURCE_FROM_FILE`` + and ``SOURCE_FROM_VAR``. Previously such sources caused an error.
diff --git a/Help/release/index.rst b/Help/release/index.rst index 8bd51f3..9bc1bee 100644 --- a/Help/release/index.rst +++ b/Help/release/index.rst
@@ -7,6 +7,8 @@ This file should include the adjacent "dev.txt" file in development versions but not in release versions. +.. include:: dev.txt + Releases ========
diff --git a/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst b/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst index 13a02fd..dd4c508 100644 --- a/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst +++ b/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst
@@ -6,7 +6,7 @@ Default value for :prop_tgt:`<LANG>_COMPILER_LAUNCHER` target property. This variable is used to initialize the property on each target as it is created. This is done only when ``<LANG>`` is ``C``, ``CXX``, ``Fortran``, -``HIP``, ``ISPC``, ``OBJC``, ``OBJCXX``, ``CUDA``, or ``SYCL``. +``HIP``, ``ISPC``, ``OBJC``, ``OBJCXX``, ``CUDA``, ``SYCL`` or ``Rust``. .. versionchanged:: 4.5 Added support for ``SYCL``. @@ -14,5 +14,11 @@ .. note:: SYCL support is experimental and gated by ``CMAKE_EXPERIMENTAL_SYCL``. +.. versionchanged:: 4.6 + Added support for ``Rust``. + + .. note:: + Rust support is experimental and gated by ``CMAKE_EXPERIMENTAL_RUST``. + This variable is initialized to the :envvar:`CMAKE_<LANG>_COMPILER_LAUNCHER` environment variable if it is set.
diff --git a/Help/variable/CMAKE_PCH_WARNINGS.rst b/Help/variable/CMAKE_PCH_WARNINGS.rst new file mode 100644 index 0000000..f87d621 --- /dev/null +++ b/Help/variable/CMAKE_PCH_WARNINGS.rst
@@ -0,0 +1,7 @@ +CMAKE_PCH_WARNINGS +------------------ + +.. versionadded:: 4.6 + +This variable is used to initialize the :prop_tgt:`PCH_WARNINGS` +property of targets when they are created.
diff --git a/Help/variable/CTEST_BUILD_NAME.rst b/Help/variable/CTEST_BUILD_NAME.rst index 76d7ef7..cd32e33 100644 --- a/Help/variable/CTEST_BUILD_NAME.rst +++ b/Help/variable/CTEST_BUILD_NAME.rst
@@ -6,3 +6,6 @@ Specify the CTest ``BuildName`` setting in a :manual:`ctest(1)` :ref:`Dashboard Client` script, or on the :program:`ctest` command line via the :ctest-dashboard-option:`-D` option. + +In a dashboard script, set this variable before calling :command:`ctest_start`, +which initializes the ``BuildName`` setting from it.
diff --git a/Help/variable/CTEST_OUTPUT_DIRECTORY.rst b/Help/variable/CTEST_OUTPUT_DIRECTORY.rst new file mode 100644 index 0000000..1cc0e0e --- /dev/null +++ b/Help/variable/CTEST_OUTPUT_DIRECTORY.rst
@@ -0,0 +1,22 @@ +CTEST_OUTPUT_DIRECTORY +---------------------- + +.. versionadded:: 4.6 + +Specify the directory in which :manual:`ctest(1)` writes its output files +in a :ref:`Dashboard Client` script. + +CTest writes the files it produces during a run, such as the ``TAG`` file, +the logs under ``Temporary``, and the XML files submitted to a dashboard, +into a single output directory. By default this is the ``Testing`` +directory under :variable:`CTEST_BINARY_DIRECTORY`. Set this variable +before calling :command:`ctest_start` to write them elsewhere; the path may +be outside the build tree, and a relative path is interpreted with respect +to :variable:`CTEST_BINARY_DIRECTORY`. + +This makes it possible to run more than one :program:`ctest` process +against the same build tree, for example to run different subsets of the +tests with the ``INCLUDE_FROM_FILE`` option of :command:`ctest_test`, +without the processes overwriting each other's output. + +Outside of a dashboard script, use the :option:`ctest --output-dir` option.
diff --git a/Help/variable/CTEST_SITE.rst b/Help/variable/CTEST_SITE.rst index df430bd..16dd72d 100644 --- a/Help/variable/CTEST_SITE.rst +++ b/Help/variable/CTEST_SITE.rst
@@ -6,3 +6,6 @@ Specify the CTest ``Site`` setting in a :manual:`ctest(1)` :ref:`Dashboard Client` script, or on the :program:`ctest` command line via the :ctest-dashboard-option:`-D` option. + +In a dashboard script, set this variable before calling :command:`ctest_start`, +which initializes the ``Site`` setting from it.
diff --git a/Help/variable/include/CMAKE_FIND_ROOT_PATH_MODE_XXX.rst b/Help/variable/include/CMAKE_FIND_ROOT_PATH_MODE_XXX.rst index ab65e09..8421be7 100644 --- a/Help/variable/include/CMAKE_FIND_ROOT_PATH_MODE_XXX.rst +++ b/Help/variable/include/CMAKE_FIND_ROOT_PATH_MODE_XXX.rst
@@ -2,7 +2,12 @@ :variable:`CMAKE_SYSROOT` are used by |FIND_XXX|. If set to ``ONLY``, then only the roots in :variable:`CMAKE_FIND_ROOT_PATH` -will be searched. If set to ``NEVER``, then the roots in -:variable:`CMAKE_FIND_ROOT_PATH` will be ignored and only the host system -root will be used. If set to ``BOTH``, then the host system paths and the -paths in :variable:`CMAKE_FIND_ROOT_PATH` will be searched. +and :variable:`CMAKE_SYSROOT`, and directories below +:variable:`CMAKE_STAGING_PREFIX`, will be searched. If set to ``NEVER``, then +those roots will be ignored and only the host system root will be used. +If set to ``BOTH``, then the host system paths and the paths in those roots +will be searched. + +If this variable is not set, ``BOTH`` is used. Toolchain files or +platform-specific initialization may set a different value. Explicit +root path options given to |FIND_XXX| take precedence over this variable.
diff --git a/Modules/CMakeRustInformation.cmake b/Modules/CMakeRustInformation.cmake index e7d41fd..62a1c29 100644 --- a/Modules/CMakeRustInformation.cmake +++ b/Modules/CMakeRustInformation.cmake
@@ -3,6 +3,11 @@ include(CMakeLanguageInformation) +if(NOT CMAKE_Rust_COMPILER_LAUNCHER AND DEFINED ENV{CMAKE_Rust_COMPILER_LAUNCHER}) + set(CMAKE_Rust_COMPILER_LAUNCHER "$ENV{CMAKE_Rust_COMPILER_LAUNCHER}" + CACHE STRING "Compiler launcher for Rust.") +endif() + set(CMAKE_Rust_OUTPUT_EXTENSION .rlib) # Other values are supported to generate various outputs (LLVM bitcode, or IR,
diff --git a/Modules/CTestCoverageCollectGCOV.cmake b/Modules/CTestCoverageCollectGCOV.cmake index acde687..f00ffd9 100644 --- a/Modules/CTestCoverageCollectGCOV.cmake +++ b/Modules/CTestCoverageCollectGCOV.cmake
@@ -237,6 +237,9 @@ return() endif() # setup the dir for the coverage files + # FIXME(#27518): This staging directory ignores CTEST_OUTPUT_DIRECTORY. + # Moving it is not a simple substitution: the .gcov files are + # globbed relative to binary_dir and tar runs from there. set(coverage_dir "${binary_dir}/Testing/CoverageInfo") file(MAKE_DIRECTORY "${coverage_dir}") # run gcov, this will produce the .gcov files in the current
diff --git a/Modules/CTestTargets.cmake b/Modules/CTestTargets.cmake index 3759253..3c4dd3f 100644 --- a/Modules/CTestTargets.cmake +++ b/Modules/CTestTargets.cmake
@@ -10,7 +10,9 @@ message(FATAL_ERROR "Do not include(CTest) before calling project().") endif() -# make directories in the binary tree +# Make directories in the binary tree. This is only the default output +# directory: CTEST_OUTPUT_DIRECTORY and --output-dir are chosen per ctest +# invocation and are not known here, so ctest creates those itself at run time. file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/Testing/Temporary) get_filename_component(CMAKE_HOST_PATH ${CMAKE_COMMAND} PATH) set(CMAKE_TARGET_PATH ${EXECUTABLE_OUTPUT_PATH})
diff --git a/Modules/Compiler/Clang.cmake b/Modules/Compiler/Clang.cmake index 8c6bb16..d2de5e9 100644 --- a/Modules/Compiler/Clang.cmake +++ b/Modules/Compiler/Clang.cmake
@@ -109,7 +109,7 @@ set(CMAKE_PCH_EXTENSION .pch) if (NOT CMAKE_GENERATOR MATCHES "Xcode") - set(CMAKE_PCH_PROLOGUE "#pragma clang system_header") + set(CMAKE_PCH_SYSTEM_HEADER_PRAGMA "#pragma clang system_header") endif() if(CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 11.0.0 AND NOT __is_apple_clang) set(CMAKE_${lang}_COMPILE_OPTIONS_INSTANTIATE_TEMPLATES_PCH -fpch-instantiate-templates)
diff --git a/Modules/Compiler/GNU.cmake b/Modules/Compiler/GNU.cmake index e4cccb7..4c1041b 100644 --- a/Modules/Compiler/GNU.cmake +++ b/Modules/Compiler/GNU.cmake
@@ -142,7 +142,7 @@ if(NOT "x${lang}" STREQUAL "xFortran") set(CMAKE_PCH_EXTENSION .gch) if (NOT CMAKE_GENERATOR MATCHES "Xcode") - set(CMAKE_PCH_PROLOGUE "#pragma GCC system_header") + set(CMAKE_PCH_SYSTEM_HEADER_PRAGMA "#pragma GCC system_header") endif() set(CMAKE_${lang}_COMPILE_OPTIONS_INVALID_PCH -Winvalid-pch) set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -include <PCH_HEADER>)
diff --git a/Modules/Compiler/IntelLLVM.cmake b/Modules/Compiler/IntelLLVM.cmake index 8218f03..2577071 100644 --- a/Modules/Compiler/IntelLLVM.cmake +++ b/Modules/Compiler/IntelLLVM.cmake
@@ -115,7 +115,9 @@ else() # Precompile Headers set(CMAKE_PCH_EXTENSION .pch) - set(CMAKE_PCH_PROLOGUE "#pragma clang system_header") + if (NOT CMAKE_GENERATOR MATCHES "Xcode") + set(CMAKE_PCH_SYSTEM_HEADER_PRAGMA "#pragma clang system_header") + endif() set(CMAKE_${lang}_COMPILE_OPTIONS_INSTANTIATE_TEMPLATES_PCH -fpch-instantiate-templates) set(CMAKE_${lang}_COMPILE_OPTIONS_INVALID_PCH -Winvalid-pch) set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Xclang -include-pch -Xclang <PCH_FILE> -Xclang -include -Xclang <PCH_HEADER>)
diff --git a/Modules/Compiler/LCC.cmake b/Modules/Compiler/LCC.cmake index 5657db1..02b5ced 100644 --- a/Modules/Compiler/LCC.cmake +++ b/Modules/Compiler/LCC.cmake
@@ -91,7 +91,7 @@ if(NOT "x${lang}" STREQUAL "xFortran") set(CMAKE_PCH_EXTENSION .gch) if (NOT CMAKE_GENERATOR MATCHES "Xcode") - set(CMAKE_PCH_PROLOGUE "#pragma GCC system_header") + set(CMAKE_PCH_SYSTEM_HEADER_PRAGMA "#pragma GCC system_header") endif() set(CMAKE_${lang}_COMPILE_OPTIONS_INVALID_PCH -Winvalid-pch) set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -include <PCH_HEADER>)
diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake index baea4d6..617774d 100644 --- a/Modules/FindOpenMP.cmake +++ b/Modules/FindOpenMP.cmake
@@ -67,9 +67,11 @@ ``OpenMP_RUNTIME_MSVC`` .. versionadded:: 3.30 - Specify the `OpenMP Runtime <msvc-openmp_>`_ when compiling with MSVC. - If set to a non-empty value, such as ``experimental`` or ``llvm``, it - will be passed as the value of the ``-openmp:`` flag. + Specify the `OpenMP Runtime <msvc-openmp_>`_ when compiling with the + MSVC compiler (``cl``). If set to a non-empty value, such as + ``experimental`` or ``llvm``, it will be passed as the value of the + ``-openmp:`` flag. This has no effect with other compilers, including + ``clang-cl``. .. _`msvc-openmp`: https://learn.microsoft.com/en-us/cpp/build/reference/openmp-enable-openmp-2-0-support @@ -180,6 +182,17 @@ to know what include directories are needed, or preferably the ``OpenMP::OpenMP_<lang>`` imported target. +For Clang targeting the MSVC ABI, the module searches for the OpenMP runtime +library, preferring the one shipped with the compiler. A different library +can be provided directly by setting the ``OpenMP_libomp_LIBRARY`` cache +variable. Programs linked with it need the matching runtime DLL, such as +``libomp.dll``, next to them or on ``PATH`` when they run. + +.. versionchanged:: 4.6 + In previous CMake versions, the first ``libomp`` found through the ``LIB`` + environment variable was used, such as the one provided with MSVC for its + ``-openmp:llvm`` option. + Examples ^^^^^^^^ @@ -201,7 +214,12 @@ set(OMP_FLAG_GNU "-fopenmp") set(OMP_FLAG_LCC "-fopenmp") - set(OMP_FLAG_Clang "-fopenmp=libomp" "-fopenmp=libiomp5" "-fopenmp" "-Xclang -fopenmp") + if("x${CMAKE_${LANG}_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC") + # clang-cl ignores the GNU-style spellings + set(OMP_FLAG_Clang "-Xclang -fopenmp") + else() + set(OMP_FLAG_Clang "-fopenmp=libomp" "-fopenmp=libiomp5" "-fopenmp" "-Xclang -fopenmp") + endif() set(OMP_FLAG_DPClang "${OMP_FLAG_Clang}") set(OMP_FLAG_AppleClang "-Xclang -fopenmp") set(OMP_FLAG_HP "+Oopenmp") @@ -500,23 +518,52 @@ endif() elseif(CMAKE_${LANG}_COMPILER_ID MATCHES "^(Clang|DPClang)$" AND WIN32) # Check for separate OpenMP library for Clang on Windows - find_library(OpenMP_libomp_LIBRARY - NAMES libomp libgomp libiomp5 - HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES} - ) - mark_as_advanced(OpenMP_libomp_LIBRARY) if(OpenMP_libomp_LIBRARY) + set(_OpenMP_libomp_CANDIDATES "${OpenMP_libomp_LIBRARY}") + else() + if(CMAKE_${LANG}_SIMULATE_ID STREQUAL "MSVC") + # Preferring the runtime next to the compiler, as clang's driver does + get_filename_component(_OpenMP_COMPILER_DIR "${CMAKE_${LANG}_COMPILER}" DIRECTORY) + find_library(_OpenMP_libomp_COMPILER + NAMES libomp libgomp libiomp5 + HINTS "${_OpenMP_COMPILER_DIR}/../lib" + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH + NO_CACHE + ) + endif() + find_library(_OpenMP_libomp_DEFAULT + NAMES libomp libgomp libiomp5 + HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES} + NO_CACHE + ) + set(_OpenMP_libomp_CANDIDATES ${_OpenMP_libomp_COMPILER} ${_OpenMP_libomp_DEFAULT}) + list(FILTER _OpenMP_libomp_CANDIDATES EXCLUDE REGEX "-NOTFOUND$") + list(REMOVE_DUPLICATES _OpenMP_libomp_CANDIDATES) + endif() + # Taking the first that links, since the compiler's own may not suit a cross target + set(_OpenMP_libomp_WORKS "OpenMP_libomp_LIBRARY-NOTFOUND") + foreach(_OpenMP_libomp IN LISTS _OpenMP_libomp_CANDIDATES) try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT - LOG_DESCRIPTION "Trying ${LANG} OpenMP compiler with '${OpenMP_libomp_LIBRARY}'" + LOG_DESCRIPTION "Trying ${LANG} OpenMP compiler with '${_OpenMP_libomp}'" COMPILE_DEFINITIONS ${OPENMP_FLAG} - LINK_LIBRARIES ${OpenMP_libomp_LIBRARY} + LINK_LIBRARIES ${_OpenMP_libomp} ) if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}) - set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE) - set("${OPENMP_LIB_NAMES_VAR}" "libomp" PARENT_SCOPE) + set(_OpenMP_libomp_WORKS "${_OpenMP_libomp}") break() endif() + endforeach() + if(NOT OpenMP_libomp_LIBRARY) + set(OpenMP_libomp_LIBRARY "${_OpenMP_libomp_WORKS}" CACHE FILEPATH + "Path to the libomp library for OpenMP" FORCE) + endif() + mark_as_advanced(OpenMP_libomp_LIBRARY) + if(_OpenMP_libomp_WORKS) + set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE) + set("${OPENMP_LIB_NAMES_VAR}" "libomp" PARENT_SCOPE) + break() endif() endif() set("${OPENMP_LIB_NAMES_VAR}" "NOTFOUND" PARENT_SCOPE)
diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake index 3857750..d51f98b 100644 --- a/Modules/FindPkgConfig.cmake +++ b/Modules/FindPkgConfig.cmake
@@ -586,6 +586,18 @@ set(${var} ${value} CACHE INTERNAL "") endmacro() +# pkg-config <0.29.1 and pkgconf <1.5.1 leave surrounding quotes on variables +macro(_pkgconfig_unquote _var) + if((PkgConfig_VERSION VERSION_LESS 0.29.1) OR + (PkgConfig_VERSION VERSION_GREATER_EQUAL 1.0 AND PkgConfig_VERSION VERSION_LESS 1.5.1)) + if(${_var} MATCHES "^\"(.*)\"$") + set(${_var} "${CMAKE_MATCH_1}") + elseif(${_var} MATCHES "^'(.*)'$") + set(${_var} "${CMAKE_MATCH_1}") + endif() + endif() +endmacro() + # Invokes pkgconfig, cleans up the result and sets variables macro(_pkgconfig_invoke _pkglist _prefix _varname _regexp) set(_pkgconfig_invoke_result) @@ -606,16 +618,7 @@ string(REGEX REPLACE "${_regexp}" " " _pkgconfig_invoke_result "${_pkgconfig_invoke_result}") endif() - # pkg-config <0.29.1 and pkgconf <1.5.1 prints quoted variables without unquoting - # unquote only if quotes are first and last characters - if((PkgConfig_VERSION VERSION_LESS 0.29.1) OR - (PkgConfig_VERSION VERSION_GREATER_EQUAL 1.0 AND PkgConfig_VERSION VERSION_LESS 1.5.1)) - if (_pkgconfig_invoke_result MATCHES "^\"(.*)\"$") - set(_pkgconfig_invoke_result "${CMAKE_MATCH_1}") - elseif(_pkgconfig_invoke_result MATCHES "^'(.*)'$") - set(_pkgconfig_invoke_result "${CMAKE_MATCH_1}") - endif() - endif() + _pkgconfig_unquote(_pkgconfig_invoke_result) # pkg-config can represent "spaces within an argument" by backslash-escaping the space. # UNIX_COMMAND mode treats backslash-escaped spaces as "not a space that delimits arguments". @@ -1010,15 +1013,7 @@ function(_pkgconfig_parse_flags _prefix _flags_output _is_libs _static) string(REGEX REPLACE "[\r\n]" " " _pkgconfig_pf_output "${_flags_output}") - # Unquote if needed (same logic as _pkgconfig_invoke) - if((PkgConfig_VERSION VERSION_LESS 0.29.1) OR - (PkgConfig_VERSION VERSION_GREATER_EQUAL 1.0 AND PkgConfig_VERSION VERSION_LESS 1.5.1)) - if(_pkgconfig_pf_output MATCHES "^\"(.*)\"$") - set(_pkgconfig_pf_output "${CMAKE_MATCH_1}") - elseif(_pkgconfig_pf_output MATCHES "^'(.*)'$") - set(_pkgconfig_pf_output "${CMAKE_MATCH_1}") - endif() - endif() + _pkgconfig_unquote(_pkgconfig_pf_output) separate_arguments(_pkgconfig_pf_list UNIX_COMMAND "${_pkgconfig_pf_output}") @@ -1205,10 +1200,10 @@ _pkgconfig_unset(${_prefix}_${_pkg_check_modules_pkg_name}_INCLUDEDIR) _pkgconfig_unset(${_prefix}_${_pkg_check_modules_pkg_name}_LIBDIR) - # --modversion validates any version constraint and prints the module - # version. We can't combine with --variable, since FDO pkg-config treats - # these as incompatible output options. - list(APPEND _pkg_check_modules_exist_query --print-errors --short-errors --modversion) + # --modversion validates any version constraint and prints the module version. + # pkgconf also honors --variable=prefix and prints the prefix + # on a second line, but freedesktop.org pkg-config ignores it + list(APPEND _pkg_check_modules_exist_query --print-errors --short-errors --modversion --variable=prefix) if (_pkg_check_modules_pkg_op) list(APPEND _pkg_check_modules_exist_query "${_pkg_check_modules_pkg_name} ${_pkg_check_modules_pkg_op} ${_pkg_check_modules_pkg_ver}") else() @@ -1232,6 +1227,23 @@ string(APPEND _pkg_check_modules_failed " - ${_pkg_check_modules_pkg}\n") else() + # An empty output means no version or prefix was printed. Otherwise, + # a second line contains the prefix when --variable=prefix was honored + string(REPLACE ";" "\\;" _pkgconfig_combined_list "${_pkgconfig_module_version}") + string(REGEX REPLACE "\n" ";" _pkgconfig_combined_list "${_pkgconfig_combined_list}") + list(LENGTH _pkgconfig_combined_list _pkgconfig_combined_len) + if(_pkgconfig_combined_len GREATER 0) + list(GET _pkgconfig_combined_list 0 _pkgconfig_module_version) + endif() + unset(_pkgconfig_${_pkg_check_modules_pkg_name}_PREFIX) + if(_pkgconfig_combined_len GREATER 1) + list(GET _pkgconfig_combined_list 1 _pkgconfig_module_prefix) + _pkgconfig_unquote(_pkgconfig_module_prefix) + separate_arguments(_pkgconfig_module_prefix UNIX_COMMAND "${_pkgconfig_module_prefix}") + # Keep a literal semicolon from becoming a backslash escape in the cache value + string(REPLACE "\\;" ";" _pkgconfig_module_prefix "${_pkgconfig_module_prefix}") + set(_pkgconfig_${_pkg_check_modules_pkg_name}_PREFIX "${_pkgconfig_module_prefix}") + endif() list(APPEND _pkg_check_modules_packages "${_pkg_check_modules_pkg_name}") set(_pkgconfig_${_pkg_check_modules_pkg_name}_VERSION "${_pkgconfig_module_version}") endif() @@ -1259,7 +1271,11 @@ endif() _pkgconfig_set(${_pkg_check_prefix}_VERSION "${_pkgconfig_${_pkg_check_modules_pkg}_VERSION}") - pkg_get_variable("${_pkg_check_prefix}_PREFIX" ${_pkg_check_modules_pkg} "prefix") + if(DEFINED _pkgconfig_${_pkg_check_modules_pkg}_PREFIX) + set("${_pkg_check_prefix}_PREFIX" "${_pkgconfig_${_pkg_check_modules_pkg}_PREFIX}") + else() + pkg_get_variable("${_pkg_check_prefix}_PREFIX" ${_pkg_check_modules_pkg} "prefix") + endif() pkg_get_variable("${_pkg_check_prefix}_INCLUDEDIR" ${_pkg_check_modules_pkg} "includedir") pkg_get_variable("${_pkg_check_prefix}_LIBDIR" ${_pkg_check_modules_pkg} "libdir") foreach (variable IN ITEMS PREFIX INCLUDEDIR LIBDIR)
diff --git a/Modules/FindTCL.cmake b/Modules/FindTCL.cmake index 96079cc..379cfe8 100644 --- a/Modules/FindTCL.cmake +++ b/Modules/FindTCL.cmake
@@ -114,6 +114,8 @@ "${TCL_TCLSH_PATH_PARENT}/lib" "${TK_WISH_PATH_PARENT}/lib" ) +# Entries built from a path not found yet are just /lib. +list(FILTER TCLTK_POSSIBLE_LIB_PATHS EXCLUDE REGEX "^/lib$") set(TCLTK_POSSIBLE_LIB_PATH_SUFFIXES lib/tcl/tcl9.1 @@ -153,6 +155,7 @@ tcl83 tcl8.3 tcl82 tcl8.2 tcl80 tcl8.0 + NAMES_PER_DIR PATHS ${TCLTK_POSSIBLE_LIB_PATHS} PATH_SUFFIXES ${TCLTK_POSSIBLE_LIB_PATH_SUFFIXES} ) @@ -169,6 +172,7 @@ tk83 tk8.3 tk82 tk8.2 tk80 tk8.0 + NAMES_PER_DIR PATHS ${TCLTK_POSSIBLE_LIB_PATHS} PATH_SUFFIXES ${TCLTK_POSSIBLE_LIB_PATH_SUFFIXES} ) @@ -205,6 +209,7 @@ "${TCL_TCLSH_PATH_PARENT}/include" "${TK_WISH_PATH_PARENT}/include" ) +list(FILTER TCLTK_POSSIBLE_INCLUDE_PATHS EXCLUDE REGEX "^/include$") set(TCLTK_POSSIBLE_INCLUDE_PATH_SUFFIXES include/tcl${TK_LIBRARY_VERSION}
diff --git a/Modules/FindTclStub.cmake b/Modules/FindTclStub.cmake index 9856d54..fbccc3e 100644 --- a/Modules/FindTclStub.cmake +++ b/Modules/FindTclStub.cmake
@@ -105,6 +105,8 @@ "${TCL_TCLSH_PATH_PARENT}/lib" "${TK_WISH_PATH_PARENT}/lib" ) +# Entries built from a path not found yet are just /lib. +list(FILTER TCLTK_POSSIBLE_LIB_PATHS EXCLUDE REGEX "^/lib$") if(WIN32) get_filename_component( @@ -131,6 +133,7 @@ tclstub83 tclstub8.3 tclstub82 tclstub8.2 tclstub80 tclstub8.0 + NAMES_PER_DIR PATHS ${TCLTK_POSSIBLE_LIB_PATHS} ) @@ -146,6 +149,7 @@ tkstub83 tkstub8.3 tkstub82 tkstub8.2 tkstub80 tkstub8.0 + NAMES_PER_DIR PATHS ${TCLTK_POSSIBLE_LIB_PATHS} ) @@ -157,6 +161,7 @@ ttkstub90 ttkstub9.0 ttkstub86 ttkstub8.6 ttkstub85 ttkstub8.5 + NAMES_PER_DIR PATHS ${TCLTK_POSSIBLE_LIB_PATHS} )
diff --git a/Modules/FindTclsh.cmake b/Modules/FindTclsh.cmake index 2d9d0fb..0854736 100644 --- a/Modules/FindTclsh.cmake +++ b/Modules/FindTclsh.cmake
@@ -100,6 +100,8 @@ "${TK_LIBRARY_PATH_PARENT}/bin" "${TK_WISH_PATH_PARENT}/bin" ) +# Entries built from a path not found yet are just /bin. +list(FILTER TCLTK_POSSIBLE_BIN_PATHS EXCLUDE REGEX "^/bin$") if(WIN32) get_filename_component( @@ -126,6 +128,7 @@ find_program(TCL_TCLSH NAMES ${TCL_TCLSH_NAMES} + NAMES_PER_DIR HINTS ${TCLTK_POSSIBLE_BIN_PATHS} )
diff --git a/Modules/FindWish.cmake b/Modules/FindWish.cmake index 35d72cc..4255582 100644 --- a/Modules/FindWish.cmake +++ b/Modules/FindWish.cmake
@@ -76,6 +76,8 @@ "${TK_LIBRARY_PATH_PARENT}/bin" "${TCL_TCLSH_PATH_PARENT}/bin" ) +# Entries built from a path not found yet are just /bin. +list(FILTER TCLTK_POSSIBLE_BIN_PATHS EXCLUDE REGEX "^/bin$") if(WIN32) get_filename_component( @@ -102,6 +104,7 @@ find_program(TK_WISH NAMES ${TK_WISH_NAMES} + NAMES_PER_DIR HINTS ${TCLTK_POSSIBLE_BIN_PATHS} )
diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake index af48e6b..d8acd1b 100644 --- a/Modules/Platform/Windows-Clang.cmake +++ b/Modules/Platform/Windows-Clang.cmake
@@ -143,7 +143,7 @@ set(CMAKE_${lang}_LINKER_SUPPORTS_PDB ON) set(CMAKE_PCH_EXTENSION .pch) - set(CMAKE_PCH_PROLOGUE "#pragma clang system_header") + set(CMAKE_PCH_SYSTEM_HEADER_PRAGMA "#pragma clang system_header") set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Xclang -include-pch -Xclang <PCH_FILE> -Xclang -include -Xclang <PCH_HEADER>) set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Xclang -emit-pch -Xclang -include -Xclang <PCH_HEADER> -x ${__pch_header_${lang}})
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake index 88da695..5cb18f1 100644 --- a/Modules/Platform/Windows-MSVC.cmake +++ b/Modules/Platform/Windows-MSVC.cmake
@@ -446,7 +446,7 @@ set(CMAKE_PCH_EXTENSION .pch) set(CMAKE_LINK_PCH ON) if (CMAKE_${lang}_COMPILER_ID STREQUAL "Clang") - set(CMAKE_PCH_PROLOGUE "#pragma clang system_header") + set(CMAKE_PCH_SYSTEM_HEADER_PRAGMA "#pragma clang system_header") # macOS paths usually start with /Users/*. Unfortunately, clang-cl interprets # paths starting with /U as macro undefines, so we need to put a -- before the @@ -458,7 +458,7 @@ endif() elseif(MSVC_VERSION GREATER_EQUAL 1913) # At least MSVC toolet 14.13 from VS 2017 15.6 - set(CMAKE_PCH_PROLOGUE "#pragma system_header") + set(CMAKE_PCH_SYSTEM_HEADER_PRAGMA "#pragma system_header") endif() if (NOT ${CMAKE_${lang}_COMPILER_ID} STREQUAL "Clang") set(CMAKE_PCH_COPY_COMPILE_PDB ON)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 81d049b..6689145 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake
@@ -1,8 +1,8 @@ # CMake version number components. set(CMake_VERSION_MAJOR 4) set(CMake_VERSION_MINOR 5) -set(CMake_VERSION_PATCH 0) -set(CMake_VERSION_RC 1) +set(CMake_VERSION_PATCH 20261026) +#set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) # Start with the full version number used in tags. It has no dev info.
diff --git a/Source/CPack/IFW/cmCPackIFWCommon.h b/Source/CPack/IFW/cmCPackIFWCommon.h index 1b64e76..9bedd7e 100644 --- a/Source/CPack/IFW/cmCPackIFWCommon.h +++ b/Source/CPack/IFW/cmCPackIFWCommon.h
@@ -7,6 +7,8 @@ #include <map> #include <string> +#include <cmext/string_view> // IWYU pragma: keep + #include "cmValue.h" class cmCPackIFWGenerator; @@ -72,7 +74,7 @@ #define cmCPackIFWLogger(logType, ...) \ do { \ if (Generator) { \ - std::string cmCPackLog_msg = cmStrCat("", __VA_ARGS__); \ + std::string cmCPackLog_msg = cmStrCat(""_s, __VA_ARGS__); \ Generator->Logger->Log(cmCPackLog::LOG_##logType, __FILE__, __LINE__, \ cmCPackLog_msg.c_str(), cmCPackLog_msg.size()); \ } \
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index 595f3ac..7dd676a 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx
@@ -102,8 +102,7 @@ inputArgs.reserve(argc - 1); cm::append(inputArgs, argv + 1, argv + argc); - cmSystemTools::InitializeLibUV(); - cmSystemTools::FindCMakeResources(argv[0]); + cmSystemTools::InitializeCMake(argv[0]); cmCPackLog log; log.SetErrorPrefix("CPack Error: ");
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index 9e27fdc..e87ba27 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -745,8 +745,7 @@ } else { // Compute a directory in which to store launcher fragments. std::string& launchDir = this->Handler->CTestLaunchDir; - launchDir = - cmStrCat(this->CTest->GetBinaryDir(), "/Testing/", tag, "/Build"); + launchDir = cmStrCat(this->CTest->GetOutputDir(), '/', tag, "/Build"); // Clean out any existing launcher fragments. cmSystemTools::RemoveADirectory(launchDir);
diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx index 59cf7ce..1d72018 100644 --- a/Source/CTest/cmCTestConfigureCommand.cxx +++ b/Source/CTest/cmCTestConfigureCommand.cxx
@@ -36,13 +36,11 @@ namespace { -bool ConstructConfigureCommand(cmExecutionStatus& status, cmMakefile& mf, - std::string const sourceDirectory, - std::string const buildDirectory, - std::string const options, - std::string const presetName, - std::string const presetsFile, - std::string& configureCommand) +bool ConstructConfigureCommand( + cmExecutionStatus& status, cmMakefile& mf, std::string const sourceDirectory, + std::string const buildDirectory, std::string const outputDirectory, + std::string const options, std::string const presetName, + std::string const presetsFile, std::string& configureCommand) { configureCommand = cmStrCat('"', cmSystemTools::GetCMakeCommand(), "\" \"-S", @@ -130,8 +128,7 @@ cmValue buildName = mf.GetDefinition("CTEST_BUILD_NAME"); if (cmNonempty(site) || cmNonempty(buildName)) { std::string const initialCacheFile = - cmStrCat(cmSystemTools::CollapseFullPath(buildDirectory), - "/Testing/Temporary/CTestConfigureInitialCache.cmake"); + cmStrCat(outputDirectory, "/Temporary/CTestConfigureInitialCache.cmake"); cmGeneratedFileStream initialCache(initialCacheFile); if (cmNonempty(site)) { initialCache << "set(SITE " << cmOutputConverter::EscapeForCMake(*site) @@ -244,8 +241,8 @@ } if (configureCommand.empty() && !ConstructConfigureCommand(status, mf, sourceDirectory, buildDirectory, - args.Options, presetName, presetsFile, - configureCommand)) { + this->CTest->GetOutputDir(), args.Options, + presetName, presetsFile, configureCommand)) { return false; }
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index e835199..7fcc1f2 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -43,8 +43,8 @@ void cmCTestCoverageHandler::CleanCoverageLogFiles(std::ostream& log) { std::string logGlob = - cmStrCat(this->CTest->GetCTestConfiguration("BuildDirectory"), "/Testing/", - this->CTest->GetCurrentTag(), "/CoverageLog*"); + cmStrCat(this->CTest->GetOutputDir(), '/', this->CTest->GetCurrentTag(), + "/CoverageLog*"); cmsys::Glob gl; gl.FindFiles(logGlob); std::vector<std::string> const& files = gl.GetFiles(); @@ -193,6 +193,7 @@ std::string sourceDir = this->CTest->GetCTestConfiguration("SourceDirectory"); std::string binaryDir = this->CTest->GetCTestConfiguration("BuildDirectory"); + std::string outputDir = this->CTest->GetOutputDir(); if (binaryDir.empty()) { cmCTestLog(this->CTest, ERROR_MESSAGE, @@ -215,6 +216,7 @@ cmSystemTools::ConvertToUnixSlashes(sourceDir); cmSystemTools::ConvertToUnixSlashes(binaryDir); + cmSystemTools::ConvertToUnixSlashes(outputDir); cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, this->Quiet, "Performing coverage\n"); @@ -223,6 +225,7 @@ cont.Error = error; cont.SourceDir = sourceDir; cont.BinaryDir = binaryDir; + cont.OutputDir = outputDir; cont.OFS = &ofs; cont.Quiet = this->Quiet; @@ -876,7 +879,8 @@ return 0; } - std::string testingDir = this->CTest->GetBinaryDir() + "/Testing"; + // TODO(#27518): no test asserts this lands in the output directory. + std::string testingDir = this->CTest->GetOutputDir(); std::string tempDir = testingDir + "/CoverageInfo"; if (!cmSystemTools::MakeDirectory(tempDir)) { cmCTestLog(this->CTest, ERROR_MESSAGE, @@ -1403,7 +1407,6 @@ // No coverage files is a valid thing, so the exit code is 0 return 0; } - std::string testingDir = this->CTest->GetBinaryDir(); std::set<std::string> missingFiles; @@ -1683,7 +1686,8 @@ return 0; } - std::string testingDir = this->CTest->GetBinaryDir() + "/Testing"; + // TODO(#27518): This directory is never used. + std::string testingDir = this->CTest->GetOutputDir(); std::string tempDir = testingDir + "/CoverageInfo"; cmSystemTools::MakeDirectory(tempDir); @@ -1949,8 +1953,9 @@ } // create a process object and start it cmUVProcessChainBuilder builder; + // TODO(#27518): no test asserts this lands in the output directory. std::string stdoutFile = - cmStrCat(cont->BinaryDir, "/Testing/Temporary/", + cmStrCat(cont->OutputDir, "/Temporary/", this->GetCTestInstance()->GetCurrentTag(), '-', cmd); std::string stderrFile = stdoutFile; stdoutFile += ".stdout";
diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h index c938734..5635420 100644 --- a/Source/CTest/cmCTestCoverageHandler.h +++ b/Source/CTest/cmCTestCoverageHandler.h
@@ -25,6 +25,7 @@ int Error; std::string SourceDir; std::string BinaryDir; + std::string OutputDir; using SingleFileCoverageVector = std::vector<int>; using SingleFileBranchCoverageVector = std::vector<std::array<int, 2>>; using TotalCoverageMap = std::map<std::string, SingleFileCoverageVector>;
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx index 512f4c5..3d27181 100644 --- a/Source/CTest/cmCTestMemCheckHandler.cxx +++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -550,7 +550,7 @@ cmSystemTools::ParseArguments(memoryTesterOptions); this->MemoryTesterOutputFile = - this->CTest->GetBinaryDir() + "/Testing/Temporary/MemoryChecker.??.log"; + this->CTest->GetOutputDir() + "/Temporary/MemoryChecker.??.log"; switch (this->MemoryTesterStyle) { case cmCTestMemCheckHandler::VALGRIND: { @@ -582,7 +582,7 @@ } case cmCTestMemCheckHandler::DRMEMORY: { std::string tempDrMemoryDir = - this->CTest->GetBinaryDir() + "/Testing/Temporary/DrMemory"; + this->CTest->GetOutputDir() + "/Temporary/DrMemory"; if (!cm::contains(this->MemoryTesterOptions, "-quiet")) { this->MemoryTesterOptions.emplace_back("-quiet"); @@ -666,8 +666,8 @@ } case cmCTestMemCheckHandler::BOUNDS_CHECKER: { this->BoundsCheckerXMLFile = this->MemoryTesterOutputFile; - std::string dpbdFile = this->CTest->GetBinaryDir() + - "/Testing/Temporary/MemoryChecker.??.DPbd"; + std::string dpbdFile = + this->CTest->GetOutputDir() + "/Temporary/MemoryChecker.??.DPbd"; this->BoundsCheckerDPBDFile = dpbdFile; this->MemoryTesterDynamicOptions.emplace_back("/B"); this->MemoryTesterDynamicOptions.push_back(std::move(dpbdFile));
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index 331b0cb..b4c95f7 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -1377,7 +1377,7 @@ void cmCTestMultiProcessHandler::WriteCheckpoint(int index) { std::string fname = - this->CTest->GetBinaryDir() + "/Testing/Temporary/CTestCheckpoint.txt"; + this->CTest->GetOutputDir() + "/Temporary/CTestCheckpoint.txt"; cmsys::ofstream fout; fout.open(fname.c_str(), std::ios::app); fout << index << "\n"; @@ -1387,7 +1387,7 @@ void cmCTestMultiProcessHandler::MarkFinished() { std::string fname = - this->CTest->GetBinaryDir() + "/Testing/Temporary/CTestCheckpoint.txt"; + this->CTest->GetOutputDir() + "/Temporary/CTestCheckpoint.txt"; cmSystemTools::RemoveFile(fname); } @@ -1925,7 +1925,7 @@ void cmCTestMultiProcessHandler::CheckResume() { std::string fname = - this->CTest->GetBinaryDir() + "/Testing/Temporary/CTestCheckpoint.txt"; + this->CTest->GetOutputDir() + "/Temporary/CTestCheckpoint.txt"; if (this->CTest->GetFailover()) { if (cmSystemTools::FileExists(fname, true)) { *this->TestHandler->LogFile
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index 53bd3ad..989e232 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx
@@ -902,11 +902,17 @@ diff.ApplyTo(env); } + // The ctest_test() COVERAGE_TOOL option, or the CTEST_TEST_COVERAGE_TOOL + // variable of a dashboard script, overrides the CTestTestCoverageTool + // setting. + std::string coverageTool = this->TestHandler->TestOptions.CoverageTool; + if (coverageTool.empty()) { + coverageTool = this->CTest->GetCTestConfiguration("CTestTestCoverageTool"); + } + // Inject LLVM Profile name : // https://clang.llvm.org/docs/SourceBasedCodeCoverage.html#running-the-instrumented-program - if (this->CTest->GetCTestConfiguration("CTestTestCoverageTool") == - "LLVM-COV"_s || - this->TestHandler->TestOptions.CoverageTool == "LLVM-COV"_s) { + if (coverageTool == "LLVM-COV"_s) { this->UseLLVMCov = true; // Isolate the test from any ambient LLVM_PROFILE_FILE
diff --git a/Source/CTest/cmCTestStartCommand.cxx b/Source/CTest/cmCTestStartCommand.cxx index ac448b7..b176912 100644 --- a/Source/CTest/cmCTestStartCommand.cxx +++ b/Source/CTest/cmCTestStartCommand.cxx
@@ -94,6 +94,10 @@ this->CTest->SetCTestConfiguration("SourceDirectory", sourceDir, quiet); this->CTest->SetCTestConfiguration("BuildDirectory", binaryDir, quiet); + cmValue out_dir = mf.GetDefinition("CTEST_OUTPUT_DIRECTORY"); + std::string outputDir = + cmCTest::ComputeOutputDir(binaryDir, out_dir ? *out_dir : std::string()); + if (smodel) { cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, quiet, "Run dashboard with model ", smodel, @@ -120,7 +124,7 @@ } // Log startup actions. - std::string startLogFile = binaryDir + "/Testing/Temporary/LastStart.log"; + std::string startLogFile = outputDir + "/Temporary/LastStart.log"; cmGeneratedFileStream ofs(startLogFile); if (!ofs) { cmCTestLog(this->CTest, ERROR_MESSAGE, @@ -184,7 +188,7 @@ this->CTest->SetCTestConfigurationFromCMakeVariable( &mf, "BuildName", "CTEST_BUILD_NAME", quiet); - this->CTest->Initialize(binaryDir); + this->CTest->Initialize(binaryDir, outputDir); cmCTestOptionalLog( this->CTest, OUTPUT, quiet,
diff --git a/Source/CTest/cmCTestStartCommand.h b/Source/CTest/cmCTestStartCommand.h index acac563..a085509 100644 --- a/Source/CTest/cmCTestStartCommand.h +++ b/Source/CTest/cmCTestStartCommand.h
@@ -14,7 +14,7 @@ /** \class cmCTestStart * \brief Run a ctest script * - * cmCTestStartCommand defineds the command to start the nightly testing. + * cmCTestStartCommand defines the command to start the nightly testing. */ class cmCTestStartCommand : public cmCTestCommand {
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index 1599a1f..f2e127c 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -670,14 +670,7 @@ this->CDashUploadType); } - std::string const& buildDirectory = - this->CTest->GetCTestConfiguration("BuildDirectory"); - if (buildDirectory.empty()) { - cmCTestLog( - this->CTest, ERROR_MESSAGE, - "Cannot find BuildDirectory key in the DartConfiguration.tcl\n"); - return -1; - } + std::string const outputDirectory = this->CTest->GetOutputDir(); cmGeneratedFileStream ofs; this->StartLogFile("Submit", ofs); @@ -735,7 +728,7 @@ if (this->CTest->AddIfExists(cmCTest::PartCoverage, "Coverage.xml")) { std::vector<std::string> gfiles; std::string gpath = - cmStrCat(buildDirectory, "/Testing/", this->CTest->GetCurrentTag()); + cmStrCat(outputDirectory, '/', this->CTest->GetCurrentTag()); std::string::size_type glen = gpath.size() + 1; gpath += "/CoverageLog*"; cmCTestOptionalLog(this->CTest, DEBUG, this->Quiet, @@ -804,8 +797,8 @@ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, this->Quiet, " SubmitURL: ", url, '\n'); if (!this->SubmitUsingHTTP( - cmStrCat(buildDirectory, "/Testing/", this->CTest->GetCurrentTag()), - files, prefix, url)) { + cmStrCat(outputDirectory, '/', this->CTest->GetCurrentTag()), files, + prefix, url)) { cmCTestLog(this->CTest, ERROR_MESSAGE, " Problems when submitting via HTTP\n"); ofs << " Problems when submitting via HTTP\n";
diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx index 767f5fc..a6063ba 100644 --- a/Source/CTest/cmCTestTestCommand.cxx +++ b/Source/CTest/cmCTestTestCommand.cxx
@@ -215,6 +215,13 @@ } } + if (args.CoverageTool.empty()) { + cmValue coverageTool = mf.GetDefinition("CTEST_TEST_COVERAGE_TOOL"); + if (cmNonempty(coverageTool)) { + args.CoverageTool = *coverageTool; + } + } + // Apply explicitly specified ctest_test() options, // overriding any conflicting preset values. if (!args.Start.empty() || !args.End.empty() || !args.Stride.empty()) {
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 25d886b..50910db 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -2077,7 +2077,7 @@ void cmCTestTestHandler::ExpandTestsToRunInformationForRerunFailed() { - std::string dirName = this->CTest->GetBinaryDir() + "/Testing/Temporary"; + std::string dirName = this->CTest->GetOutputDir() + "/Temporary"; cmsys::Directory directory; if (!directory.Load(dirName)) { @@ -2109,7 +2109,7 @@ } std::string lastTestsFailedLog = - cmStrCat(this->CTest->GetBinaryDir(), "/Testing/Temporary/", logName); + cmStrCat(this->CTest->GetOutputDir(), "/Temporary/", logName); if (!cmSystemTools::FileExists(lastTestsFailedLog)) { if (!this->CTest->GetShowOnly() && !this->CTest->ShouldPrintLabels()) {
diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx index bf6a9ea..857bc5b 100644 --- a/Source/CursesDialog/ccmake.cxx +++ b/Source/CursesDialog/ccmake.cxx
@@ -70,8 +70,7 @@ argc = encoding_args.argc(); argv = encoding_args.argv(); - cmSystemTools::InitializeLibUV(); - cmSystemTools::FindCMakeResources(argv[0]); + cmSystemTools::InitializeCMake(argv[0]); cmDocumentation doc; doc.addCMakeStandardDocSections(); if (doc.CheckOptions(argc, argv)) {
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index dfc8265..77c8e63 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx
@@ -68,8 +68,7 @@ int argc2 = encoding_args.argc(); char const* const* argv2 = encoding_args.argv(); - cmSystemTools::InitializeLibUV(); - cmSystemTools::FindCMakeResources(argv2[0]); + cmSystemTools::InitializeCMake(argv2[0]); // check docs first so that X is not need to get docs // do docs, if args were given cmDocumentation doc;
diff --git a/Source/cmCMakePresetsErrors.cxx b/Source/cmCMakePresetsErrors.cxx index ce0ebb3..0705da7 100644 --- a/Source/cmCMakePresetsErrors.cxx +++ b/Source/cmCMakePresetsErrors.cxx
@@ -53,7 +53,11 @@ std::string getVariableName(cmJSONState* state) { std::string var = state->key_after("cacheVariables"); - std::string errMsg = cmStrCat("variable \"", var, '"'); + if (var.empty()) { + var = state->key_after("variables"); + } + std::string errMsg = + var.empty() ? "variable" : cmStrCat("variable \"", var, '"'); errMsg = cmStrCat(std::move(errMsg), " for preset \"", getPresetName(state), '"'); return errMsg;
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index b772c87..a26cece 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx
@@ -182,6 +182,12 @@ std::string NotesFiles; + // Output directory as requested on the command line or by a script. It + // may be empty or relative; OutputDir holds the resolved absolute path. + std::string OutputDirArg; + + std::string OutputDir; + // Default for the current mode; an explicit user choice takes precedence. bool InteractiveDebugMode = true; cm::optional<bool> InteractiveDebugModeCli; @@ -303,7 +309,7 @@ { std::string fname = this->GetCTestConfiguration("CostDataFile"); if (fname.empty()) { - fname = this->GetBinaryDir() + "/Testing/Temporary/CTestCostData.txt"; + fname = this->GetOutputDir() + "/Temporary/CTestCostData.txt"; } return fname; } @@ -441,7 +447,8 @@ return PartCount; } -void cmCTest::Initialize(std::string const& binary_dir) +void cmCTest::Initialize(std::string const& binary_dir, + std::string const& output_dir) { this->Impl->BuildID = ""; for (Part p = PartStart; p != PartCount; p = static_cast<Part>(p + 1)) { @@ -456,11 +463,16 @@ this->Impl->BinaryDir = binary_dir; cmSystemTools::ConvertToUnixSlashes(this->Impl->BinaryDir); + + if (!output_dir.empty()) { + this->Impl->OutputDirArg = output_dir; + } + this->UpdateOutputDir(); } bool cmCTest::CreateNewTag(bool quiet) { - std::string const testingDir = this->Impl->BinaryDir + "/Testing"; + std::string const testingDir = this->Impl->OutputDir; std::string const tagfile = testingDir + "/TAG"; auto const result = cmSystemTools::MakeDirectory(testingDir); @@ -504,7 +516,7 @@ bool cmCTest::ReadExistingTag(bool quiet) { - std::string const testingDir = this->Impl->BinaryDir + "/Testing"; + std::string const testingDir = this->Impl->OutputDir; std::string const tagfile = testingDir + "/TAG"; std::string tag; @@ -624,6 +636,9 @@ cmSystemTools::SetLogicalWorkingDirectory(this->Impl->BinaryDir); } } + // The binary directory may have just changed, so resolve the output + // directory against its final value. + this->UpdateOutputDir(); this->Impl->TimeOut = std::chrono::seconds(atoi(this->GetCTestConfiguration("TimeOut").c_str())); std::string const& testLoad = this->GetCTestConfiguration("TestLoad"); @@ -690,7 +705,7 @@ bool cmCTest::OpenOutputFile(std::string const& path, std::string const& name, cmGeneratedFileStream& stream, bool compress) { - std::string testingDir = this->Impl->BinaryDir + "/Testing"; + std::string testingDir = this->Impl->OutputDir; if (!path.empty()) { testingDir = cmStrCat(std::move(testingDir), '/', path); } @@ -738,7 +753,7 @@ bool cmCTest::CTestFileExists(std::string const& filename) { - std::string testingDir = cmStrCat(this->Impl->BinaryDir, "/Testing/", + std::string testingDir = cmStrCat(this->Impl->OutputDir, '/', this->Impl->CurrentTag, '/', filename); return cmSystemTools::FileExists(testingDir); } @@ -827,6 +842,9 @@ std::string const binaryDir = resolveResult.Preset->BinaryDir; this->SetCTestConfiguration("BuildDirectory", binaryDir); this->Impl->BinaryDir = binaryDir; + // Resolve the output directory against the new binary directory. + // UpdateCTestConfiguration may return early without doing so. + this->UpdateOutputDir(); cmSystemTools::SetLogicalWorkingDirectory(binaryDir); mf.AddDefinition("CTEST_BINARY_DIRECTORY", binaryDir); // Re-parse DartConfiguration.tcl since we changed BinaryDir. @@ -927,7 +945,7 @@ res |= cmCTest::MEMORY_ERRORS; } } - std::string notes_dir = this->Impl->BinaryDir + "/Testing/Notes"; + std::string notes_dir = this->Impl->OutputDir + "/Notes"; if (cmSystemTools::FileIsDirectory(notes_dir)) { cmsys::Directory d; d.Load(notes_dir); @@ -2358,6 +2376,11 @@ this->Impl->OutputTestOutputOnTestFailure = true; return true; } }, + CommandArgument{ "--output-dir", CommandArgument::Values::One, + [this](std::string const& od) -> bool { + this->Impl->OutputDirArg = od; + return true; + } }, CommandArgument{ "--test-output-size-passed", CommandArgument::Values::One, [this](std::string const& sz) -> bool { @@ -2729,6 +2752,7 @@ return 1; } this->Impl->BinaryDir = workDir; + this->UpdateOutputDir(); // -D, -T, and/or -M was specified if (processSteps) { @@ -2832,7 +2856,7 @@ cmCTestLog(this, ERROR_MESSAGE, "Errors while running CTest\n"); if (!this->Impl->OutputTestOutputOnTestFailure) { std::string const lastTestLog = - this->GetBinaryDir() + "/Testing/Temporary/LastTest.log"; + this->GetOutputDir() + "/Temporary/LastTest.log"; cmCTestLog(this, ERROR_MESSAGE, "Output from these tests are in: ", lastTestLog, '\n'); cmCTestLog(this, ERROR_MESSAGE, @@ -3096,7 +3120,39 @@ std::string cmCTest::GetStampDir() { - return this->Impl->BinaryDir + "/Testing/Temporary/LastTestRun"; + return this->Impl->OutputDir + "/Temporary/LastTestRun"; +} + +std::string cmCTest::ComputeOutputDir(std::string const& binary_dir, + std::string const& output_dir) +{ + if (output_dir.empty()) { + return cmStrCat(binary_dir, "/Testing"); + } + // Expand a leading '~', normalize separators, collapse repeated slashes, + // and drop any trailing slash. + std::string dir = output_dir; + cmSystemTools::ConvertToUnixSlashes(dir); + // Resolve a relative path against the binary directory so that it means the + // same thing as the default value, "<binary-dir>/Testing". + return cmSystemTools::CollapseFullPath(dir, binary_dir); +} + +void cmCTest::UpdateOutputDir() +{ + this->Impl->OutputDir = + cmCTest::ComputeOutputDir(this->Impl->BinaryDir, this->Impl->OutputDirArg); +} + +std::string cmCTest::GetOutputDir() +{ + return this->Impl->OutputDir; +} + +void cmCTest::SetOutputDir(std::string const& outdir) +{ + this->Impl->OutputDirArg = outdir; + this->UpdateOutputDir(); } std::string const& cmCTest::GetConfigType()
diff --git a/Source/cmCTest.h b/Source/cmCTest.h index fb04c7d..24d6fed 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h
@@ -15,6 +15,7 @@ #include <cm/optional> #include <cm/string_view> +#include <cmext/string_view> #include "cmDuration.h" #include "cmProcessOutput.h" @@ -66,8 +67,10 @@ /** Process Command line arguments */ int Run(std::vector<std::string> const& args); - /** Initialize a dashboard run in the given build tree. */ - void Initialize(std::string const& binary_dir); + /** Initialize a dashboard run in the given build tree, writing output + files to the given output directory. */ + void Initialize(std::string const& binary_dir, + std::string const& output_dir); bool CreateNewTag(bool quiet); bool ReadExistingTag(bool quiet); @@ -271,6 +274,26 @@ std::string GetStampDir(); /** + * Get / set the path to the output directory. + * By default, this is the binary directory + "/Testing". + * The stored path is always absolute, uses forward slashes, and has no + * trailing slash, so callers must supply their own separator when + * appending to it. + * */ + std::string GetOutputDir(); + void SetOutputDir(std::string const& outdir); + + /** + * Compute the output directory of a dashboard run. An empty output_dir + * yields the default, binary_dir + "/Testing". Otherwise a leading '~' is + * expanded, separators are normalized, any trailing slash is removed, and a + * relative path is resolved against binary_dir so that it means the same + * thing as the default. + */ + static std::string ComputeOutputDir(std::string const& binary_dir, + std::string const& output_dir); + + /** * Get the short path to the file. * * This means if the file is in binary or @@ -464,6 +487,10 @@ /** apply CTEST_* variable definitions to the CTest configuration map */ void ApplyDefinitionsToCTestConfig(); + /** recompute the output directory from the requested value and the + binary directory, which may not be known until late in the run */ + void UpdateOutputDir(); + /** set command line arguments read from a test preset */ bool SetArgsFromPreset(cmCMakePresetsArgs const& args); @@ -487,10 +514,10 @@ }; #define cmCTestLog(ctSelf, logType, ...) \ - (ctSelf)->Log(cmCTest::logType, cmStrCat("", __VA_ARGS__)) + (ctSelf)->Log(cmCTest::logType, cmStrCat(""_s, __VA_ARGS__)) #define cmCTestOptionalLog(ctSelf, logType, suppress, ...) \ - (ctSelf)->Log(cmCTest::logType, cmStrCat("", __VA_ARGS__), suppress) + (ctSelf)->Log(cmCTest::logType, cmStrCat(""_s, __VA_ARGS__), suppress) #define cmCTestColorLog(ctSelf, logType, attrs, ...) \ - (ctSelf)->Log(cmCTest::logType, cmStrCat("", __VA_ARGS__), attrs) + (ctSelf)->Log(cmCTest::logType, cmStrCat(""_s, __VA_ARGS__), attrs)
diff --git a/Source/cmCacheDocumentationTable.cxx b/Source/cmCacheDocumentationTable.cxx index 0ac2c5b..65ede69 100644 --- a/Source/cmCacheDocumentationTable.cxx +++ b/Source/cmCacheDocumentationTable.cxx
@@ -497,6 +497,8 @@ "Location or short name (e.g. macosx) of the macOS platform SDK passed to the compiler via -isysroot. Initialized from the SDKROOT environment variable; empty by default."_s }, { "CMAKE_PCH_INSTANTIATE_TEMPLATES"_s, "Initializes the PCH_INSTANTIATE_TEMPLATES target property"_s }, + { "CMAKE_PCH_WARNINGS"_s, + "Initializes the PCH_WARNINGS target property"_s }, { "CMAKE_PCH_WARN_INVALID"_s, "Initializes the PCH_WARN_INVALID target property"_s }, { "CMAKE_PDB_OUTPUT_DIRECTORY"_s,
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index 147d4ba..70389b5 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx
@@ -428,7 +428,7 @@ std::vector<std::string> compilerLauncher; if (lang == "C" || lang == "CXX" || lang == "Fortran" || lang == "CUDA" || lang == "HIP" || lang == "ISPC" || lang == "OBJC" || lang == "OBJCXX" || - lang == "SYCL") { + lang == "SYCL" || lang == "Rust") { // FIXME(#27402,#28110): The FASTBuild generator's limitations w.r.t. // shell escaping and command line ordering means we can't support // wrappers for now.
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 081052b..876d86b 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx
@@ -957,15 +957,17 @@ } } break; case Arguments::SourceType::CxxModule: { - if (!in_file_set) { - file_set_name += 'a'; - fprintf(fout, - " PRIVATE FILE_SET %s TYPE CXX_MODULES BASE_DIRS \"%s\" " - "FILES\n", - file_set_name.c_str(), - this->Makefile->GetCurrentSourceDirectory().c_str()); - in_file_set = true; - } + // Module sources may reside anywhere, including the scratch + // directory for copied sources. Each one gets its own file set + // whose base directory contains it. + std::string const baseDir = cmSystemTools::GetFilenamePath( + cmSystemTools::CollapseFullPath(si, this->BinaryDirectory)); + file_set_name += 'a'; + fprintf(fout, + " PRIVATE FILE_SET %s TYPE CXX_MODULES BASE_DIRS \"%s\" " + "FILES\n", + file_set_name.c_str(), baseDir.c_str()); + in_file_set = true; } break; case Arguments::SourceType::Directory: /* Handled elsewhere. */
diff --git a/Source/cmExperimental.cxx b/Source/cmExperimental.cxx index e0c5f8f..3a493d7 100644 --- a/Source/cmExperimental.cxx +++ b/Source/cmExperimental.cxx
@@ -48,7 +48,7 @@ cmExperimental::TryCompileCondition::Never }, // Rust support { "Rust", - "b6fdddce-bf66-41a5-bc5f-077f6fa4d2a1", + "628f8f9f-d7dc-4a06-9aaf-d4ede4426ddf", "CMAKE_EXPERIMENTAL_RUST", "CMake's support for the Rust programming language is experimental. " "It is meant only for experimentation and feedback to CMake developers.",
diff --git a/Source/cmFileTime.h b/Source/cmFileTime.h index 7887bf1..1fb62b1 100644 --- a/Source/cmFileTime.h +++ b/Source/cmFileTime.h
@@ -6,6 +6,8 @@ #include <string> +#include <cm/bits/constexpr.hxx> + /** \class cmFileTime * \brief Abstract file modification time with support for comparison with * other file modification times. @@ -32,28 +34,37 @@ /** * @brief Return true if this is older than ftm */ - bool Older(cmFileTime ftm) const { return (this->Time - ftm.Time) < 0; } + constexpr bool Older(cmFileTime ftm) const + { + return (this->Time - ftm.Time) < 0; + } /** * @brief Return true if this is newer than ftm */ - bool Newer(cmFileTime ftm) const { return (ftm.Time - this->Time) < 0; } + constexpr bool Newer(cmFileTime ftm) const + { + return (ftm.Time - this->Time) < 0; + } /** * @brief Return true if this is the same as ftm */ - bool Equal(cmFileTime ftm) const { return this->Time == ftm.Time; } + constexpr bool Equal(cmFileTime ftm) const { return this->Time == ftm.Time; } /** * @brief Return true if this is not the same as ftm */ - bool Differ(cmFileTime ftm) const { return this->Time != ftm.Time; } + constexpr bool Differ(cmFileTime ftm) const + { + return this->Time != ftm.Time; + } /** * @brief Compare file modification times. * @return -1, 0, +1 for this older, same, or newer than ftm. */ - int Compare(cmFileTime ftm) const + CONSTEXPR_CXX14 int Compare(cmFileTime ftm) const { TimeType const diff = this->Time - ftm.Time; if (diff == 0) { @@ -67,7 +78,7 @@ /** * @brief Return true if this is at least a second older than ftm */ - bool OlderS(cmFileTime ftm) const + constexpr bool OlderS(cmFileTime ftm) const { return (ftm.Time - this->Time) >= cmFileTime::UtPerS; } @@ -75,7 +86,7 @@ /** * @brief Return true if this is at least a second newer than ftm */ - bool NewerS(cmFileTime ftm) const + constexpr bool NewerS(cmFileTime ftm) const { return (this->Time - ftm.Time) >= cmFileTime::UtPerS; } @@ -83,7 +94,7 @@ /** * @brief Return true if this is within the same second as ftm */ - bool EqualS(cmFileTime ftm) const + CONSTEXPR_CXX14 bool EqualS(cmFileTime ftm) const { TimeType diff = this->Time - ftm.Time; if (diff < 0) { @@ -95,7 +106,7 @@ /** * @brief Return true if this is older or newer than ftm by at least a second */ - bool DifferS(cmFileTime ftm) const + CONSTEXPR_CXX14 bool DifferS(cmFileTime ftm) const { TimeType diff = this->Time - ftm.Time; if (diff < 0) { @@ -109,7 +120,7 @@ * @return -1: this at least a second older, 0: this within the same second * as ftm, +1: this at least a second newer than ftm. */ - int CompareS(cmFileTime ftm) const + CONSTEXPR_CXX14 int CompareS(cmFileTime ftm) const { TimeType const diff = this->Time - ftm.Time; if (diff <= -cmFileTime::UtPerS) { @@ -124,7 +135,7 @@ /** * @brief The file modification time in unit time per second */ - TimeType GetTime() const { return this->Time; } + constexpr TimeType GetTime() const { return this->Time; } private: TimeType Time = 0;
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 9476c1d..7497954 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx
@@ -2188,7 +2188,8 @@ // Also found in `cmCommonTargetGenerator::GetCompilerLauncher`. return lang == "C"_s || lang == "CXX"_s || lang == "Fortran"_s || lang == "CUDA"_s || lang == "HIP"_s || lang == "ISPC"_s || - lang == "SYCL"_s || lang == "OBJC"_s || lang == "OBJCXX"_s; + lang == "SYCL"_s || lang == "OBJC"_s || lang == "OBJCXX"_s || + lang == "Rust"_s; } // FIXME: return a vector of `cm::string_view` instead to avoid lots of tiny @@ -3359,6 +3360,12 @@ std::string const filename_tmp = cmStrCat(filename, ".tmp"); if (!haveReuseTarget) { + // Marking the generated header as a system header suppresses the + // diagnostics of every header it includes. Skip it when the target + // asks for warnings from its precompiled headers. + cmValue pchSystemHeaderPragma = this->GetPropertyAsBool("PCH_WARNINGS") + ? nullptr + : this->Makefile->GetDefinition("CMAKE_PCH_SYSTEM_HEADER_PRAGMA"); cmValue pchPrologue = this->Makefile->GetDefinition("CMAKE_PCH_PROLOGUE"); cmValue pchEpilogue = @@ -3370,6 +3377,9 @@ filename_tmp, false, this->GetGlobalGenerator()->GetMakefileEncoding()); file << "/* generated by CMake */\n\n"; + if (pchSystemHeaderPragma) { + file << *pchSystemHeaderPragma << "\n"; + } if (pchPrologue) { file << *pchPrologue << "\n"; } @@ -3405,7 +3415,12 @@ } } - if (!firstHeaderOnDisk.empty()) { + // Give the generated header the timestamp of a header from the project + // to help ccache. Do this only when creating it for the first time: + // if its content later changes, e.g. because PCH_WARNINGS was toggled, + // an older timestamp would make build systems consider the already + // precompiled header up to date. + if (!firstHeaderOnDisk.empty() && !cmSystemTools::FileExists(filename)) { cmFileTimes::Copy(firstHeaderOnDisk, filename_tmp); }
diff --git a/Source/cmJSONState.cxx b/Source/cmJSONState.cxx index 18a3946..400fb2d 100644 --- a/Source/cmJSONState.cxx +++ b/Source/cmJSONState.cxx
@@ -95,8 +95,11 @@ { for (auto it = this->parseStack.begin(); it != this->parseStack.end(); ++it) { - if (it->first == k && (++it) != this->parseStack.end()) { - return it->first; + if (it->first == k) { + auto next = std::next(it); + if (next != this->parseStack.end()) { + return next->first; + } } } return ""; @@ -106,8 +109,11 @@ { for (auto it = this->parseStack.begin(); it != this->parseStack.end(); ++it) { - if (it->first == k && (++it) != this->parseStack.end()) { - return it->second; + if (it->first == k) { + auto next = std::next(it); + if (next != this->parseStack.end()) { + return next->second; + } } } return nullptr;
diff --git a/Source/cmMessenger.cxx b/Source/cmMessenger.cxx index 3aebc92..5ab4f3a 100644 --- a/Source/cmMessenger.cxx +++ b/Source/cmMessenger.cxx
@@ -82,9 +82,10 @@ } void displayMessage(MessageType type, cmDiagnosticCategory category, - std::ostringstream& msg) + cmMessenger::SuppressionHint hint, std::ostringstream& msg) { - if (isAuthorDiagnostic(category)) { + if (hint == cmMessenger::SuppressionHint::Show && + isAuthorDiagnostic(category)) { // Add a note about warning suppression. std::ostringstream text; if (type == MessageType::WARNING) { @@ -245,7 +246,7 @@ // Add the rest of the context. PrintCallStack(msg, backtrace, this->TopSource); - displayMessage(type, category, msg); + displayMessage(type, category, this->SuppressionHintMode, msg); // Add message to logs this->DisplayedMessages.emplace_back(
diff --git a/Source/cmMessenger.h b/Source/cmMessenger.h index 3ae7fc0..cc14360 100644 --- a/Source/cmMessenger.h +++ b/Source/cmMessenger.h
@@ -27,6 +27,12 @@ class cmMessenger { public: + enum class SuppressionHint + { + Show, + Hide, + }; + void IssueMessage( MessageType type, std::string const& text, cmListFileBacktrace const& backtrace = cmListFileBacktrace()); @@ -41,6 +47,12 @@ void SetTopSource(cm::optional<std::string> topSource); + // Whether author diagnostics end with a note on how to suppress them. + void SetSuppressionHint(SuppressionHint hint) + { + this->SuppressionHintMode = hint; + } + // Print the top of a backtrace. void PrintBacktraceTitle(std::ostream& out, cmListFileBacktrace const& bt) const; @@ -67,6 +79,7 @@ private: cm::optional<std::string> TopSource; + SuppressionHint SuppressionHintMode = SuppressionHint::Show; std::vector<Message> DisplayedMessages;
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 6e5e9ef..f5d9613 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -453,7 +453,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule( bool useResponseFile, std::string const& config, std::vector<std::string> const& preLinkComments, - std::vector<std::string> const& postBuildComments) + std::vector<std::string> const& postBuildComments, bool hasPreLink, + bool hasPostBuild) { cm::TargetType targetType = this->GetGeneratorTarget()->GetType(); @@ -608,8 +609,19 @@ // If there is no ranlib the command will be ":". Skip it. cm::erase_if(linkCmds, cmNinjaRemoveNoOpCommands()); - linkCmds.insert(linkCmds.begin(), "$PRE_LINK"); - linkCmds.emplace_back("$POST_BUILD"); + // The rule is specific to this target and configuration, so only + // reference $PRE_LINK and $POST_BUILD when the target has such steps. + // Otherwise they expand to a no-op that still forces a shell on Windows + // (cmd.exe /C), one more process for every link. If the rule has no + // commands of its own, keep them: an empty rule would otherwise become + // the bare shell no-op, which is not a program on Windows. + bool const noLinkCmds = linkCmds.empty(); + if (hasPreLink || noLinkCmds) { + linkCmds.insert(linkCmds.begin(), "$PRE_LINK"); + } + if (hasPostBuild || noLinkCmds) { + linkCmds.emplace_back("$POST_BUILD"); + } rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds, config, config); @@ -783,10 +795,27 @@ case cm::TargetType::STATIC_LIBRARY: { // We have archive link commands set. First, delete the existing archive. { - std::string cmakeCommand = - this->GetLocalGenerator()->ConvertToOutputFormat( - cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL); - linkCmds.push_back(cmakeCommand + " -E rm -f $TARGET_FILE"); +#ifdef _WIN32 + // This rule always has more than one command, so it runs under + // cmd.exe: delete with its builtin instead of starting cmake.exe. + // A RULE_LAUNCH_LINK launcher runs each command itself, without + // cmd.exe, so keep using cmake.exe when there is one. + bool const useDel = this->GetLocalGenerator() + ->GetRuleLauncher(this->GetGeneratorTarget(), + "RULE_LAUNCH_LINK", config) + .empty(); +#else + bool const useDel = false; +#endif + if (useDel) { + // Discard the message 'del' prints for a missing file. + linkCmds.emplace_back("del /f /q $TARGET_FILE 2>nul"); + } else { + std::string cmakeCommand = + this->GetLocalGenerator()->ConvertToOutputFormat( + cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL); + linkCmds.push_back(cmakeCommand + " -E rm -f $TARGET_FILE"); + } } // TODO: Use ARCHIVE_APPEND for archives over a certain size. { @@ -1598,6 +1627,14 @@ bool const symlinkNeeded = (targetOutput != targetOutputReal && !gt->IsFrameworkOnApple() && !gt->IsArchivedAIXSharedLibrary()); + // Whether the link rule needs $PRE_LINK / $POST_BUILD. Decide from the + // target's commands, not from this statement's lines: the rule is shared + // by every statement for this target and config, and in a cross-config + // statement the commands above may have been skipped. + bool const hasPreLink = !gt->GetPreBuildCommands().empty() || + !gt->GetPreLinkCommands().empty() || (mdi && mdi->DefFileGenerated); + bool const hasPostBuild = + !symlinkNeeded && !gt->GetPostBuildCommands().empty(); if (!symlinkNeeded) { vars["POST_BUILD"] = postBuildCmdLine; } else { @@ -1700,7 +1737,7 @@ globalGen->WriteBuild(this->GetImplFileStream(fileConfig), linkBuild, commandLineLengthLimit, &usedResponseFile); this->WriteLinkRule(usedResponseFile, config, preLinkComments, - postBuildComments); + postBuildComments, hasPreLink, hasPostBuild); if (symlinkNeeded) { if (targetType == cm::TargetType::EXECUTABLE) {
diff --git a/Source/cmNinjaNormalTargetGenerator.h b/Source/cmNinjaNormalTargetGenerator.h index 8d396ab..603882b 100644 --- a/Source/cmNinjaNormalTargetGenerator.h +++ b/Source/cmNinjaNormalTargetGenerator.h
@@ -32,7 +32,8 @@ void WriteLinkRule(bool useResponseFile, std::string const& config, std::vector<std::string> const& preLinkComments, - std::vector<std::string> const& postBuildComments); + std::vector<std::string> const& postBuildComments, + bool hasPreLink, bool hasPostBuild); void WriteDeviceLinkRules(std::string const& config); void WriteDriverDeviceLinkRule(bool useResponseFile, std::string const& config);
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 7e22dd2..cb87f56 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx
@@ -2532,6 +2532,7 @@ std::string const tdin = this->GetTargetDependInfoPath(lang, config); cmGeneratedFileStream tdif(tdin); + tdif.SetCopyIfDifferent(true); tdif << tdi; }
diff --git a/Source/cmPackageInfoReader.cxx b/Source/cmPackageInfoReader.cxx index 9e659d1..25d6b6b 100644 --- a/Source/cmPackageInfoReader.cxx +++ b/Source/cmPackageInfoReader.cxx
@@ -612,6 +612,9 @@ for (auto ri = requirementObjects.begin(), re = requirementObjects.end(); ri != re; ++ri) { + if (!ri->isObject() && !ri->isNull()) { + continue; + } cmPackageRequirement r{ ri.name(), ToString((*ri)["version"]), ReadList(*ri, "components"), @@ -926,7 +929,16 @@ auto const& cfgData = data["configurations"]; if (cfgData.isObject()) { for (auto ci = cfgData.begin(), ce = cfgData.end(); ci != ce; ++ci) { - this->SetTargetProperties(makefile, target, *ci, package, IterKey(ci)); + cm::string_view const cfgName = IterKey(ci); + Json::Value const& cfgObj = *ci; + if (cfgObj.isObject()) { + this->SetTargetProperties(makefile, target, cfgObj, package, cfgName); + } else if (!cfgObj.isNull()) { + makefile->IssueMessage(MessageType::WARNING, + cmStrCat("Component \""_s, name, + "\" configuration \""_s, cfgName, + "\" is not an object."_s)); + } } } else if (!cfgData.isNull()) { makefile->IssueMessage( @@ -1094,6 +1106,12 @@ } // Read supplemental data for component. + if (!ci->isObject()) { + makefile->IssueMessage( + MessageType::WARNING, + cmStrCat("Component \""_s, name, "\" is not an object."_s)); + continue; + } this->SetTargetProperties(makefile, ti->second, *ci, package, configuration); }
diff --git a/Source/cmPkgConfigParser.cxx b/Source/cmPkgConfigParser.cxx index 96d693d..7dbb61d 100644 --- a/Source/cmPkgConfigParser.cxx +++ b/Source/cmPkgConfigParser.cxx
@@ -4,7 +4,6 @@ #include "cmPkgConfigParser.h" #include <algorithm> -#include <cctype> #include <cstddef> #include <set> #include <string> @@ -12,37 +11,8 @@ #include <utility> #include <vector> -#include <cm/string_view> - #include <cmllpkgc/llpkgc.h> -namespace { - -cmPkgConfigDependencyOperation LookupDependencyOperation(cm::string_view op) -{ - if (op == "<") { - return cmPkgConfigDependencyOperation::LessThan; - } - if (op == "<=") { - return cmPkgConfigDependencyOperation::LessThanEqual; - } - if (op == "=") { - return cmPkgConfigDependencyOperation::Equal; - } - if (op == "!=") { - return cmPkgConfigDependencyOperation::NotEqual; - } - if (op == ">") { - return cmPkgConfigDependencyOperation::GreaterThan; - } - if (op == ">=") { - return cmPkgConfigDependencyOperation::GreaterThanEqual; - } - return cmPkgConfigDependencyOperation::None; -} - -} // namespace - cmPkgConfigValueItem::cmPkgConfigValueItem(std::string text, bool isSubstitution) : Text{ std::move(text) } @@ -84,8 +54,7 @@ if (this != &other) { this->ResetCallbacks(); llpkgc_file_init(static_cast<llpkgc_file_t*>(this), &Settings_); - Ptr_ = nullptr; - Len_ = 0; + CurrentValue_.clear(); Ident_ = other.Ident_; Data_ = other.Data_; } @@ -98,8 +67,7 @@ if (this != &other) { this->ResetCallbacks(); llpkgc_file_init(static_cast<llpkgc_file_t*>(this), &Settings_); - Ptr_ = nullptr; - Len_ = 0; + CurrentValue_.clear(); Ident_ = std::move(other.Ident_); Data_ = std::move(other.Data_); } @@ -111,7 +79,6 @@ Settings_.on_ident = OnIdentTr; Settings_.on_value_literal = OnValueLiteralTr; Settings_.on_value_substitution = OnValueSubstitutionTr; - Settings_.on_line_begin = nullptr; Settings_.on_property_complete = OnPropertyCompleteTr; Settings_.on_variable_complete = OnVariableCompleteTr; Settings_.on_barewords_complete = OnBarewordsCompleteTr; @@ -132,11 +99,6 @@ return llpkgc_file_finish(static_cast<llpkgc_file_t*>(this)); } -void cmPkgConfigFileParser::Resume() -{ - llpkgc_file_resume(static_cast<llpkgc_file_t*>(this)); -} - llpkgc_file_errno_t cmPkgConfigFileParser::GetErrno() const { return llpkgc_file_get_errno(static_cast<llpkgc_file_t const*>(this)); @@ -180,9 +142,9 @@ Data_.back().Value.emplace_back(std::move(text), isSubstitution); } -int cmPkgConfigFileParser::OnSpanNext(char const*, std::size_t len) +int cmPkgConfigFileParser::OnSpanNext(char const* at, std::size_t len) { - Len_ += len; + CurrentValue_.append(at, len); return 0; } @@ -246,8 +208,7 @@ int cmPkgConfigFileParser::OnValueLiteral(char const* at, std::size_t len) { - Ptr_ = at; - Len_ = len; + CurrentValue_.assign(at, len); Settings_.on_value_literal = OnSpanNextTr; return 0; } @@ -261,7 +222,7 @@ int cmPkgConfigFileParser::OnValueLiteralComplete() { Settings_.on_value_literal = OnValueLiteralTr; - AppendValue(std::string{ Ptr_, Len_ }, false); + AppendValue(std::move(CurrentValue_), false); return 0; } @@ -272,8 +233,7 @@ int cmPkgConfigFileParser::OnValueSubstitution(char const* at, std::size_t len) { - Ptr_ = at; - Len_ = len; + CurrentValue_.assign(at, len); Settings_.on_value_substitution = OnSpanNextTr; return 0; } @@ -289,7 +249,7 @@ int cmPkgConfigFileParser::OnValueSubstitutionComplete() { Settings_.on_value_substitution = OnValueSubstitutionTr; - AppendValue(std::string{ Ptr_, Len_ }, true); + AppendValue(std::move(CurrentValue_), true); return 0; } @@ -390,7 +350,7 @@ int cmPkgConfigDependencyParser::OnDependencyName(char const* at, std::size_t len) { - Current_.Name.assign(at, len); + Current_.Name.append(at, len); return 0; } @@ -402,25 +362,10 @@ at, len); } -int cmPkgConfigDependencyParser::OnDependencyOperator(char const* at, - std::size_t len) -{ - Current_.Operation = LookupDependencyOperation(cm::string_view{ at, len }); - return 0; -} - -int cmPkgConfigDependencyParser::OnDependencyOperatorTr(llpkgc_dep_t* parser, - char const* at, - std::size_t len) -{ - return static_cast<cmPkgConfigDependencyParser*>(parser) - ->OnDependencyOperator(at, len); -} - int cmPkgConfigDependencyParser::OnDependencyVersion(char const* at, std::size_t len) { - Current_.Version.assign(at, len); + Current_.Version.append(at, len); return 0; } @@ -434,6 +379,8 @@ int cmPkgConfigDependencyParser::OnDependencyComplete() { + Current_.Operation = static_cast<cmPkgConfigDependencyOperation>( + llpkgc_dep_get_comparator(static_cast<llpkgc_dep_t*>(this))); Dependencies_.push_back(std::move(Current_)); Current_ = cmPkgConfigDependencySpec{}; return 0; @@ -460,7 +407,7 @@ std::size_t len) { auto err = Parse(input, len); - if (err != PFCE_OK) { + if (err != PFCE_OK && err != PFCE_NEED_MORE) { return err; } return Finish(); @@ -591,6 +538,7 @@ if (it != StoredVariables_.end()) { resolving.insert(item.Text); result += ResolveValueImpl(it->second, resolving); + resolving.erase(item.Text); } } else { result += item.Text; @@ -615,24 +563,16 @@ } std::string resolved = ResolveValue(entry->Value); - auto start = resolved.find_first_not_of(" \t"); - if (start != std::string::npos) { - resolved.erase(0, start); - } cache.Literal = resolved; - std::string lower = name; - for (auto& c : lower) { - c = static_cast<char>(std::tolower(static_cast<unsigned char>(c))); - } - - if (IsFragmentProperty(lower)) { + auto kind = llpkgc_classify_field(name.data(), name.size()); + if (kind == LLPKGC_VALUE_FRAGMENTS) { cmPkgConfigFragmentParser fragmentParser; auto err = fragmentParser.Parse(resolved.data(), resolved.size()); if (err == PFFE_OK && fragmentParser.Finish() == PFFE_OK) { cache.Fragments = fragmentParser.Fragments(); } - } else if (IsDependencyProperty(lower)) { + } else if (kind == LLPKGC_VALUE_DEPENDENCIES) { cmPkgConfigDependencyParser dependencyParser; auto err = dependencyParser.Parse(resolved.data(), resolved.size()); if (err == PDEP_OK && dependencyParser.Finish() == PDEP_OK) { @@ -643,17 +583,3 @@ Cache_[name] = cache; return true; } - -bool cmPkgConfigParser::IsFragmentProperty(std::string const& lower) -{ - return lower == "cflags" || lower == "cflags.private" || - lower == "cflags.shared" || lower == "libs" || lower == "libs.private" || - lower == "libs.shared"; -} - -bool cmPkgConfigParser::IsDependencyProperty(std::string const& lower) -{ - return lower == "conflicts" || lower == "provides" || lower == "requires" || - lower == "requires.private" || lower == "requires.internal" || - lower == "requires.shared"; -}
diff --git a/Source/cmPkgConfigParser.h b/Source/cmPkgConfigParser.h index 662b1b7..aa491c3 100644 --- a/Source/cmPkgConfigParser.h +++ b/Source/cmPkgConfigParser.h
@@ -53,7 +53,6 @@ llpkgc_file_errno_t Parse(char const* input, std::size_t len); llpkgc_file_errno_t Finish(); - void Resume(); llpkgc_file_errno_t GetErrno() const; char const* ErrorReason() const; @@ -68,7 +67,7 @@ void AppendValue(std::string text, bool isSubstitution); - int OnSpanNext(char const*, std::size_t len); + int OnSpanNext(char const* at, std::size_t len); static int OnSpanNextTr(llpkgc_file_t* parser, char const* at, std::size_t len); @@ -105,7 +104,6 @@ OnIdentTr, OnValueLiteralTr, OnValueSubstitutionTr, - nullptr, // on_line_begin OnPropertyCompleteTr, OnVariableCompleteTr, OnBarewordsCompleteTr, @@ -115,8 +113,7 @@ nullptr, // on_pkgc_complete }; - char const* Ptr_ = nullptr; - std::size_t Len_ = 0; + std::string CurrentValue_; std::string Ident_; std::vector<cmPkgConfigEntry> Data_; }; @@ -153,13 +150,13 @@ enum class cmPkgConfigDependencyOperation { - None, - LessThan, - LessThanEqual, - Equal, - NotEqual, - GreaterThan, - GreaterThanEqual, + None = LLPKGC_DEP_ANY, + LessThan = LLPKGC_DEP_LESS_THAN, + LessThanEqual = LLPKGC_DEP_LESS_THAN_EQUAL, + Equal = LLPKGC_DEP_EQUAL, + NotEqual = LLPKGC_DEP_NOT_EQUAL, + GreaterThan = LLPKGC_DEP_GREATER_THAN, + GreaterThanEqual = LLPKGC_DEP_GREATER_THAN_EQUAL, }; struct cmPkgConfigDependencySpec @@ -191,10 +188,6 @@ static int OnDependencyNameTr(llpkgc_dep_t* parser, char const* at, std::size_t len); - int OnDependencyOperator(char const* at, std::size_t len); - static int OnDependencyOperatorTr(llpkgc_dep_t* parser, char const* at, - std::size_t len); - int OnDependencyVersion(char const* at, std::size_t len); static int OnDependencyVersionTr(llpkgc_dep_t* parser, char const* at, std::size_t len); @@ -203,10 +196,7 @@ static int OnDependencyCompleteTr(llpkgc_dep_t* parser); llpkgc_dep_settings_t Settings_{ - OnDependencyNameTr, - OnDependencyOperatorTr, - OnDependencyVersionTr, - OnDependencyCompleteTr, + OnDependencyNameTr, OnDependencyVersionTr, OnDependencyCompleteTr, nullptr, // on_dep_list_complete }; @@ -254,9 +244,6 @@ bool ResolveAndParse(std::string const& name, cmPkgConfigResolvedValue& cache); - static bool IsFragmentProperty(std::string const& lower); - static bool IsDependencyProperty(std::string const& lower); - cmPkgConfigFileParser File_; std::unordered_map<std::string, ValueItems> StoredVariables_; std::vector<cmPkgConfigEntry> StoredProperties_;
diff --git a/Source/cmPlistParser.cxx b/Source/cmPlistParser.cxx index d02eada..e1e38a0 100644 --- a/Source/cmPlistParser.cxx +++ b/Source/cmPlistParser.cxx
@@ -5,19 +5,42 @@ #include <iterator> #include <sstream> #include <string> +#include <utility> #include <vector> #include <cm3p/json/value.h> #include "cmJSONState.h" +#include "cmSystemTools.h" #include "cmUVProcessChain.h" #include "cmUVStream.h" +namespace { +std::vector<std::string> PlistToJsonCommand(std::string const& filename) +{ + static std::string const plutil = cmSystemTools::FindProgram("plutil"); + if (!plutil.empty()) { + return { plutil, "-convert", "json", "-o", "-", filename }; + } + + static std::string const plistutil = cmSystemTools::FindProgram("plistutil"); + if (!plistutil.empty()) { + return { plistutil, "-f", "json", "-o", "-", "-i", filename }; + } + + return {}; +} +} + cm::optional<Json::Value> cmParsePlist(std::string const& filename) { + std::vector<std::string> command = PlistToJsonCommand(filename); + if (command.empty()) { + return cm::nullopt; + } + cmUVProcessChainBuilder builder; - builder.AddCommand( - { "/usr/bin/plutil", "-convert", "json", "-o", "-", filename }); + builder.AddCommand(std::move(command)); builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT); auto chain = builder.Start();
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 2559d75..a0c99d8 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx
@@ -1402,25 +1402,6 @@ #endif } -void cmSystemTools::InitializeLibUV() -{ -#if defined(_WIN32) - // Perform libuv one-time initialization now, and then un-do its - // global _fmode setting so that using libuv does not change the - // default file text/binary mode. See libuv issue 840. - if (uv_loop_t* loop = uv_default_loop()) { - uv_loop_close(loop); - } -# ifdef _MSC_VER - _set_fmode(_O_TEXT); -# else - _fmode = _O_TEXT; -# endif - // Replace libuv's report handler with our own to suppress popups. - cmSystemTools::EnableMSVCDebugHook(); -#endif -} - #if defined(_WIN32) # include <random> @@ -3146,8 +3127,24 @@ #endif } -void cmSystemTools::FindCMakeResources(char const* argv0) +void cmSystemTools::InitializeCMake(char const* argv0) { +#if defined(_WIN32) + // Perform libuv one-time initialization now, and then un-do its + // global _fmode setting so that using libuv does not change the + // default file text/binary mode. See libuv issue 840. + if (uv_loop_t* loop = uv_default_loop()) { + uv_loop_close(loop); + } +# ifdef _MSC_VER + _set_fmode(_O_TEXT); +# else + _fmode = _O_TEXT; +# endif + // Replace libuv's report handler with our own to suppress popups. + cmSystemTools::EnableMSVCDebugHook(); +#endif + std::string exe = FindOwnExecutable(argv0); #ifdef CMAKE_BOOTSTRAP // The bootstrap cmake knows its resource locations. @@ -3249,6 +3246,16 @@ cm::optional<std::string> cmSystemTools::GetSystemConfigDirectory() { #if defined(_WIN32) + // Prefer %LOCALAPPDATA%, which Windows sets from the same known folder at + // logon. SHGetKnownFolderPath loads shell32 and its dependencies, which + // costs several milliseconds in every process that looks up this directory. + if (cm::optional<std::string> env = + cmSystemTools::GetEnvVar("LOCALAPPDATA")) { + if (cmSystemTools::FileIsFullPath(*env)) { + cmSystemTools::ConvertToUnixSlashes(*env); + return env; + } + } LPWSTR lpwstr; if (FAILED(SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &lpwstr))) { return cm::nullopt;
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 3f1235b..f326104 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h
@@ -554,10 +554,10 @@ std::string const& name, std::vector<std::string> const& path = std::vector<std::string>()); - /** Find the directory containing CMake executables. */ - static void FindCMakeResources(char const* argv0); + /** Initialize infrastructure common to CMake/CTest/CPack. */ + static void InitializeCMake(char const* argv0); - /** Get the CMake resource paths, after FindCMakeResources. */ + /** Get the CMake resource paths, after InitializeCMake. */ static std::string const& GetCTestCommand(); static std::string const& GetCPackCommand(); static std::string const& GetCMakeCommand(); @@ -652,9 +652,6 @@ static std::string GetRealPath(std::string const& path, std::string* errorMessage = nullptr); - /** Perform one-time initialization of libuv. */ - static void InitializeLibUV(); - /** Create a symbolic link if the platform supports it. Returns whether creation succeeded. */ static cmsys::Status CreateSymlink(std::string const& origName,
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 5cf1c46..f9d396b 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx
@@ -339,6 +339,7 @@ { "DISABLE_PRECOMPILE_HEADERS"_s, IC::CanCompileSources }, { "PCH_WARN_INVALID"_s, "ON"_s, IC::CanCompileSources }, { "PCH_INSTANTIATE_TEMPLATES"_s, "ON"_s, IC::CanCompileSources }, + { "PCH_WARNINGS"_s, IC::CanCompileSources }, // -- Platforms // ---- Android { "ANDROID_API"_s, IC::CanCompileSources }, @@ -411,6 +412,7 @@ { "Swift_SEPARATE_MODULE_EMISSION"_s, IC::CanCompileSources }, // ---- Rust { "Rust_EDITION"_s, IC::CanCompileSources }, + { "Rust_COMPILER_LAUNCHER"_s, IC::CanCompileSources }, { "Rust_MAIN_CRATE_ROOT"_s, IC::CanCompileSources }, // ---- moc { "AUTOMOC"_s, IC::CanCompileSources },
diff --git a/Source/cmValue.h b/Source/cmValue.h index 58edd54..9820d37 100644 --- a/Source/cmValue.h +++ b/Source/cmValue.h
@@ -136,11 +136,14 @@ } static bool IsNOTFOUND(cm::string_view) noexcept; - static bool IsEmpty(char const* value) noexcept + static constexpr bool IsEmpty(char const* value) noexcept { return !value || *value == '\0'; } - static bool IsEmpty(cm::string_view value) noexcept { return value.empty(); } + static constexpr bool IsEmpty(cm::string_view value) noexcept + { + return value.empty(); + } /** * Does a string indicates that CMake/CPack/CTest internally
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index cfdee1c..00056bf 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx
@@ -151,7 +151,7 @@ args.reserve(ac - 1); args.emplace_back(av[0]); cm::append(args, av + 2, av + ac); - return cmcmd::ExecuteCMakeCommand(args, std::move(console)); + return cmcmd::ExecuteCMakeCommand(std::move(args), std::move(console)); } cmMakefile* cmakemainGetMakefile(cmake* cm) @@ -952,8 +952,8 @@ "Options:\n" " <dir> = Project binary directory to install.\n" " --config <cfg> = For multi-configuration tools, choose <cfg>.\n" - " --component <comp> = Component-based install. Only install <comp>.\n" - " May be passed multiple components. t\n" + " --component <comp>...\n" + " Component-based install. Only install <comp>.\n" " --default-directory-permissions <permission> \n" " Default install permission. Use default permission <permission>.\n" " -j <jobs> --parallel <jobs>\n" @@ -1241,8 +1241,23 @@ ac = args.argc(); av = args.argv(); - cmSystemTools::InitializeLibUV(); - cmSystemTools::FindCMakeResources(av[0]); + // Dispatch "cmake -E" and "--print-config-dir" before the start-up + // work below, which they do not need. cmcmd does that work itself + // for the "-E" commands that do. + if (ac > 1) { + if (strcmp(av[1], "-E") == 0) { + return do_command(ac, av, std::move(console)); + } + if (strcmp(av[1], "--print-config-dir") == 0) { + std::cout << cmSystemTools::ConvertToOutputPath( + cmSystemTools::GetCMakeConfigDirectory().value_or( + std::string())) + << std::endl; + return 0; + } + } + + cmSystemTools::InitializeCMake(av[0]); if (ac > 1) { if (strcmp(av[1], "--build") == 0) { return do_build(ac, av); @@ -1256,16 +1271,6 @@ if (strcmp(av[1], "--workflow") == 0) { return do_workflow(ac, av); } - if (strcmp(av[1], "-E") == 0) { - return do_command(ac, av, std::move(console)); - } - if (strcmp(av[1], "--print-config-dir") == 0) { - std::cout << cmSystemTools::ConvertToOutputPath( - cmSystemTools::GetCMakeConfigDirectory().value_or( - std::string())) - << std::endl; - return 0; - } } int ret = do_cmake(ac, av); if (uv_loop_t* loop = uv_default_loop()) {
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index dce2588..8b2fc70 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx
@@ -3,6 +3,7 @@ #include "cmcmd.h" #include <algorithm> +#include <cstddef> #include <functional> #include <iomanip> #include <iterator> @@ -17,6 +18,7 @@ #include "cmCommandLineArgument.h" #include "cmCryptoHash.h" +#include "cmDiagnostics.h" #include "cmDuration.h" #include "cmEnvironment.h" #include "cmGeneratedFileStream.h" @@ -24,6 +26,7 @@ #include "cmList.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" +#include "cmMessenger.h" #include "cmProcessOutput.h" #include "cmQtAutoMocUic.h" #include "cmQtAutoRcc.h" @@ -81,6 +84,14 @@ #include "cmsys/FStream.hxx" #include "cmsys/RegularExpression.hxx" +// We need identifiers containing two underscores +// to make it easy to sort the commands table. +#if defined(__clang__) && defined(__has_warning) +# if __has_warning("-Wreserved-identifier") +# pragma clang diagnostic ignored "-Wreserved-identifier" +# endif +#endif + int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg, std::vector<std::string>::const_iterator argEnd); int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg, @@ -97,143 +108,39 @@ } namespace { -struct cmCommandLineHelpEntry +enum class Group { - char const* Name; - char const* Usage; - char const* Help; + Internal, + Common, + Windows, }; -// ATTENTION If you add new commands, change here, -// and in `cmakemain.cxx` in the options table -std::vector<cmCommandLineHelpEntry> const AvailableCommands = { - { "bin2c", "", "Turn a binary file into a C array" }, - { "capabilities", "", - "Report capabilities built into cmake in JSON format" }, - { "cat", "[--] <files>...", - "concat the files and print them to the standard output" }, - { "chdir", "dir cmd [args...]", "run command in a given directory" }, - { "compare_files", "[--ignore-eol] file1 file2", - "check if file1 is same as file2" }, - { "copy", "<file>... destination | -t <destination> <file>...", - "copy files to destination (either file or directory)" }, - { "copy_directory", "<dir>... destination | -t <destination> <dir>...", - "copy content of <dir>... directories to 'destination' directory" }, - { "copy_directory_if_different", - "<dir>... destination | -t <destination> <dir>...", - "copy changed content of <dir>... directories to 'destination' " - "directory" }, - { "copy_directory_if_newer", - "<dir>... destination | -t <destination> <dir>...", - "copy newer content of <dir>... directories to 'destination' " - "directory" }, - { "copy_if_different", "<file>... destination | -t <destination> <file>...", - "copy files if source has changed" }, - { "copy_if_newer", "<file>... destination | -t <destination> <file>...", - "copy files if source is newer than destination" }, - { "echo", "[<string>...]", "displays arguments as text" }, - { "echo_append", "[<string>...]", - "displays arguments as text but no new line" }, - { "env", "[--unset=NAME ...] [NAME=VALUE ...] [--] <command> [<arg>...]", - "run command in a modified environment" }, - { "environment", "", "display the current environment" }, - { "make_directory", "<dir>...", "create parent and <dir> directories" }, - { "md5sum", "<file>...", "create MD5 checksum of files" }, - { "sha1sum", "<file>...", "create SHA1 checksum of files" }, - { "sha224sum", "<file>...", "create SHA224 checksum of files" }, - { "sha256sum", "<file>...", "create SHA256 checksum of files" }, - { "sha384sum", "<file>...", "create SHA384 checksum of files" }, - { "sha512sum", "<file>...", "create SHA512 checksum of files" }, - { "remove", "[-f] <file>...", - "remove the file(s), use -f to force it (deprecated: use rm instead)" }, - { "remove_directory", "<dir>...", - "remove directories and their contents (deprecated: use rm instead)" }, - { "rename", "oldname newname", - "rename a file or directory (on one volume)" }, - { "rm", "[-rRf] [--] <file/dir>...", - "remove files or directories, use -f to force it, r or R to remove " - "directories and their contents recursively" }, - { "sleep", "<number>...", "sleep for given number of seconds" }, - { "tar", "[cxt][vf][zjJ] file.tar [file/dir1 file/dir2 ...]", - "create or extract a tar or zip archive" }, - { "time", "command [args...]", "run command and display elapsed time" }, - { "touch", "<file>...", "touch a <file>." }, - { "touch_nocreate", "<file>...", "touch a <file> but do not create it." }, - { "create_symlink", "old new", "create a symbolic link new -> old" }, - { "create_hardlink", "old new", "create a hard link new -> old" }, - { "true", "", "do nothing with an exit code of 0" }, - { "false", "", "do nothing with an exit code of 1" }, -}; - -#if defined(_WIN32) && !defined(__CYGWIN__) -std::vector<cmCommandLineHelpEntry> const AvailableWindowsCommands = { - { "delete_regv", "key", "delete registry value" }, - { "env_vs8_wince", "sdkname", - "displays a batch file which sets the environment for the provided " - "Windows CE SDK installed in VS2005" }, - { "env_vs9_wince", "sdkname", - "displays a batch file which sets the environment for the provided " - "Windows CE SDK installed in VS2008" }, - { "write_regv", "key value", "write registry value" }, -}; -#endif - -std::string FormatCommandLineHelp( - cm::string_view header, std::vector<cmCommandLineHelpEntry> const& entries) +struct Command { - std::size_t const helpColumn = 28; - std::string result = cmStrCat(header, ":\n"); - for (cmCommandLineHelpEntry const& entry : entries) { - std::string invocation = entry.Name; - if (*entry.Usage) { - invocation = cmStrCat(std::move(invocation), ' ', entry.Usage); - } - std::string line = cmStrCat(" ", invocation); - if (line.size() + 2 <= helpColumn) { - line.resize(helpColumn, ' '); - result = cmStrCat(std::move(result), line, "- ", entry.Help, '\n'); - } else { - result = cmStrCat(std::move(result), line, '\n', - std::string(helpColumn, ' '), "- ", entry.Help, '\n'); - } + cm::string_view Name; + + friend bool operator<(Command const& l, cm::string_view r) + { + return l.Name < r; } - return result; -} -std::vector<std::string> CommandLineHelpEntryNames( - std::vector<cmCommandLineHelpEntry> const& entries) -{ - std::vector<std::string> names; - names.reserve(entries.size()); - for (cmCommandLineHelpEntry const& entry : entries) { - names.emplace_back(entry.Name); - } - return names; -} + cm::string_view Usage; + cm::string_view Help; -void CMakeCommandUsage(std::string const& program) -{ - /* clang-format off */ - std::string help_screen = cmStrCat( -#ifndef CMAKE_BOOTSTRAP - "cmake version " - , cmVersion::GetCMakeVersion() - , "\n" -#else - "cmake bootstrap\n" -#endif - "Usage: " - , program - , " -E <command> [arguments...]\n" - , FormatCommandLineHelp("Available commands", AvailableCommands) -#if defined(_WIN32) && !defined(__CYGWIN__) - , FormatCommandLineHelp("Available on Windows only", - AvailableWindowsCommands) -#endif - ); - /* clang-format on */ - cmSystemTools::Error(help_screen); -} + struct Arguments : public std::vector<std::string> + { + Arguments(std::vector<std::string> args, + cm::optional<cm::StdIo::Console> console) + : vector(std::move(args)) + , Console(std::move(console)) + { + } + cm::optional<cm::StdIo::Console> Console; + }; + int (*Impl)(Arguments); + + ::Group Group; +}; bool cmTarFilesFrom(std::string const& file, std::vector<std::string>& files) { @@ -996,10 +903,35 @@ sout << Bin2CPrintChars(sin, printTrailingComma, printSigned, base, false); return true; } + +void IssueDeprecation(std::string const& text) +{ + // cmake -E mode does not accept -W options, so do not suggest them. + cmake cm(cmState::Role::Internal); + cm.GetMessenger()->SetSuppressionHint(cmMessenger::SuppressionHint::Hide); + cm.IssueDiagnostic(cmDiagnostics::CMD_DEPRECATED, text); } +int HandleCoCompileCommands(std::vector<std::string> const& args); +int CMakeCommandUsage(std::string const& program); +int HashSumFile(std::vector<std::string> const& args, cmCryptoHash::Algo algo); +int SymlinkLibrary(std::vector<std::string> const& args); +int SymlinkExecutable(std::vector<std::string> const& args); +cmsys::Status SymlinkInternal(std::string const& file, + std::string const& link); +int ExecuteEchoColor(std::vector<std::string> const& args); +int ExecuteLinkScript(std::vector<std::string> const& args); +#if defined(_WIN32) && !defined(__CYGWIN__) +int WindowsCEEnvironment(char const* version, std::string const& name); +#endif +int RunPreprocessor(std::vector<std::string> const& command, + std::string const& intermediate_file); +int RunLLVMRC(std::vector<std::string> const& args); +int VisualStudioLink(std::vector<std::string> const& args, int type, + cm::optional<cm::StdIo::Console> console); + // called when args[0] == "__run_co_compile" -int cmcmd::HandleCoCompileCommands(std::vector<std::string> const& args) +int HandleCoCompileCommands(std::vector<std::string> const& args) { std::vector<CoCompileJob> jobs; std::string sourceFile; // store --source= @@ -1099,1455 +1031,2130 @@ return ret; } -int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args, - cm::optional<cm::StdIo::Console> console) +// Copy file, copy file if different, copy file if newer. +int _cmake_E_copy(Command::Arguments args) { - // IF YOU ADD A NEW COMMAND, DOCUMENT IT ABOVE and in cmakemain.cxx - if (args.size() > 1) { - // Copy file, copy file if different, copy file if newer. - if ((args[1] == "copy" || args[1] == "copy_if_different" || - args[1] == "copy_if_newer") && - args.size() > 3) { - using CopyFn = cmsys::SystemTools::CopyStatus (*)(std::string const&, - std::string const&); - CopyFn copyFn; - std::string copyErrPrefix; - if (args[1] == "copy") { - copyFn = cmSystemTools::CopyFileAlways; - copyErrPrefix = "Error copying file"; - } else if (args[1] == "copy_if_different") { - copyFn = cmSystemTools::CopyFileIfDifferent; - copyErrPrefix = "Error copying file (if different) from"; - } else { - copyFn = cmSystemTools::CopyFileIfNewer; - copyErrPrefix = "Error copying file (if newer) from"; - } - std::string const& cmdName = args[1]; + if (args.size() <= 3) { + return CMakeCommandUsage(args[0]); + } + using CopyFn = + cmsys::SystemTools::CopyStatus (*)(std::string const&, std::string const&); + CopyFn copyFn; + std::string copyErrPrefix; + if (args[1] == "copy") { + copyFn = cmSystemTools::CopyFileAlways; + copyErrPrefix = "Error copying file"; + } else if (args[1] == "copy_if_different") { + copyFn = cmSystemTools::CopyFileIfDifferent; + copyErrPrefix = "Error copying file (if different) from"; + } else { + copyFn = cmSystemTools::CopyFileIfNewer; + copyErrPrefix = "Error copying file (if newer) from"; + } + std::string const& cmdName = args[1]; - using CommandArgument = - cmCommandLineArgument<bool(std::string const& value)>; + using CommandArgument = + cmCommandLineArgument<bool(std::string const& value)>; - cm::optional<std::string> targetArg; - std::vector<CommandArgument> argParsers{ - { "-t", CommandArgument::Values::One, - CommandArgument::setToValue(targetArg) }, - }; + cm::optional<std::string> targetArg; + std::vector<CommandArgument> argParsers{ + { "-t", CommandArgument::Values::One, + CommandArgument::setToValue(targetArg) }, + }; - std::vector<std::string> files; - for (decltype(args.size()) i = 2; i < args.size(); i++) { - std::string const& arg = args[i]; - bool matched = false; - for (auto const& m : argParsers) { - if (m.matches(arg)) { - matched = true; - if (m.parse(arg, i, args)) { - break; - } - return 1; // failed to parse - } - } - if (!matched) { - files.push_back(arg); - } - } - - // If multiple source files specified, - // then destination must be directory - if (files.size() > 2 && !targetArg) { - targetArg = files.back(); - files.pop_back(); - } - if (targetArg && (!cmSystemTools::FileIsDirectory(*targetArg))) { - std::cerr << "Error: Target (for " << cmdName << " command) \"" - << *targetArg << "\" is not a directory.\n"; - return 1; - } - if (!targetArg) { - if (files.size() < 2) { - std::cerr << "Error: No files or target specified (for " << cmdName - << " command).\n"; - return 1; - } - targetArg = files.back(); - files.pop_back(); - } - // If error occurs we want to continue copying next files. - bool return_value = false; - for (auto const& file : files) { - cmsys::SystemTools::CopyStatus const status = copyFn(file, *targetArg); - if (!status) { - std::cerr << copyErrPrefix << " \"" << file << "\" to \"" - << *targetArg << "\": " << status.GetString() << '\n'; - return_value = true; - } - } - return return_value; - } - - // Copy directory contents - if (args[1] == "copy_directory" || - args[1] == "copy_directory_if_different" || - args[1] == "copy_directory_if_newer") { - cmsys::SystemTools::CopyWhen when = - cmsys::SystemTools::CopyWhen::Unconditional; - if (args[1] == "copy_directory_if_different") { - when = cmsys::SystemTools::CopyWhen::OnlyIfDifferent; - } else if (args[1] == "copy_directory_if_newer") { - when = cmsys::SystemTools::CopyWhen::OnlyIfNewer; - } - std::string const& cmdName = args[1]; - - using CommandArgument = - cmCommandLineArgument<bool(std::string const& value)>; - - cm::optional<std::string> targetArg; - std::vector<CommandArgument> argParsers{ - { "-t", CommandArgument::Values::One, - CommandArgument::setToValue(targetArg) }, - }; - - std::vector<std::string> dirs; - for (decltype(args.size()) i = 2; i < args.size(); i++) { - std::string const& arg = args[i]; - bool matched = false; - for (auto const& m : argParsers) { - if (m.matches(arg)) { - matched = true; - if (m.parse(arg, i, args)) { - break; - } - return 1; // failed to parse - } - } - if (!matched) { - dirs.push_back(arg); - } - } - - if (!targetArg) { - if (dirs.size() < 2) { - std::cerr << "Error: No directories or target specified (for " - << cmdName << " command).\n"; - return 1; - } - targetArg = dirs.back(); - dirs.pop_back(); - } - if (dirs.empty()) { - std::cerr << "Error: No source directories specified (for " << cmdName - << " command).\n"; - return 1; - } - - // If error occurs we want to continue copying next files. - bool return_value = false; - for (auto const& dir : dirs) { - cmsys::Status const status = - cmSystemTools::CopyADirectory(dir, *targetArg, when); - if (!status) { - std::cerr << "Error copying directory from \"" << dir << "\" to \"" - << *targetArg << "\": " << status.GetString() << '\n'; - return_value = true; - } - } - return return_value; - } - - // Rename a file or directory - if (args[1] == "rename" && args.size() == 4) { - if (!cmSystemTools::RenameFile(args[2], args[3])) { - std::string e = cmSystemTools::GetLastSystemError(); - std::cerr << "Error renaming from \"" << args[2] << "\" to \"" - << args[3] << "\": " << e << "\n"; - return 1; - } - return 0; - } - - // Compare files - if (args[1] == "compare_files" && (args.size() == 4 || args.size() == 5)) { - bool filesDiffer; - if (args.size() == 4) { - filesDiffer = cmSystemTools::FilesDiffer(args[2], args[3]); - } else if (args[2] == "--ignore-eol") { - filesDiffer = cmsys::SystemTools::TextFilesDiffer(args[3], args[4]); - } else { - CMakeCommandUsage(args[0]); - return 2; - } - - if (filesDiffer) { - return 1; - } - return 0; - } - -#if !defined(CMAKE_BOOTSTRAP) - if (args[1] == "__create_def") { - if (args.size() < 4) { - std::cerr << "__create_def Usage: -E __create_def outfile.def " - "objlistfile [--nm=nm-path]\n"; - return 1; - } - cmsys::ifstream fin(args[3].c_str(), std::ios::in | std::ios::binary); - if (!fin) { - std::cerr << "could not open object list file: " << args[3] << '\n'; - return 1; - } - std::vector<std::string> defFiles; - std::vector<std::string> objFiles; - { - std::string file; - cmFileTime outTime; - bool outValid = outTime.Load(args[2]); - while (cmSystemTools::GetLineFromStream(fin, file)) { - std::string const& ext = - cmSystemTools::GetFilenameLastExtension(file); - if (cmSystemTools::LowerCase(ext) == ".def") { - defFiles.push_back(file); - } else { - objFiles.push_back(file); - } - if (outValid) { - cmFileTime inTime; - outValid = inTime.Load(file) && inTime.Older(outTime); - } - } - if (outValid) { - // The def file already exists and all input files are older than - // the existing def file. - return 0; - } - } - fin.close(); - cmsys::ofstream fout(args[2].c_str()); - if (!fout) { - std::cerr << "could not open output .def file: " << args[2] << '\n'; - return 1; - } - bindexplib deffile; - if (args.size() >= 5) { - std::string const& a = args[4]; - if (cmHasLiteralPrefix(a, "--nm=")) { - deffile.SetNmPath(a.substr(5)); - } else { - std::cerr << "unknown argument: " << a << '\n'; - } - } - if (!deffile.AddDefinitionFile(defFiles) || - !deffile.AddObjectFile(objFiles, cmStrCat(args[3], ".rsp"))) { - return 1; - } - if (!deffile.WriteFile(fout)) { - std::cerr << "could not write output .def file: " << args[2] << '\n'; - return 1; - } - return 0; - } -#endif - if (args[1] == "__run_co_compile") { - return cmcmd::HandleCoCompileCommands(args); - } - - // Echo string - if (args[1] == "echo") { - std::cout << cmJoin(cmMakeRange(args).advance(2), " ") << std::endl; - return 0; - } - - // Echo string no new line - if (args[1] == "echo_append") { - std::cout << cmJoin(cmMakeRange(args).advance(2), " "); - return 0; - } - - if (args[1] == "env") { -#ifndef CMAKE_BOOTSTRAP - auto envdiff = cmEnvironmentModification{}; -#endif - - auto ai = args.cbegin() + 2; - auto ae = args.cend(); - for (; ai != ae; ++ai) { - std::string const& a = *ai; - if (a == "--") { - // Stop parsing options/environment variables; the next argument - // should be the command. - ++ai; + std::vector<std::string> files; + for (decltype(args.size()) i = 2; i < args.size(); i++) { + std::string const& arg = args[i]; + bool matched = false; + for (auto const& m : argParsers) { + if (m.matches(arg)) { + matched = true; + if (m.parse(arg, i, args)) { break; } - if (cmHasLiteralPrefix(a, "--unset=")) { - // Unset environment variable. -#ifdef CMAKE_BOOTSTRAP - cmSystemTools::UnPutEnv(a.substr(8)); -#else - envdiff.Add(a.substr(8) + "=unset:"); -#endif - } else if (a == "--modify") { -#ifdef CMAKE_BOOTSTRAP - std::cerr - << "cmake -E env: --modify not available during bootstrapping\n"; - return 1; -#else - if (++ai == ae) { - std::cerr << "cmake -E env: --modify missing a parameter\n"; - return 1; - } - std::string const& op = *ai; - if (!envdiff.Add(op)) { - std::cerr << "cmake -E env: invalid parameter to --modify: " << op - << '\n'; - return 1; - } -#endif - } else if (!a.empty() && a[0] == '-') { - // Environment variable and command names cannot start in '-', - // so this must be an unknown option. - std::cerr << "cmake -E env: unknown option '" << a << "'\n"; - return 1; - } else if (a.find('=') != std::string::npos) { - // Set environment variable. -#ifdef CMAKE_BOOTSTRAP - cmSystemTools::PutEnv(a); -#else - auto const pos = a.find('='); - std::string const& name = a.substr(0, pos); - std::string const& value = a.substr(pos + 1); - envdiff.Add(cmStrCat(name, "=set:", value)); -#endif - } else { - // This is the beginning of the command. - break; - } + return 1; // failed to parse } - - if (ai == ae) { - std::cerr << "cmake -E env: no command given\n"; - return 1; - } - - auto env = cmEnvironment{}; -#ifndef CMAKE_BOOTSTRAP - env.Update(cmSystemTools::GetEnvironmentVariables()); - envdiff.ApplyTo(env); -#endif - - // Execute command from remaining arguments. - std::vector<std::string> cmd(ai, ae); - int retval; - if (cmSystemTools::RunSingleCommand( - cmd, nullptr, nullptr, &retval, nullptr, - cmSystemTools::OUTPUT_PASSTHROUGH, cmDuration::zero(), - cmProcessOutput::Auto, env.GetVariables())) { - return retval; - } - return 1; } - -#if !defined(CMAKE_BOOTSTRAP) - if (args[1] == "environment") { - for (auto const& env : cmSystemTools::GetEnvironmentVariables()) { - std::cout << env << std::endl; - } - return 0; - } -#endif - - if (args[1] == "make_directory" && args.size() > 2) { - // If an error occurs, we want to continue making directories. - bool return_value = false; - for (auto const& arg : cmMakeRange(args).advance(2)) { - cmsys::Status const status = cmSystemTools::MakeDirectory(arg); - if (!status) { - std::cerr << "Error creating directory \"" << arg - << "\": " << status.GetString() << '\n'; - return_value = true; - } - } - return return_value; - } - - if (args[1] == "remove_directory" && args.size() > 2) { - // If an error occurs, we want to continue removing directories. - bool return_value = false; - for (auto const& arg : cmMakeRange(args).advance(2)) { - if (cmSystemTools::FileIsDirectory(arg)) { - if (!cmRemoveDirectory(arg)) { - return_value = true; - } - } - } - return return_value; - } - - // Remove file - if (args[1] == "remove" && args.size() > 2) { - bool force = false; - for (auto const& arg : cmMakeRange(args).advance(2)) { - if (arg == "\\-f" || arg == "-f") { - force = true; - } else { - // Complain if the file could not be removed, still exists, - // and the -f option was not given. - if (!cmSystemTools::RemoveFile(arg) && !force && - cmSystemTools::FileExists(arg)) { - return 1; - } - } - } - return 0; - } - - // Remove directories or files with rm - if (args[1] == "rm" && args.size() > 2) { - // If an error occurs, we want to continue removing the remaining - // files/directories. - int return_value = 0; - bool force = false; - bool recursive = false; - bool doing_options = true; - bool at_least_one_file = false; - for (auto const& arg : cmMakeRange(args).advance(2)) { - if (doing_options && cmHasPrefix(arg, '-')) { - if (arg == "--") { - doing_options = false; - } - if (arg.find('f') != std::string::npos) { - force = true; - } - if (arg.find_first_of("rR") != std::string::npos) { - recursive = true; - } - if (arg.find_first_not_of("-frR") != std::string::npos) { - cmSystemTools::Error("Unknown -E rm argument: " + arg); - return 1; - } - } else { - if (arg.empty()) { - continue; - } - at_least_one_file = true; - // Complain if the -f option was not given and - // either file does not exist or - // file could not be removed and still exists - bool file_exists_or_forced_remove = - cmSystemTools::PathExists(arg) || force; - if (cmSystemTools::FileIsDirectory(arg)) { - if (!cmRemoveDirectory(arg, recursive)) { - return_value = 1; - } - } else if ((!file_exists_or_forced_remove) || - (!cmSystemTools::RemoveFile(arg) && - cmSystemTools::FileExists(arg))) { - if (!file_exists_or_forced_remove) { - cmSystemTools::Error( - "File to remove does not exist and force is not set: " + arg); - } else { - cmSystemTools::Error("File can't be removed and still exist: " + - arg); - } - return_value = 1; - } - } - } - if (!at_least_one_file) { - cmSystemTools::Error("Missing file/directory to remove"); - return 1; - } - return return_value; - } - - // Touch file - if (args[1] == "touch" && args.size() > 2) { - for (auto const& arg : cmMakeRange(args).advance(2)) { - if (!cmSystemTools::Touch(arg, true)) { - std::cerr << "cmake -E touch: failed to update \"" << arg << "\".\n"; - return 1; - } - } - return 0; - } - - // Touch file - if (args[1] == "touch_nocreate" && args.size() > 2) { - for (auto const& arg : cmMakeRange(args).advance(2)) { - if (!cmSystemTools::Touch(arg, false)) { - std::cerr << "cmake -E touch_nocreate: failed to update \"" << arg - << "\".\n"; - return 1; - } - } - return 0; - } - - // capabilities - if (args[1] == "capabilities") { - if (args.size() > 2) { - std::cerr << "-E capabilities accepts no additional arguments\n"; - return 1; - } - cmake cm(cmState::Role::Internal); - std::cout << cm.ReportCapabilities(); - return 0; - } - - // Sleep command - if (args[1] == "sleep" && args.size() > 2) { - double total = 0; - for (auto const& arg : cmMakeRange(args).advance(2)) { - double num = 0.0; - char unit; - char extra; - int n = sscanf(arg.c_str(), "%lg%c%c", &num, &unit, &extra); - if ((n == 1 || (n == 2 && unit == 's')) && num >= 0) { - total += num; - } else { - std::cerr << "Unknown sleep time format \"" << arg << "\".\n"; - return 1; - } - } - if (total > 0) { - cmSystemTools::Delay(static_cast<unsigned int>(total * 1000)); - } - return 0; - } - - // Clock command - if (args[1] == "time" && args.size() > 2) { - std::vector<std::string> command(args.begin() + 2, args.end()); - - int ret = 0; - auto time_start = std::chrono::steady_clock::now(); - cmSystemTools::RunSingleCommand(command, nullptr, nullptr, &ret, nullptr, - cmSystemTools::OUTPUT_PASSTHROUGH); - auto time_finish = std::chrono::steady_clock::now(); - - std::chrono::duration<double> time_elapsed = time_finish - time_start; - std::cout << "Elapsed time (seconds): " << time_elapsed.count() << '\n'; - return ret; - } - - // Command to calculate the md5sum of a file - if (args[1] == "md5sum" && args.size() >= 3) { - return HashSumFile(args, cmCryptoHash::AlgoMD5); - } - - // Command to calculate the sha1sum of a file - if (args[1] == "sha1sum" && args.size() >= 3) { - return HashSumFile(args, cmCryptoHash::AlgoSHA1); - } - - if (args[1] == "sha224sum" && args.size() >= 3) { - return HashSumFile(args, cmCryptoHash::AlgoSHA224); - } - - if (args[1] == "sha256sum" && args.size() >= 3) { - return HashSumFile(args, cmCryptoHash::AlgoSHA256); - } - - if (args[1] == "sha384sum" && args.size() >= 3) { - return HashSumFile(args, cmCryptoHash::AlgoSHA384); - } - - if (args[1] == "sha512sum" && args.size() >= 3) { - return HashSumFile(args, cmCryptoHash::AlgoSHA512); - } - - // Command to concat files into one - if (args[1] == "cat") { - if (args.size() == 2) { - // Destroy console buffers to drop cout/cerr encoding transform. - console.reset(); - cmCatFile(cm::nullopt); - return 0; - } - int return_value = 0; - bool doing_options = true; - for (auto const& arg : cmMakeRange(args).advance(2)) { - if (arg == "-") { - doing_options = false; - // Destroy console buffers to drop cout/cerr encoding transform. - console.reset(); - cmCatFile(cm::nullopt); - } else if (doing_options && cmHasPrefix(arg, '-')) { - if (arg == "--") { - doing_options = false; - } else { - cmSystemTools::Error(arg + ": option not handled"); - return_value = 1; - } - } else if (!cmSystemTools::TestFileAccess(arg, - cmsys::TEST_FILE_READ) && - cmSystemTools::TestFileAccess(arg, cmsys::TEST_FILE_OK)) { - cmSystemTools::Error(arg + ": permission denied (ignoring)"); - return_value = 1; - } else if (cmSystemTools::FileIsDirectory(arg)) { - cmSystemTools::Error(arg + ": is a directory (ignoring)"); - return_value = 1; - } else if (!cmSystemTools::FileExists(arg)) { - cmSystemTools::Error(arg + ": no such file or directory (ignoring)"); - return_value = 1; - } else if (cmSystemTools::FileLength(arg) == 0) { - // Ignore empty files, this is not an error - } else { - // Destroy console buffers to drop cout/cerr encoding transform. - console.reset(); - cmCatFile(arg); - } - } - return return_value; - } - - // Command to change directory and run a program. - if (args[1] == "chdir" && args.size() >= 4) { - std::string const& directory = args[2]; - if (!cmSystemTools::FileExists(directory)) { - cmSystemTools::Error("Directory does not exist for chdir command: " + - directory); - return 1; - } - - std::string command = - cmWrap('"', cmMakeRange(args).advance(3), '"', " "); - int retval = 0; - if (cmSystemTools::RunSingleCommand( - command, nullptr, nullptr, &retval, directory.c_str(), - cmSystemTools::OUTPUT_PASSTHROUGH, cmDuration::zero())) { - return retval; - } - - return 1; - } - - // Command to start progress for a build - if (args[1] == "cmake_progress_start" && args.size() == 4) { - // basically remove the directory - std::string dirName = cmStrCat(args[2], "/Progress"); - cmSystemTools::RemoveADirectory(dirName); - - // is the last argument a filename that exists? - FILE* countFile = cmsys::SystemTools::Fopen(args[3], "r"); - int count; - if (countFile) { - if (1 != fscanf(countFile, "%i", &count)) { - std::cerr << "Could not read from count file.\n"; - } - fclose(countFile); - } else { - count = atoi(args[3].c_str()); - } - if (count) { - cmSystemTools::MakeDirectory(dirName); - // write the count into the directory - std::string fName = cmStrCat(dirName, "/count.txt"); - FILE* progFile = cmsys::SystemTools::Fopen(fName, "w"); - if (progFile) { - fprintf(progFile, "%i\n", count); - fclose(progFile); - } - } - return 0; - } - - // Command to report progress for a build - if (args[1] == "cmake_progress_report" && args.size() >= 3) { - // This has been superseded by cmake_echo_color --progress-* - // options. We leave it here to avoid errors if somehow this - // is invoked by an existing makefile without regenerating. - return 0; - } - - // Command to create a symbolic link. Fails on platforms not - // supporting them. - if (args[1] == "create_symlink" && args.size() == 4) { - std::string const& destinationFileName = args[3]; - if (cmSystemTools::PathExists(destinationFileName) && - !cmSystemTools::RemoveFile(destinationFileName)) { - std::string emsg = cmSystemTools::GetLastSystemError(); - std::cerr << "failed to create symbolic link '" << destinationFileName - << "' because existing path cannot be removed: " << emsg - << '\n'; - return 1; - } - if (!cmSystemTools::CreateSymlink(args[2], destinationFileName)) { - return 1; - } - return 0; - } - - // Command to create a hard link. Fails on platforms not - // supporting them. - if (args[1] == "create_hardlink" && args.size() == 4) { - std::string const& sourceFileName = args[2]; - std::string const& destinationFileName = args[3]; - - if (!cmSystemTools::FileExists(sourceFileName)) { - std::cerr << "failed to create hard link because source path '" - << sourceFileName << "' does not exist\n"; - return 1; - } - - if (cmSystemTools::PathExists(destinationFileName) && - !cmSystemTools::RemoveFile(destinationFileName)) { - std::string emsg = cmSystemTools::GetLastSystemError(); - std::cerr << "failed to create hard link '" << destinationFileName - << "' because existing path cannot be removed: " << emsg - << '\n'; - return 1; - } - - if (!cmSystemTools::CreateLink(sourceFileName, destinationFileName)) { - return 1; - } - return 0; - } - - // Command to do nothing with an exit code of 0. - if (args[1] == "true") { - return 0; - } - - // Command to do nothing with an exit code of 1. - if (args[1] == "false") { - return 1; - } - - // Internal CMake shared library support. - if (args[1] == "cmake_symlink_library" && args.size() == 5) { - return cmcmd::SymlinkLibrary(args); - } - - // Internal CMake versioned executable support. - if (args[1] == "cmake_symlink_executable" && args.size() == 4) { - return cmcmd::SymlinkExecutable(args); - } - - // Internal CMake dependency scanning support. - // The format is: -E cmake_fastbuild_check_depends <dummy_file> - // <space_separated_list_of_real_outputs> - if (args[1] == "cmake_fastbuild_check_depends" && args.size() >= 3) { - auto const dummyFile = args[2]; - for (auto const& arg : cmMakeRange(args).advance(3)) { - if (!cmSystemTools::FileExists(arg)) { - cmSystemTools::RemoveFile(dummyFile); - return 0; - } - } - return 0; - } - if (args[1] == "cmake_depends" && args.size() >= 6) { - bool const verbose = isCMakeVerbose(); - - // Create a cmake object instance to process dependencies. - // All we need is the `set` command. - cmake cm(cmState::Role::Script); - std::string gen; - std::string homeDir; - std::string startDir; - std::string homeOutDir; - std::string startOutDir; - std::string depInfo; - std::string targetName; - bool color = false; - if (args.size() >= 8) { - // Full signature: - // - // -E cmake_depends <generator> - // <home-src-dir> <start-src-dir> - // <home-out-dir> <start-out-dir> - // <dep-info> [--color=$(COLOR)] - // <target-name> - // - // All paths are provided. - gen = args[2]; - homeDir = args[3]; - startDir = args[4]; - homeOutDir = args[5]; - startOutDir = args[6]; - depInfo = args[7]; - size_t targetNameIdx = 8; - if (args.size() >= 9 && cmHasLiteralPrefix(args[8], "--color=")) { - // Enable or disable color based on the switch value. - targetNameIdx = 9; - color = (args[8].size() == 8 || cmIsOn(args[8].substr(8))); - } - if (args.size() > targetNameIdx) { - targetName = args[targetNameIdx]; - } else { - std::string targetDir = cmSystemTools::GetFilenamePath(depInfo); - targetDir = cmSystemTools::GetFilenameName(targetDir); - targetName = targetDir.substr(0, targetDir.size() - 4); - } - } else { - // Support older signature for existing makefiles: - // - // -E cmake_depends <generator> - // <home-out-dir> <start-out-dir> - // <dep-info> - // - // Just pretend the source directories are the same as the - // binary directories so at least scanning will work. - gen = args[2]; - homeDir = args[3]; - startDir = args[4]; - homeOutDir = args[3]; - startOutDir = args[3]; - depInfo = args[5]; - // Strip the `.dir` suffix. Old CMake always uses this pattern. - std::string targetDir = cmSystemTools::GetFilenamePath(depInfo); - targetDir = cmSystemTools::GetFilenameName(targetDir); - targetName = targetDir.substr(0, targetDir.size() - 4); - } - - // Create a local generator configured for the directory in - // which dependencies will be scanned. - homeDir = cmSystemTools::ToNormalizedPathOnDisk(homeDir); - startDir = cmSystemTools::ToNormalizedPathOnDisk(startDir); - homeOutDir = cmSystemTools::ToNormalizedPathOnDisk(homeOutDir); - startOutDir = cmSystemTools::ToNormalizedPathOnDisk(startOutDir); - cm.SetHomeDirectory(homeDir); - cm.SetHomeOutputDirectory(homeOutDir); - cm.GetCurrentSnapshot().SetDefaultDefinitions(); - if (auto ggd = cm.CreateGlobalGenerator(gen)) { - cm.SetGlobalGenerator(std::move(ggd)); - cmStateSnapshot snapshot = cm.GetCurrentSnapshot(); - snapshot.GetDirectory().SetCurrentBinary(startOutDir); - snapshot.GetDirectory().SetCurrentSource(startDir); - cmMakefile mf(cm.GetGlobalGenerator(), snapshot); - auto lgd = cm.GetGlobalGenerator()->CreateLocalGenerator(&mf); - - // FIXME: With advanced add_subdirectory usage, these are - // not necessarily the same as the generator originally used. - // We should pass all these directories through an info file. - lgd->SetRelativePathTop(homeDir, homeOutDir); - - // Actually scan dependencies. - return lgd->UpdateDependencies(depInfo, targetName, verbose, color) - ? 0 - : 2; - } - return 1; - } - -#if !defined(CMAKE_BOOTSTRAP) || defined(CMAKE_BOOTSTRAP_MAKEFILES) - // Internal CMake compiler dependencies filtering - if (args[1] == "cmake_cl_compile_depends") { - return CLCompileAndDependencies(args); - } -#endif - - // Internal CMake link script support. - if (args[1] == "cmake_link_script" && args.size() >= 3) { - return cmcmd::ExecuteLinkScript(args); - } - -#if !defined(CMAKE_BOOTSTRAP) - // Internal CMake ninja dependency scanning support. - if (args[1] == "cmake_ninja_depends") { - return cmcmd_cmake_ninja_depends(args.begin() + 2, args.end()); - } - - // Internal CMake ninja dyndep support. - if (args[1] == "cmake_ninja_dyndep") { - return cmcmd_cmake_ninja_dyndep(args.begin() + 2, args.end()); - } -#endif - - // Internal CMake C++ module compilation database support. - if (args[1] == "cmake_module_compile_db") { - return cmcmd_cmake_module_compile_db(args.begin() + 2, args.end()); - } - - // Internal CMake unimplemented feature notification. - if (args[1] == "cmake_unimplemented_variable") { - std::cerr << "Feature not implemented for this platform."; - if (args.size() == 3) { - std::cerr << " Variable " << args[2] << " is not set."; - } - std::cerr << '\n'; - return 1; - } - - if (args[1] == "vs_link_exe") { - return cmcmd::VisualStudioLink(args, 1, std::move(console)); - } - - if (args[1] == "vs_link_dll") { - return cmcmd::VisualStudioLink(args, 2, std::move(console)); - } - - if (args[1] == "cmake_llvm_rc") { - return cmcmd::RunLLVMRC(args); - } - - // Internal CMake color makefile support. - if (args[1] == "cmake_echo_color") { - return cmcmd::ExecuteEchoColor(args); - } - -#ifndef CMAKE_BOOTSTRAP - if ((args[1] == "cmake_autogen") && (args.size() >= 4)) { - cm::string_view const infoFile = args[2]; - cm::string_view const config = args[3]; - cm::string_view const executableConfig = - (args.size() >= 5) ? cm::string_view(args[4]) : cm::string_view(); - return cmQtAutoMocUic(infoFile, config, executableConfig) ? 0 : 1; - } - if ((args[1] == "cmake_autorcc") && (args.size() >= 3)) { - cm::string_view const infoFile = args[2]; - cm::string_view const config = - (args.size() > 3) ? cm::string_view(args[3]) : cm::string_view(); - cm::string_view const executableConfig = - (args.size() >= 5) ? cm::string_view(args[4]) : cm::string_view(); - return cmQtAutoRcc(infoFile, config, executableConfig) ? 0 : 1; - } -#endif - - // Tar files - if (args[1] == "tar" && args.size() > 3) { - char const* knownFormats[] = { "7zip", "gnutar", "pax", - "paxr", "raw", "zip" }; - - std::string const& flags = args[2]; - std::string const& outFile = args[3]; - std::vector<std::string> files; - std::string mtime; - std::string format; - int numThreads = 1; - int compressionLevel = 0; - bool compressionLevelFlagPassed = false; - cmSystemTools::cmTarExtractTimestamps extractTimestamps = - cmSystemTools::cmTarExtractTimestamps::Yes; - cmSystemTools::cmTarCompression compress = - cmSystemTools::TarCompressAuto; - int nCompress = 0; - bool doing_options = true; - std::string encoding = "UTF-8"; - for (auto const& arg : cmMakeRange(args).advance(4)) { - if (doing_options && cmHasLiteralPrefix(arg, "--")) { - if (arg == "--") { - doing_options = false; - } else if (arg == "--zstd") { - compress = cmSystemTools::TarCompressZstd; - ++nCompress; - } else if (arg == "--lzma") { - compress = cmSystemTools::TarCompressLZMA; - ++nCompress; - } else if (cmHasLiteralPrefix(arg, "--mtime=")) { - mtime = arg.substr(8); - } else if (cmHasLiteralPrefix(arg, "--cmake-tar-threads=")) { - std::string const& numThreadsStr = arg.substr(20); - long numThreadsLong = 0; - if (!cmStrToLong(numThreadsStr, &numThreadsLong)) { - cmSystemTools::Error( - cmStrCat("Invalid --cmake-tar-threads value: '", numThreadsStr, - "' - not a number")); - return 1; - } - if (numThreadsLong > - std::numeric_limits<decltype(numThreads)>::max()) { - cmSystemTools::Error( - cmStrCat("Invalid --cmake-tar-threads value: '", numThreadsStr, - "' - too large")); - return 1; - } - if (numThreadsLong < - std::numeric_limits<decltype(numThreads)>::min()) { - cmSystemTools::Error( - cmStrCat("Invalid --cmake-tar-threads value: '", numThreadsStr, - "' - too small")); - return 1; - } - - numThreads = static_cast<decltype(numThreads)>(numThreadsLong); - } else if (cmHasLiteralPrefix(arg, "--cmake-tar-encoding=")) { - encoding = arg.substr(21); - if (encoding.empty()) { - cmSystemTools::Error( - "Encoding value is empty - it must be filled if passed"); - return 1; - } - } else if (cmHasLiteralPrefix(arg, - "--cmake-tar-compression-level=")) { - std::string const& compressionLevelStr = arg.substr(30); - long compressionLevelLong = 0; - if (!cmStrToLong(compressionLevelStr, &compressionLevelLong)) { - cmSystemTools::Error( - cmStrCat("Invalid --cmake-tar-compression-level value: '", - compressionLevelStr, "' - not a number")); - return 1; - } - if (compressionLevelLong > - std::numeric_limits<decltype(compressionLevel)>::max()) { - cmSystemTools::Error( - cmStrCat("Invalid --cmake-tar-compression-level value: '", - compressionLevelStr, "' - too large")); - return 1; - } - if (compressionLevelLong < - std::numeric_limits<decltype(compressionLevel)>::min()) { - cmSystemTools::Error( - cmStrCat("Invalid --cmake-tar-compression-level value: '", - compressionLevelStr, "' - too small")); - return 1; - } - - compressionLevel = - static_cast<decltype(compressionLevel)>(compressionLevelLong); - compressionLevelFlagPassed = true; - } else if (cmHasLiteralPrefix(arg, - "--cmake-tar-compression-method=")) { - std::string const& compressionMethodStr = arg.substr(31); - if (compressionMethodStr == "none" || - compressionMethodStr == "store") { - compress = cmSystemTools::TarCompressNone; - ++nCompress; - } else if (compressionMethodStr == "deflate" || - compressionMethodStr == "gzip") { - compress = cmSystemTools::TarCompressGZip; - ++nCompress; - } else if (compressionMethodStr == "bzip2") { - compress = cmSystemTools::TarCompressBZip2; - ++nCompress; - } else if (compressionMethodStr == "lzma") { - compress = cmSystemTools::TarCompressLZMA; - ++nCompress; - } else if (compressionMethodStr == "lzma2" || - compressionMethodStr == "xz") { - compress = cmSystemTools::TarCompressXZ; - ++nCompress; - } else if (compressionMethodStr == "zstd") { - compress = cmSystemTools::TarCompressZstd; - ++nCompress; - } else if (compressionMethodStr == "ppmd") { - compress = cmSystemTools::TarCompressPPMd; - ++nCompress; - } else { - cmSystemTools::Error( - cmStrCat("Unknown --cmake-tar-compression-method value: '", - compressionMethodStr, '\'')); - return 1; - } - } else if (cmHasLiteralPrefix(arg, "--files-from=")) { - std::string const& files_from = arg.substr(13); - if (!cmTarFilesFrom(files_from, files)) { - return 1; - } - } else if (cmHasLiteralPrefix(arg, "--format=")) { - format = arg.substr(9); - if (!cm::contains(knownFormats, format)) { - cmSystemTools::Error("Unknown -E tar --format= argument: " + - format); - return 1; - } - } else if (arg == "--touch") { - extractTimestamps = cmSystemTools::cmTarExtractTimestamps::No; - } else { - cmSystemTools::Error("Unknown option to -E tar: " + arg); - return 1; - } - } else { - files.push_back(arg); - } - } - cmSystemTools::cmTarAction action = cmSystemTools::TarActionNone; - bool verbose = false; - - for (auto flag : flags) { - switch (flag) { - case '-': - case 'f': { - // Keep for backward compatibility. Ignored - } break; - case 'j': { - compress = cmSystemTools::TarCompressBZip2; - ++nCompress; - } break; - case 'J': { - compress = cmSystemTools::TarCompressXZ; - ++nCompress; - } break; - case 'z': { - compress = cmSystemTools::TarCompressGZip; - ++nCompress; - } break; - case 'v': { - verbose = true; - } break; - case 't': { - action = cmSystemTools::TarActionList; - } break; - case 'c': { - action = cmSystemTools::TarActionCreate; - } break; - case 'x': { - action = cmSystemTools::TarActionExtract; - } break; - default: { - std::cerr << "tar: Unknown argument: " << flag << '\n'; - } - } - } - if (nCompress > 1) { - cmSystemTools::Error("Can only compress a tar file one way; " - "at most one flag of z, j, or J may be used"); - return 1; - } - if (compressionLevelFlagPassed) { - if (nCompress == 0 && format != "zip" && format != "7zip") { - cmSystemTools::Error("Can not use --cmake-tar-compression-level " - "without compression algorithm selection"); - return 1; - } - - constexpr int minCompressionLevel = 0; - int maxCompressionLevel = 9; - if (compress == cmSystemTools::TarCompressZstd && format != "zip") { - maxCompressionLevel = 19; - } - - if (compressionLevel < minCompressionLevel || - compressionLevel > maxCompressionLevel) { - cmSystemTools::Error(cmStrCat( - "Compression level must be between ", minCompressionLevel, " and ", - maxCompressionLevel, ". Got ", compressionLevel)); - return 1; - } - } - - if (action == cmSystemTools::TarActionList) { - if (!cmSystemTools::ListTar(outFile, files, {}, encoding, verbose)) { - cmSystemTools::Error("Problem listing tar: " + outFile); - return 1; - } - } else if (action == cmSystemTools::TarActionCreate) { - if (files.empty()) { - std::cerr << "tar: No files or directories specified\n"; - } - if (!cmSystemTools::CreateTar(outFile, files, {}, {}, compress, - encoding, verbose, mtime, format, - compressionLevel, numThreads)) { - cmSystemTools::Error(cmStrCat("Problem creating tar:\n ", outFile)); - return 1; - } - } else if (action == cmSystemTools::TarActionExtract) { - if (!cmSystemTools::ExtractTar(outFile, files, {}, extractTimestamps, - encoding, verbose)) { - cmSystemTools::Error( - cmStrCat("Problem extracting tar:\n ", outFile)); - return 1; - } -#ifdef _WIN32 - // OK, on windows 7 after we untar some files, - // sometimes we can not rename the directory after - // the untar is done. This breaks the external project - // untar and rename code. So, by default we will wait - // 1/10th of a second after the untar. If CMAKE_UNTAR_DELAY - // is set in the env, its value will be used instead of 100. - int delay = 100; - std::string delayVar; - if (cmSystemTools::GetEnv("CMAKE_UNTAR_DELAY", delayVar)) { - delay = atoi(delayVar.c_str()); - } - if (delay) { - cmSystemTools::Delay(delay); - } -#endif - } else { - cmSystemTools::Error("tar: No action specified. Please choose: 't' " - "(list), 'c' (create) or 'x' (extract)"); - return 1; - } - return 0; - } - - // bin2c - if (args[1] == "bin2c"_s) { - auto const usage = []() { - std::cerr << "bin2c Usage: -E bin2c " - "[<options>...] " - "[--] [<input-file> [<output-file>]]\n"; - return 1; - }; - auto const isFilename = [](std::string const& arg) -> bool { - return arg == "-"_s || !cmHasPrefix(arg, '-'); - }; - - static char const validPlaceholderChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789/_.+-"; - - std::string inputFile = "-"; - std::string outputFile = "-"; - cm::optional<cm::string_view> templateFilename; - cm::optional<cm::string_view> templateArrayPlaceholder; - cm::optional<cm::string_view> templateLengthPlaceholder; - bool printTrailingComma = false; - bool printSigned = false; - auto base = Bin2CBase::Hex; - - using CommandArgument = - cmCommandLineArgument<bool(std::string const& value)>; - std::vector<CommandArgument> arguments = { - CommandArgument{ "--template-file", CommandArgument::Values::One, - [&templateFilename](std::string const& arg) -> bool { - templateFilename = arg; - return true; - } }, - CommandArgument{ - "--template-array-placeholder", CommandArgument::Values::One, - [&templateArrayPlaceholder](std::string const& arg) -> bool { - if (arg.find_first_not_of(validPlaceholderChars) != - std::string::npos) { - std::cerr << "Invalid array placeholder name: \"" << arg - << "\"\n"; - return false; - } - templateArrayPlaceholder = arg; - return true; - } }, - CommandArgument{ - "--template-length-placeholder", CommandArgument::Values::One, - [&templateLengthPlaceholder](std::string const& arg) -> bool { - if (arg.find_first_not_of(validPlaceholderChars) != - std::string::npos) { - std::cerr << "Invalid length placeholder name: \"" << arg - << "\"\n"; - return false; - } - templateLengthPlaceholder = arg; - return true; - } }, - CommandArgument{ "--trailing-comma", CommandArgument::Values::Zero, - CommandArgument::setToTrue(printTrailingComma) }, - CommandArgument{ "--signed", CommandArgument::Values::Zero, - CommandArgument::setToTrue(printSigned) }, - CommandArgument{ "--decimal", CommandArgument::Values::Zero, - [&base](std::string const&) -> bool { - base = Bin2CBase::Decimal; - return true; - } }, - }; - - size_t i; - for (i = 2; i < args.size(); i++) { - bool matched = false; - auto const& arg = args[i]; - if (arg == "--"_s) { - i++; - break; - } - for (auto const& argument : arguments) { - if (argument.matches(arg)) { - matched = true; - if (!argument.parse(arg, i, args)) { - std::cerr << "\n"; - return usage(); - } - break; - } - } - - if (isFilename(arg)) { - break; - } - if (!matched) { - return usage(); - } - } - - if (i < args.size() - 2) { - return usage(); - } - if (i < args.size()) { - if (!isFilename(args[i])) { - return usage(); - } - inputFile = args[i]; - i++; - } - if (i < args.size()) { - if (!isFilename(args[i])) { - return usage(); - } - outputFile = args[i]; - i++; - } - - cm::optional<Bin2CTemplateFile> templateFile; - cmsys::ifstream templateStream; - if (templateFilename) { - templateStream.open(templateFilename->data()); - if (!templateStream) { - std::cerr << "Could not open template file for reading: \"" - << *templateFilename << "\"\n"; - return 1; - } - templateFile = - Bin2CTemplateFile{ &templateStream, - templateArrayPlaceholder.value_or("array"_s), - templateLengthPlaceholder.value_or("length"_s) }; - } else { - if (templateArrayPlaceholder) { - std::cerr << "Cannot use --template-array-placeholder without " - "--template-file\n\n"; - return usage(); - } - if (templateLengthPlaceholder) { - std::cerr << "Cannot use --template-length-placeholder without " - "--template-file\n\n"; - return usage(); - } - } - - std::istream* sin = &std::cin; - cmsys::ifstream fin; - if (inputFile != "-"_s) { - fin.open(inputFile.c_str(), std::ios::in | std::ios::binary); - if (!fin) { - std::cerr << "Could not open file for reading: \"" << inputFile - << "\"\n"; - return 1; - } - sin = &fin; -#ifdef _WIN32 - } else { - _setmode(fileno(stdin), _O_BINARY); -#endif - } - - std::ostream* sout = &std::cout; - cmGeneratedFileStream fout; - if (outputFile != "-"_s) { - fout.Open(outputFile); - if (!fout) { - std::cerr << "Could not open file for writing: \"" << outputFile - << "\"\n"; - return 1; - } - fout.SetCopyIfDifferent(true); - sout = &fout; - } - - if (!Bin2C(*sout, *sin, templateFile, printTrailingComma, printSigned, - base)) { - return 1; - } - - return 0; - } - - if (args[1] == "server") { - cmSystemTools::Error( - "CMake server mode has been removed in favor of the file-api."); - return 1; - } - -#if !defined(CMAKE_BOOTSTRAP) - // Internal CMake Fortran module support. - if (args[1] == "cmake_copy_f90_mod" && args.size() >= 4) { - return cmDependsFortran::CopyModule(args) ? 0 : 1; - } -#endif - -#if defined(_WIN32) && !defined(__CYGWIN__) - // Write registry value - if (args[1] == "write_regv" && args.size() > 3) { - return cmSystemTools::WriteRegistryValue(args[2], args[3]) ? 0 : 1; - } - - // Delete registry value - if (args[1] == "delete_regv" && args.size() > 2) { - return cmSystemTools::DeleteRegistryValue(args[2]) ? 0 : 1; - } - - // Remove file - if (args[1] == "comspec" && args.size() > 2) { - std::cerr << "Win9x helper \"cmake -E comspec\" no longer supported\n"; - return 1; - } - - if (args[1] == "env_vs8_wince" && args.size() == 3) { - return cmcmd::WindowsCEEnvironment("8.0", args[2]); - } - - if (args[1] == "env_vs9_wince" && args.size() == 3) { - return cmcmd::WindowsCEEnvironment("9.0", args[2]); - } -#endif - - // Internal depfile transformation - if (args[1] == "cmake_transform_depfile" && args.size() == 10) { - auto format = cmDepfileFormat::GccDepfile; - if (args[3] == "gccdepfile") { - format = cmDepfileFormat::GccDepfile; - } else if (args[3] == "makedepfile") { - format = cmDepfileFormat::MakeDepfile; - } else if (args[3] == "MSBuildAdditionalInputs") { - format = cmDepfileFormat::MSBuildAdditionalInputs; - } else { - return 1; - } - // Create a cmake object instance to process dependencies. - // All we need is the `set` command. - cmake cm(cmState::Role::Script); - std::string homeDir; - std::string startDir; - std::string homeOutDir; - std::string startOutDir; - homeDir = cmSystemTools::ToNormalizedPathOnDisk(args[4]); - startDir = cmSystemTools::ToNormalizedPathOnDisk(args[5]); - homeOutDir = cmSystemTools::ToNormalizedPathOnDisk(args[6]); - startOutDir = cmSystemTools::ToNormalizedPathOnDisk(args[7]); - cm.SetHomeDirectory(homeDir); - cm.SetHomeOutputDirectory(homeOutDir); - cm.GetCurrentSnapshot().SetDefaultDefinitions(); - if (auto ggd = cm.CreateGlobalGenerator(args[2])) { - cm.SetGlobalGenerator(std::move(ggd)); - cmStateSnapshot snapshot = cm.GetCurrentSnapshot(); - snapshot.GetDirectory().SetCurrentBinary(startOutDir); - snapshot.GetDirectory().SetCurrentSource(startDir); - cmMakefile mf(cm.GetGlobalGenerator(), snapshot); - auto lgd = cm.GetGlobalGenerator()->CreateLocalGenerator(&mf); - - // FIXME: With advanced add_subdirectory usage, these are - // not necessarily the same as the generator originally used. - // We should pass all these directories through an info file. - lgd->SetRelativePathTop(homeDir, homeOutDir); - - return cmTransformDepfile(format, *lgd, args[8], args[9]) ? 0 : 2; - } - return 1; - } - - std::vector<std::string> availableCommands = - CommandLineHelpEntryNames(AvailableCommands); -#if defined(_WIN32) && !defined(__CYGWIN__) - cm::append(availableCommands, - CommandLineHelpEntryNames(AvailableWindowsCommands)); -#endif - // Some commands above only fall through to here when they were - // matched by name but had the wrong number/form of arguments; only - // offer a suggestion when the name itself is not recognized. - if (std::find(availableCommands.begin(), availableCommands.end(), - args[1]) == availableCommands.end()) { - std::string error = cmStrCat("Unknown command \"", args[1], "\"."); - std::string const suggestion = - cmFindClosestString(args[1], availableCommands); - if (!suggestion.empty()) { - error = - cmStrCat(std::move(error), " Did you mean \"", suggestion, "\"?"); - } - cmSystemTools::Error(error); + if (!matched) { + files.push_back(arg); } } - CMakeCommandUsage(args[0]); + // If multiple source files specified, + // then destination must be directory + if (files.size() > 2 && !targetArg) { + targetArg = files.back(); + files.pop_back(); + } + if (targetArg && (!cmSystemTools::FileIsDirectory(*targetArg))) { + std::cerr << "Error: Target (for " << cmdName << " command) \"" + << *targetArg << "\" is not a directory.\n"; + return 1; + } + if (!targetArg) { + if (files.size() < 2) { + std::cerr << "Error: No files or target specified (for " << cmdName + << " command).\n"; + return 1; + } + targetArg = files.back(); + files.pop_back(); + } + // If error occurs we want to continue copying next files. + bool return_value = false; + for (auto const& file : files) { + cmsys::SystemTools::CopyStatus const status = copyFn(file, *targetArg); + if (!status) { + std::cerr << copyErrPrefix << " \"" << file << "\" to \"" << *targetArg + << "\": " << status.GetString() << '\n'; + return_value = true; + } + } + return return_value; +} +Command constexpr cmake_E_copy{ + "copy"_s, + "<file>... destination | -t <destination> <file>..."_s, + "copy files to destination (either file or directory)"_s, + _cmake_E_copy, + Group::Common, +}; +Command constexpr cmake_E_copy_if_different{ + "copy_if_different"_s, + "<file>... destination | -t <destination> <file>..."_s, + "copy files if source has changed"_s, + _cmake_E_copy, + Group::Common, +}; +Command constexpr cmake_E_copy_if_newer{ + "copy_if_newer"_s, + "<file>... destination | -t <destination> <file>..."_s, + "copy files if source is newer than destination"_s, + _cmake_E_copy, + Group::Common, +}; + +// Copy directory contents +int _cmake_E_copy_directory(Command::Arguments args) +{ + cmsys::SystemTools::CopyWhen when = + cmsys::SystemTools::CopyWhen::Unconditional; + if (args[1] == "copy_directory_if_different") { + when = cmsys::SystemTools::CopyWhen::OnlyIfDifferent; + } else if (args[1] == "copy_directory_if_newer") { + when = cmsys::SystemTools::CopyWhen::OnlyIfNewer; + } + std::string const& cmdName = args[1]; + + using CommandArgument = + cmCommandLineArgument<bool(std::string const& value)>; + + cm::optional<std::string> targetArg; + std::vector<CommandArgument> argParsers{ + { "-t", CommandArgument::Values::One, + CommandArgument::setToValue(targetArg) }, + }; + + std::vector<std::string> dirs; + for (decltype(args.size()) i = 2; i < args.size(); i++) { + std::string const& arg = args[i]; + bool matched = false; + for (auto const& m : argParsers) { + if (m.matches(arg)) { + matched = true; + if (m.parse(arg, i, args)) { + break; + } + return 1; // failed to parse + } + } + if (!matched) { + dirs.push_back(arg); + } + } + + if (!targetArg) { + if (dirs.size() < 2) { + std::cerr << "Error: No directories or target specified (for " << cmdName + << " command).\n"; + return 1; + } + targetArg = dirs.back(); + dirs.pop_back(); + } + if (dirs.empty()) { + std::cerr << "Error: No source directories specified (for " << cmdName + << " command).\n"; + return 1; + } + + // If error occurs we want to continue copying next files. + bool return_value = false; + for (auto const& dir : dirs) { + cmsys::Status const status = + cmSystemTools::CopyADirectory(dir, *targetArg, when); + if (!status) { + std::cerr << "Error copying directory from \"" << dir << "\" to \"" + << *targetArg << "\": " << status.GetString() << '\n'; + return_value = true; + } + } + return return_value; +} +Command constexpr cmake_E_copy_directory{ + "copy_directory"_s, + "<dir>... destination | -t <destination> <dir>..."_s, + "copy content of <dir>... directories to 'destination' directory"_s, + _cmake_E_copy_directory, + Group::Common, +}; +Command constexpr cmake_E_copy_directory_if_different{ + "copy_directory_if_different"_s, + "<dir>... destination | -t <destination> <dir>..."_s, + "copy changed content of <dir>... directories to 'destination' " + "directory"_s, + _cmake_E_copy_directory, + Group::Common, +}; +Command constexpr cmake_E_copy_directory_if_newer{ + "copy_directory_if_newer"_s, + "<dir>... destination | -t <destination> <dir>..."_s, + "copy newer content of <dir>... directories to 'destination' " + "directory"_s, + _cmake_E_copy_directory, + Group::Common, +}; + +// Rename a file or directory +int _cmake_E_rename(Command::Arguments args) +{ + if (args.size() != 4) { + return CMakeCommandUsage(args[0]); + } + if (!cmSystemTools::RenameFile(args[2], args[3])) { + std::string e = cmSystemTools::GetLastSystemError(); + std::cerr << "Error renaming from \"" << args[2] << "\" to \"" << args[3] + << "\": " << e << "\n"; + return 1; + } + return 0; +} +Command constexpr cmake_E_rename{ + "rename"_s, + "oldname newname"_s, + "rename a file or directory (on one volume)"_s, + _cmake_E_rename, + Group::Common, +}; + +// Compare files +int _cmake_E_compare_files(Command::Arguments args) +{ + if (args.size() != 4 && args.size() != 5) { + return CMakeCommandUsage(args[0]); + } + bool filesDiffer; + if (args.size() == 4) { + filesDiffer = cmSystemTools::FilesDiffer(args[2], args[3]); + } else if (args[2] == "--ignore-eol") { + filesDiffer = cmsys::SystemTools::TextFilesDiffer(args[3], args[4]); + } else { + CMakeCommandUsage(args[0]); + return 2; + } + + if (filesDiffer) { + return 1; + } + return 0; +} +Command constexpr cmake_E_compare_files{ + "compare_files"_s, + "[--ignore-eol] file1 file2"_s, + "check if file1 is same as file2"_s, + _cmake_E_compare_files, + Group::Common, +}; + +#if !defined(CMAKE_BOOTSTRAP) +// NOLINTNEXTLINE(bugprone-reserved-identifier) +int _cmake_E___create_def(Command::Arguments args) +{ + if (args.size() < 4) { + std::cerr << "__create_def Usage: -E __create_def outfile.def " + "objlistfile [--nm=nm-path]\n"; + return 1; + } + cmSystemTools::InitializeCMake(args[0].c_str()); + cmsys::ifstream fin(args[3].c_str(), std::ios::in | std::ios::binary); + if (!fin) { + std::cerr << "could not open object list file: " << args[3] << '\n'; + return 1; + } + std::vector<std::string> defFiles; + std::vector<std::string> objFiles; + { + std::string file; + cmFileTime outTime; + bool outValid = outTime.Load(args[2]); + while (cmSystemTools::GetLineFromStream(fin, file)) { + std::string const& ext = cmSystemTools::GetFilenameLastExtension(file); + if (cmSystemTools::LowerCase(ext) == ".def") { + defFiles.push_back(file); + } else { + objFiles.push_back(file); + } + if (outValid) { + cmFileTime inTime; + outValid = inTime.Load(file) && inTime.Older(outTime); + } + } + if (outValid) { + // The def file already exists and all input files are older than + // the existing def file. + return 0; + } + } + fin.close(); + cmsys::ofstream fout(args[2].c_str()); + if (!fout) { + std::cerr << "could not open output .def file: " << args[2] << '\n'; + return 1; + } + bindexplib deffile; + if (args.size() >= 5) { + std::string const& a = args[4]; + if (cmHasLiteralPrefix(a, "--nm=")) { + deffile.SetNmPath(a.substr(5)); + } else { + std::cerr << "unknown argument: " << a << '\n'; + } + } + if (!deffile.AddDefinitionFile(defFiles) || + !deffile.AddObjectFile(objFiles, cmStrCat(args[3], ".rsp"))) { + return 1; + } + if (!deffile.WriteFile(fout)) { + std::cerr << "could not write output .def file: " << args[2] << '\n'; + return 1; + } + return 0; +} +#else +// NOLINTNEXTLINE(bugprone-reserved-identifier) +std::nullptr_t constexpr _cmake_E___create_def = nullptr; +#endif +// NOLINTNEXTLINE(bugprone-reserved-identifier) +Command constexpr cmake_E___create_def{ + "__create_def"_s, ""_s, ""_s, _cmake_E___create_def, Group::Internal, +}; + +// NOLINTNEXTLINE(bugprone-reserved-identifier) +int _cmake_E___run_co_compile(Command::Arguments args) +{ + cmSystemTools::InitializeCMake(args[0].c_str()); + return HandleCoCompileCommands(args); +} +// NOLINTNEXTLINE(bugprone-reserved-identifier) +Command constexpr cmake_E___run_co_compile{ + "__run_co_compile"_s, ""_s, ""_s, _cmake_E___run_co_compile, Group::Internal, +}; + +// Echo string +int _cmake_E_echo(Command::Arguments args) +{ + std::cout << cmJoin(cmMakeRange(args).advance(2), " ") << std::endl; + return 0; +} +Command constexpr cmake_E_echo{ + "echo"_s, "[<string>...]"_s, "displays arguments as text"_s, + _cmake_E_echo, Group::Common, +}; + +// Echo string no new line +int _cmake_E_echo_append(Command::Arguments args) +{ + std::cout << cmJoin(cmMakeRange(args).advance(2), " "); + return 0; +} +Command constexpr cmake_E_echo_append{ + "echo_append"_s, + "[<string>...]"_s, + "displays arguments as text but no new line"_s, + _cmake_E_echo_append, + Group::Common, +}; + +int _cmake_E_env(Command::Arguments args) +{ + cmSystemTools::InitializeCMake(args[0].c_str()); +#ifndef CMAKE_BOOTSTRAP + auto envdiff = cmEnvironmentModification{}; +#endif + + auto ai = args.cbegin() + 2; + auto ae = args.cend(); + for (; ai != ae; ++ai) { + std::string const& a = *ai; + if (a == "--") { + // Stop parsing options/environment variables; the next argument + // should be the command. + ++ai; + break; + } + if (cmHasLiteralPrefix(a, "--unset=")) { + // Unset environment variable. +#ifdef CMAKE_BOOTSTRAP + cmSystemTools::UnPutEnv(a.substr(8)); +#else + envdiff.Add(a.substr(8) + "=unset:"); +#endif + } else if (a == "--modify") { +#ifdef CMAKE_BOOTSTRAP + std::cerr + << "cmake -E env: --modify not available during bootstrapping\n"; + return 1; +#else + if (++ai == ae) { + std::cerr << "cmake -E env: --modify missing a parameter\n"; + return 1; + } + std::string const& op = *ai; + if (!envdiff.Add(op)) { + std::cerr << "cmake -E env: invalid parameter to --modify: " << op + << '\n'; + return 1; + } +#endif + } else if (!a.empty() && a[0] == '-') { + // Environment variable and command names cannot start in '-', + // so this must be an unknown option. + std::cerr << "cmake -E env: unknown option '" << a << "'\n"; + return 1; + } else if (a.find('=') != std::string::npos) { + // Set environment variable. +#ifdef CMAKE_BOOTSTRAP + cmSystemTools::PutEnv(a); +#else + auto const pos = a.find('='); + std::string const& name = a.substr(0, pos); + std::string const& value = a.substr(pos + 1); + envdiff.Add(cmStrCat(name, "=set:", value)); +#endif + } else { + // This is the beginning of the command. + break; + } + } + + if (ai == ae) { + std::cerr << "cmake -E env: no command given\n"; + return 1; + } + + auto env = cmEnvironment{}; +#ifndef CMAKE_BOOTSTRAP + env.Update(cmSystemTools::GetEnvironmentVariables()); + envdiff.ApplyTo(env); +#endif + + // Execute command from remaining arguments. + std::vector<std::string> cmd(ai, ae); + int retval; + if (cmSystemTools::RunSingleCommand( + cmd, nullptr, nullptr, &retval, nullptr, + cmSystemTools::OUTPUT_PASSTHROUGH, cmDuration::zero(), + cmProcessOutput::Auto, env.GetVariables())) { + return retval; + } + return 1; +} +Command constexpr cmake_E_env{ + "env"_s, + "[--unset=NAME ...] [NAME=VALUE ...] [--] <command> [<arg>...]"_s, + "run command in a modified environment"_s, + _cmake_E_env, + Group::Common, +}; + +#if !defined(CMAKE_BOOTSTRAP) +int _cmake_E_environment(Command::Arguments) +{ + for (auto const& env : cmSystemTools::GetEnvironmentVariables()) { + std::cout << env << std::endl; + } + return 0; +} +#else +std::nullptr_t constexpr _cmake_E_environment = nullptr; +#endif +Command constexpr cmake_E_environment{ + "environment"_s, ""_s, "display the current environment"_s, + _cmake_E_environment, Group::Common, +}; + +int _cmake_E_make_directory(Command::Arguments args) +{ + if (args.size() <= 2) { + return CMakeCommandUsage(args[0]); + } + // If an error occurs, we want to continue making directories. + bool return_value = false; + for (auto const& arg : cmMakeRange(args).advance(2)) { + cmsys::Status const status = cmSystemTools::MakeDirectory(arg); + if (!status) { + std::cerr << "Error creating directory \"" << arg + << "\": " << status.GetString() << '\n'; + return_value = true; + } + } + return return_value; +} +Command constexpr cmake_E_make_directory{ + "make_directory"_s, + "<dir>..."_s, + "create parent and <dir> directories"_s, + _cmake_E_make_directory, + Group::Common, +}; + +int _cmake_E_remove_directory(Command::Arguments args) +{ + if (args.size() <= 2) { + return CMakeCommandUsage(args[0]); + } + + IssueDeprecation( + "The 'cmake -E remove_directory' command has been superseded. " + "Use 'cmake -E rm' instead."); + + // If an error occurs, we want to continue removing directories. + bool return_value = false; + for (auto const& arg : cmMakeRange(args).advance(2)) { + if (cmSystemTools::FileIsDirectory(arg)) { + if (!cmRemoveDirectory(arg)) { + return_value = true; + } + } + } + return return_value; +} +Command constexpr cmake_E_remove_directory{ + "remove_directory"_s, + "<dir>..."_s, + "remove directories and their contents (deprecated: use rm instead)"_s, + _cmake_E_remove_directory, + Group::Common, +}; + +// Remove file +int _cmake_E_remove(Command::Arguments args) +{ + if (args.size() <= 2) { + return CMakeCommandUsage(args[0]); + } + + IssueDeprecation("The 'cmake -E remove' command has been superseded. " + "Use 'cmake -E rm' instead."); + + bool force = false; + for (auto const& arg : cmMakeRange(args).advance(2)) { + if (arg == "\\-f" || arg == "-f") { + force = true; + } else { + // Complain if the file could not be removed, still exists, + // and the -f option was not given. + if (!cmSystemTools::RemoveFile(arg) && !force && + cmSystemTools::FileExists(arg)) { + return 1; + } + } + } + return 0; +} +Command constexpr cmake_E_remove{ + "remove"_s, + "[-f] <file>..."_s, + "remove the file(s), use -f to force it (deprecated: use rm instead)"_s, + _cmake_E_remove, + Group::Common, +}; + +// Remove directories or files with rm +int _cmake_E_rm(Command::Arguments args) +{ + if (args.size() <= 2) { + return CMakeCommandUsage(args[0]); + } + // If an error occurs, we want to continue removing the remaining + // files/directories. + int return_value = 0; + bool force = false; + bool recursive = false; + bool doing_options = true; + bool at_least_one_file = false; + for (auto const& arg : cmMakeRange(args).advance(2)) { + if (doing_options && cmHasPrefix(arg, '-')) { + if (arg == "--") { + doing_options = false; + } + if (arg.find('f') != std::string::npos) { + force = true; + } + if (arg.find_first_of("rR") != std::string::npos) { + recursive = true; + } + if (arg.find_first_not_of("-frR") != std::string::npos) { + cmSystemTools::Error("Unknown -E rm argument: " + arg); + return 1; + } + } else { + if (arg.empty()) { + continue; + } + at_least_one_file = true; + // Complain if the -f option was not given and + // either file does not exist or + // file could not be removed and still exists + bool file_exists_or_forced_remove = + cmSystemTools::PathExists(arg) || force; + if (cmSystemTools::FileIsDirectory(arg)) { + if (!cmRemoveDirectory(arg, recursive)) { + return_value = 1; + } + } else if ((!file_exists_or_forced_remove) || + (!cmSystemTools::RemoveFile(arg) && + cmSystemTools::FileExists(arg))) { + if (!file_exists_or_forced_remove) { + cmSystemTools::Error( + "File to remove does not exist and force is not set: " + arg); + } else { + cmSystemTools::Error("File can't be removed and still exists: " + + arg); + } + return_value = 1; + } + } + } + if (!at_least_one_file) { + cmSystemTools::Error("Missing file/directory to remove"); + return 1; + } + return return_value; +} +Command constexpr cmake_E_rm{ + "rm"_s, + "[-rRf] [--] <file/dir>..."_s, + "remove files or directories, use -f to force it, r or R to remove " + "directories and their contents recursively"_s, + _cmake_E_rm, + Group::Common, +}; + +// Touch file +int _cmake_E_touch(Command::Arguments args) +{ + if (args.size() <= 2) { + return CMakeCommandUsage(args[0]); + } + for (auto const& arg : cmMakeRange(args).advance(2)) { + if (!cmSystemTools::Touch(arg, true)) { + std::cerr << "cmake -E touch: failed to update \"" << arg << "\".\n"; + return 1; + } + } + return 0; +} +Command constexpr cmake_E_touch{ + "touch"_s, "<file>..."_s, "touch a <file>."_s, _cmake_E_touch, Group::Common, +}; + +// Touch file +int _cmake_E_touch_nocreate(Command::Arguments args) +{ + if (args.size() <= 2) { + return CMakeCommandUsage(args[0]); + } + for (auto const& arg : cmMakeRange(args).advance(2)) { + if (!cmSystemTools::Touch(arg, false)) { + std::cerr << "cmake -E touch_nocreate: failed to update \"" << arg + << "\".\n"; + return 1; + } + } + return 0; +} +Command constexpr cmake_E_touch_nocreate{ + "touch_nocreate"_s, + "<file>..."_s, + "touch a <file> but do not create it."_s, + _cmake_E_touch_nocreate, + Group::Common, +}; + +// capabilities +int _cmake_E_capabilities(Command::Arguments args) +{ + if (args.size() > 2) { + std::cerr << "-E capabilities accepts no additional arguments\n"; + return 1; + } + cmSystemTools::InitializeCMake(args[0].c_str()); + cmake cm(cmState::Role::Internal); + std::cout << cm.ReportCapabilities(); + return 0; +} +Command constexpr cmake_E_capabilities{ + "capabilities"_s, + ""_s, + "Report capabilities built into cmake in JSON format"_s, + _cmake_E_capabilities, + Group::Common, +}; + +// Sleep command +int _cmake_E_sleep(Command::Arguments args) +{ + if (args.size() <= 2) { + return CMakeCommandUsage(args[0]); + } + double total = 0; + for (auto const& arg : cmMakeRange(args).advance(2)) { + double num = 0.0; + char unit; + char extra; + int n = sscanf(arg.c_str(), "%lg%c%c", &num, &unit, &extra); + if ((n == 1 || (n == 2 && unit == 's')) && num >= 0) { + total += num; + } else { + std::cerr << "Unknown sleep time format \"" << arg << "\".\n"; + return 1; + } + } + if (total > 0) { + cmSystemTools::Delay(static_cast<unsigned int>(total * 1000)); + } + return 0; +} +Command constexpr cmake_E_sleep{ + "sleep"_s, "<number>..."_s, "sleep for given number of seconds"_s, + _cmake_E_sleep, Group::Common, +}; + +// Clock command +int _cmake_E_time(Command::Arguments args) +{ + if (args.size() <= 2) { + return CMakeCommandUsage(args[0]); + } + cmSystemTools::InitializeCMake(args[0].c_str()); + std::vector<std::string> command(args.begin() + 2, args.end()); + + int ret = 0; + auto time_start = std::chrono::steady_clock::now(); + cmSystemTools::RunSingleCommand(command, nullptr, nullptr, &ret, nullptr, + cmSystemTools::OUTPUT_PASSTHROUGH); + auto time_finish = std::chrono::steady_clock::now(); + + std::chrono::duration<double> time_elapsed = time_finish - time_start; + std::cout << "Elapsed time (seconds): " << time_elapsed.count() << '\n'; + return ret; +} +Command constexpr cmake_E_time{ + "time"_s, + "command [args...]"_s, + "run command and display elapsed time"_s, + _cmake_E_time, + Group::Common, +}; + +// Command to calculate the md5sum of a file +int _cmake_E_md5sum(Command::Arguments args) +{ + if (args.size() < 3) { + return CMakeCommandUsage(args[0]); + } + return HashSumFile(args, cmCryptoHash::AlgoMD5); +} +Command constexpr cmake_E_md5sum{ + "md5sum"_s, "<file>..."_s, "create MD5 checksum of files"_s, + _cmake_E_md5sum, Group::Common, +}; + +// Command to calculate the sha1sum of a file +int _cmake_E_sha1sum(Command::Arguments args) +{ + if (args.size() < 3) { + return CMakeCommandUsage(args[0]); + } + return HashSumFile(args, cmCryptoHash::AlgoSHA1); +} +Command constexpr cmake_E_sha1sum{ + "sha1sum"_s, "<file>..."_s, "create SHA1 checksum of files"_s, + _cmake_E_sha1sum, Group::Common, +}; + +int _cmake_E_sha224sum(Command::Arguments args) +{ + if (args.size() < 3) { + return CMakeCommandUsage(args[0]); + } + return HashSumFile(args, cmCryptoHash::AlgoSHA224); +} +Command constexpr cmake_E_sha224sum{ + "sha224sum"_s, "<file>..."_s, "create SHA224 checksum of files"_s, + _cmake_E_sha224sum, Group::Common, +}; + +int _cmake_E_sha256sum(Command::Arguments args) +{ + if (args.size() < 3) { + return CMakeCommandUsage(args[0]); + } + return HashSumFile(args, cmCryptoHash::AlgoSHA256); +} +Command constexpr cmake_E_sha256sum{ + "sha256sum"_s, "<file>..."_s, "create SHA256 checksum of files"_s, + _cmake_E_sha256sum, Group::Common, +}; + +int _cmake_E_sha384sum(Command::Arguments args) +{ + if (args.size() < 3) { + return CMakeCommandUsage(args[0]); + } + return HashSumFile(args, cmCryptoHash::AlgoSHA384); +} +Command constexpr cmake_E_sha384sum{ + "sha384sum"_s, "<file>..."_s, "create SHA384 checksum of files"_s, + _cmake_E_sha384sum, Group::Common, +}; + +int _cmake_E_sha512sum(Command::Arguments args) +{ + if (args.size() < 3) { + return CMakeCommandUsage(args[0]); + } + return HashSumFile(args, cmCryptoHash::AlgoSHA512); +} +Command constexpr cmake_E_sha512sum{ + "sha512sum"_s, "<file>..."_s, "create SHA512 checksum of files"_s, + _cmake_E_sha512sum, Group::Common, +}; + +// Command to concat files into one +int _cmake_E_cat(Command::Arguments args) +{ + if (args.size() == 2) { + // Destroy console buffers to drop cout/cerr encoding transform. + args.Console.reset(); + cmCatFile(cm::nullopt); + return 0; + } + int return_value = 0; + bool doing_options = true; + for (auto const& arg : cmMakeRange(args).advance(2)) { + if (arg == "-") { + doing_options = false; + // Destroy console buffers to drop cout/cerr encoding transform. + args.Console.reset(); + cmCatFile(cm::nullopt); + } else if (doing_options && cmHasPrefix(arg, '-')) { + if (arg == "--") { + doing_options = false; + } else { + cmSystemTools::Error(arg + ": option not handled"); + return_value = 1; + } + } else if (!cmSystemTools::TestFileAccess(arg, cmsys::TEST_FILE_READ) && + cmSystemTools::TestFileAccess(arg, cmsys::TEST_FILE_OK)) { + cmSystemTools::Error(arg + ": permission denied (ignoring)"); + return_value = 1; + } else if (cmSystemTools::FileIsDirectory(arg)) { + cmSystemTools::Error(arg + ": is a directory (ignoring)"); + return_value = 1; + } else if (!cmSystemTools::FileExists(arg)) { + cmSystemTools::Error(arg + ": no such file or directory (ignoring)"); + return_value = 1; + } else if (cmSystemTools::FileLength(arg) == 0) { + // Ignore empty files, this is not an error + } else { + // Destroy console buffers to drop cout/cerr encoding transform. + args.Console.reset(); + cmCatFile(arg); + } + } + return return_value; +} +Command constexpr cmake_E_cat{ + "cat"_s, + "[--] <files>..."_s, + "concat the files and print them to the standard output"_s, + _cmake_E_cat, + Group::Common, +}; + +// Command to change directory and run a program. +int _cmake_E_chdir(Command::Arguments args) +{ + if (args.size() < 4) { + return CMakeCommandUsage(args[0]); + } + cmSystemTools::InitializeCMake(args[0].c_str()); + std::string const& directory = args[2]; + if (!cmSystemTools::FileExists(directory)) { + cmSystemTools::Error("Directory does not exist for chdir command: " + + directory); + return 1; + } + + std::string command = cmWrap('"', cmMakeRange(args).advance(3), '"', " "); + int retval = 0; + if (cmSystemTools::RunSingleCommand( + command, nullptr, nullptr, &retval, directory.c_str(), + cmSystemTools::OUTPUT_PASSTHROUGH, cmDuration::zero())) { + return retval; + } + + return 1; +} +Command constexpr cmake_E_chdir{ + "chdir"_s, "dir cmd [args...]"_s, "run command in a given directory"_s, + _cmake_E_chdir, Group::Common, +}; + +// Command to start progress for a build +int _cmake_E_cmake_progress_start(Command::Arguments args) +{ + if (args.size() != 4) { + return CMakeCommandUsage(args[0]); + } + // basically remove the directory + std::string dirName = cmStrCat(args[2], "/Progress"); + cmSystemTools::RemoveADirectory(dirName); + + // is the last argument a filename that exists? + FILE* countFile = cmsys::SystemTools::Fopen(args[3], "r"); + int count; + if (countFile) { + if (1 != fscanf(countFile, "%i", &count)) { + std::cerr << "Could not read from count file.\n"; + } + fclose(countFile); + } else { + count = atoi(args[3].c_str()); + } + if (count) { + cmSystemTools::MakeDirectory(dirName); + // write the count into the directory + std::string fName = cmStrCat(dirName, "/count.txt"); + FILE* progFile = cmsys::SystemTools::Fopen(fName, "w"); + if (progFile) { + fprintf(progFile, "%i\n", count); + fclose(progFile); + } + } + return 0; +} +Command constexpr cmake_E_cmake_progress_start{ + "cmake_progress_start"_s, ""_s, ""_s, _cmake_E_cmake_progress_start, + Group::Internal, +}; + +// Command to report progress for a build +int _cmake_E_cmake_progress_report(Command::Arguments args) +{ + if (args.size() < 3) { + return CMakeCommandUsage(args[0]); + } + // This has been superseded by cmake_echo_color --progress-* + // options. We leave it here to avoid errors if somehow this + // is invoked by an existing makefile without regenerating. + return 0; +} +Command constexpr cmake_E_cmake_progress_report{ + "cmake_progress_report"_s, ""_s, ""_s, _cmake_E_cmake_progress_report, + Group::Internal, +}; + +// Command to create a symbolic link. Fails on platforms not +// supporting them. +int _cmake_E_create_symlink(Command::Arguments args) +{ + if (args.size() != 4) { + return CMakeCommandUsage(args[0]); + } + cmSystemTools::InitializeCMake(args[0].c_str()); + std::string const& destinationFileName = args[3]; + if (cmSystemTools::PathExists(destinationFileName) && + !cmSystemTools::RemoveFile(destinationFileName)) { + std::string emsg = cmSystemTools::GetLastSystemError(); + std::cerr << "failed to create symbolic link '" << destinationFileName + << "' because existing path cannot be removed: " << emsg << '\n'; + return 1; + } + if (!cmSystemTools::CreateSymlink(args[2], destinationFileName)) { + return 1; + } + return 0; +} +Command constexpr cmake_E_create_symlink{ + "create_symlink"_s, + "old new"_s, + "create a symbolic link new -> old"_s, + _cmake_E_create_symlink, + Group::Common, +}; + +// Command to create a hard link. Fails on platforms not +// supporting them. +int _cmake_E_create_hardlink(Command::Arguments args) +{ + if (args.size() != 4) { + return CMakeCommandUsage(args[0]); + } + cmSystemTools::InitializeCMake(args[0].c_str()); + std::string const& sourceFileName = args[2]; + std::string const& destinationFileName = args[3]; + + if (!cmSystemTools::FileExists(sourceFileName)) { + std::cerr << "failed to create hard link because source path '" + << sourceFileName << "' does not exist\n"; + return 1; + } + + if (cmSystemTools::PathExists(destinationFileName) && + !cmSystemTools::RemoveFile(destinationFileName)) { + std::string emsg = cmSystemTools::GetLastSystemError(); + std::cerr << "failed to create hard link '" << destinationFileName + << "' because existing path cannot be removed: " << emsg << '\n'; + return 1; + } + + if (!cmSystemTools::CreateLink(sourceFileName, destinationFileName)) { + return 1; + } + return 0; +} +Command constexpr cmake_E_create_hardlink{ + "create_hardlink"_s, "old new"_s, "create a hard link new -> old"_s, + _cmake_E_create_hardlink, Group::Common, +}; + +// Command to do nothing with an exit code of 0. +int _cmake_E_true(Command::Arguments) +{ + return 0; +} +Command constexpr cmake_E_true{ + "true"_s, ""_s, "do nothing with an exit code of 0"_s, + _cmake_E_true, Group::Common, +}; + +// Command to do nothing with an exit code of 1. +int _cmake_E_false(Command::Arguments) +{ + return 1; +} +Command constexpr cmake_E_false{ + "false"_s, ""_s, "do nothing with an exit code of 1"_s, + _cmake_E_false, Group::Common, +}; + +// Internal CMake shared library support. +int _cmake_E_cmake_symlink_library(Command::Arguments args) +{ + if (args.size() != 5) { + return CMakeCommandUsage(args[0]); + } + cmSystemTools::InitializeCMake(args[0].c_str()); + return SymlinkLibrary(args); +} +Command constexpr cmake_E_cmake_symlink_library{ + "cmake_symlink_library"_s, ""_s, ""_s, _cmake_E_cmake_symlink_library, + Group::Internal, +}; + +// Internal CMake versioned executable support. +int _cmake_E_cmake_symlink_executable(Command::Arguments args) +{ + if (args.size() != 4) { + return CMakeCommandUsage(args[0]); + } + cmSystemTools::InitializeCMake(args[0].c_str()); + return SymlinkExecutable(args); +} +Command constexpr cmake_E_cmake_symlink_executable{ + "cmake_symlink_executable"_s, + ""_s, + ""_s, + _cmake_E_cmake_symlink_executable, + Group::Internal, +}; + +// Internal CMake dependency scanning support. +// The format is: -E cmake_fastbuild_check_depends <dummy_file> +// <space_separated_list_of_real_outputs> +int _cmake_E_cmake_fastbuild_check_depends(Command::Arguments args) +{ + if (args.size() < 3) { + return CMakeCommandUsage(args[0]); + } + cmSystemTools::InitializeCMake(args[0].c_str()); + auto const dummyFile = args[2]; + for (auto const& arg : cmMakeRange(args).advance(3)) { + if (!cmSystemTools::FileExists(arg)) { + cmSystemTools::RemoveFile(dummyFile); + return 0; + } + } + return 0; +} +Command constexpr cmake_E_cmake_fastbuild_check_depends{ + "cmake_fastbuild_check_depends"_s, + ""_s, + ""_s, + _cmake_E_cmake_fastbuild_check_depends, + Group::Internal, +}; + +int _cmake_E_cmake_depends(Command::Arguments args) +{ + if (args.size() < 6) { + return CMakeCommandUsage(args[0]); + } + cmSystemTools::InitializeCMake(args[0].c_str()); + bool const verbose = isCMakeVerbose(); + + // Create a cmake object instance to process dependencies. + // All we need is the `set` command. + cmake cm(cmState::Role::Script); + std::string gen; + std::string homeDir; + std::string startDir; + std::string homeOutDir; + std::string startOutDir; + std::string depInfo; + std::string targetName; + bool color = false; + if (args.size() >= 8) { + // Full signature: + // + // -E cmake_depends <generator> + // <home-src-dir> <start-src-dir> + // <home-out-dir> <start-out-dir> + // <dep-info> [--color=$(COLOR)] + // <target-name> + // + // All paths are provided. + gen = args[2]; + homeDir = args[3]; + startDir = args[4]; + homeOutDir = args[5]; + startOutDir = args[6]; + depInfo = args[7]; + size_t targetNameIdx = 8; + if (args.size() >= 9 && cmHasLiteralPrefix(args[8], "--color=")) { + // Enable or disable color based on the switch value. + targetNameIdx = 9; + color = (args[8].size() == 8 || cmIsOn(args[8].substr(8))); + } + if (args.size() > targetNameIdx) { + targetName = args[targetNameIdx]; + } else { + std::string targetDir = cmSystemTools::GetFilenamePath(depInfo); + targetDir = cmSystemTools::GetFilenameName(targetDir); + targetName = targetDir.substr(0, targetDir.size() - 4); + } + } else { + // Support older signature for existing makefiles: + // + // -E cmake_depends <generator> + // <home-out-dir> <start-out-dir> + // <dep-info> + // + // Just pretend the source directories are the same as the + // binary directories so at least scanning will work. + gen = args[2]; + homeDir = args[3]; + startDir = args[4]; + homeOutDir = args[3]; + startOutDir = args[3]; + depInfo = args[5]; + // Strip the `.dir` suffix. Old CMake always uses this pattern. + std::string targetDir = cmSystemTools::GetFilenamePath(depInfo); + targetDir = cmSystemTools::GetFilenameName(targetDir); + targetName = targetDir.substr(0, targetDir.size() - 4); + } + + // Create a local generator configured for the directory in + // which dependencies will be scanned. + homeDir = cmSystemTools::ToNormalizedPathOnDisk(homeDir); + startDir = cmSystemTools::ToNormalizedPathOnDisk(startDir); + homeOutDir = cmSystemTools::ToNormalizedPathOnDisk(homeOutDir); + startOutDir = cmSystemTools::ToNormalizedPathOnDisk(startOutDir); + cm.SetHomeDirectory(homeDir); + cm.SetHomeOutputDirectory(homeOutDir); + cm.GetCurrentSnapshot().SetDefaultDefinitions(); + if (auto ggd = cm.CreateGlobalGenerator(gen)) { + cm.SetGlobalGenerator(std::move(ggd)); + cmStateSnapshot snapshot = cm.GetCurrentSnapshot(); + snapshot.GetDirectory().SetCurrentBinary(startOutDir); + snapshot.GetDirectory().SetCurrentSource(startDir); + cmMakefile mf(cm.GetGlobalGenerator(), snapshot); + auto lgd = cm.GetGlobalGenerator()->CreateLocalGenerator(&mf); + + // FIXME: With advanced add_subdirectory usage, these are + // not necessarily the same as the generator originally used. + // We should pass all these directories through an info file. + lgd->SetRelativePathTop(homeDir, homeOutDir); + + // Actually scan dependencies. + return lgd->UpdateDependencies(depInfo, targetName, verbose, color) ? 0 + : 2; + } + return 1; +} +Command constexpr cmake_E_cmake_depends{ + "cmake_depends"_s, ""_s, ""_s, _cmake_E_cmake_depends, Group::Internal, +}; + +#if !defined(CMAKE_BOOTSTRAP) || defined(CMAKE_BOOTSTRAP_MAKEFILES) +// Internal CMake compiler dependencies filtering +int _cmake_E_cmake_cl_compile_depends(Command::Arguments args) +{ + cmSystemTools::InitializeCMake(args[0].c_str()); + return CLCompileAndDependencies(args); +} +#else +std::nullptr_t constexpr _cmake_E_cmake_cl_compile_depends = nullptr; +#endif +Command constexpr cmake_E_cmake_cl_compile_depends{ + "cmake_cl_compile_depends"_s, + ""_s, + ""_s, + _cmake_E_cmake_cl_compile_depends, + Group::Internal, +}; + +// Internal CMake link script support. +int _cmake_E_cmake_link_script(Command::Arguments args) +{ + if (args.size() < 3) { + return CMakeCommandUsage(args[0]); + } + cmSystemTools::InitializeCMake(args[0].c_str()); + return ExecuteLinkScript(args); +} +Command constexpr cmake_E_cmake_link_script{ + "cmake_link_script"_s, ""_s, ""_s, _cmake_E_cmake_link_script, + Group::Internal, +}; + +#if !defined(CMAKE_BOOTSTRAP) +// Internal CMake ninja dependency scanning support. +int _cmake_E_cmake_ninja_depends(Command::Arguments args) +{ + cmSystemTools::InitializeCMake(args[0].c_str()); + return cmcmd_cmake_ninja_depends(args.begin() + 2, args.end()); +} + +// Internal CMake ninja dyndep support. +int _cmake_E_cmake_ninja_dyndep(Command::Arguments args) +{ + cmSystemTools::InitializeCMake(args[0].c_str()); + return cmcmd_cmake_ninja_dyndep(args.begin() + 2, args.end()); +} +#else +std::nullptr_t constexpr _cmake_E_cmake_ninja_depends = nullptr; +std::nullptr_t constexpr _cmake_E_cmake_ninja_dyndep = nullptr; +#endif +Command constexpr cmake_E_cmake_ninja_depends{ + "cmake_ninja_depends"_s, ""_s, ""_s, _cmake_E_cmake_ninja_depends, + Group::Internal, +}; +Command constexpr cmake_E_cmake_ninja_dyndep{ + "cmake_ninja_dyndep"_s, ""_s, ""_s, _cmake_E_cmake_ninja_dyndep, + Group::Internal, +}; + +// Internal CMake C++ module compilation database support. +int _cmake_E_cmake_module_compile_db(Command::Arguments args) +{ + cmSystemTools::InitializeCMake(args[0].c_str()); + return cmcmd_cmake_module_compile_db(args.begin() + 2, args.end()); +} +Command constexpr cmake_E_cmake_module_compile_db{ + "cmake_module_compile_db"_s, + ""_s, + ""_s, + _cmake_E_cmake_module_compile_db, + Group::Internal, +}; + +// Internal CMake unimplemented feature notification. +int _cmake_E_cmake_unimplemented_variable(Command::Arguments args) +{ + std::cerr << "Feature not implemented for this platform."; + if (args.size() == 3) { + std::cerr << " Variable " << args[2] << " is not set."; + } + std::cerr << '\n'; + return 1; +} +Command constexpr cmake_E_cmake_unimplemented_variable{ + "cmake_unimplemented_variable"_s, + ""_s, + ""_s, + _cmake_E_cmake_unimplemented_variable, + Group::Internal, +}; + +int _cmake_E_vs_link_exe(Command::Arguments args) +{ + cmSystemTools::InitializeCMake(args[0].c_str()); + return VisualStudioLink(args, 1, std::move(args.Console)); +} +Command constexpr cmake_E_vs_link_exe{ + "vs_link_exe"_s, ""_s, ""_s, _cmake_E_vs_link_exe, Group::Internal, +}; + +int _cmake_E_vs_link_dll(Command::Arguments args) +{ + cmSystemTools::InitializeCMake(args[0].c_str()); + return VisualStudioLink(args, 2, std::move(args.Console)); +} +Command constexpr cmake_E_vs_link_dll{ + "vs_link_dll"_s, ""_s, ""_s, _cmake_E_vs_link_dll, Group::Internal, +}; + +int _cmake_E_cmake_llvm_rc(Command::Arguments args) +{ + cmSystemTools::InitializeCMake(args[0].c_str()); + return RunLLVMRC(args); +} +Command constexpr cmake_E_cmake_llvm_rc{ + "cmake_llvm_rc"_s, ""_s, ""_s, _cmake_E_cmake_llvm_rc, Group::Internal, +}; + +// Internal CMake color makefile support. +int _cmake_E_cmake_echo_color(Command::Arguments args) +{ + return ExecuteEchoColor(args); +} +Command constexpr cmake_E_cmake_echo_color{ + "cmake_echo_color"_s, ""_s, ""_s, _cmake_E_cmake_echo_color, Group::Internal, +}; + +#ifndef CMAKE_BOOTSTRAP +int _cmake_E_cmake_autogen(Command::Arguments args) +{ + if (args.size() < 4) { + return CMakeCommandUsage(args[0]); + } + cmSystemTools::InitializeCMake(args[0].c_str()); + cm::string_view const infoFile = args[2]; + cm::string_view const config = args[3]; + cm::string_view const executableConfig = + (args.size() >= 5) ? cm::string_view(args[4]) : cm::string_view(); + return cmQtAutoMocUic(infoFile, config, executableConfig) ? 0 : 1; +} + +int _cmake_E_cmake_autorcc(Command::Arguments args) +{ + if (args.size() < 3) { + return CMakeCommandUsage(args[0]); + } + cmSystemTools::InitializeCMake(args[0].c_str()); + cm::string_view const infoFile = args[2]; + cm::string_view const config = + (args.size() > 3) ? cm::string_view(args[3]) : cm::string_view(); + cm::string_view const executableConfig = + (args.size() >= 5) ? cm::string_view(args[4]) : cm::string_view(); + return cmQtAutoRcc(infoFile, config, executableConfig) ? 0 : 1; +} +#else +std::nullptr_t constexpr _cmake_E_cmake_autogen = nullptr; +std::nullptr_t constexpr _cmake_E_cmake_autorcc = nullptr; +#endif +Command constexpr cmake_E_cmake_autogen{ + "cmake_autogen"_s, ""_s, ""_s, _cmake_E_cmake_autogen, Group::Internal, +}; +Command constexpr cmake_E_cmake_autorcc{ + "cmake_autorcc"_s, ""_s, ""_s, _cmake_E_cmake_autorcc, Group::Internal, +}; + +// Tar files +int _cmake_E_tar(Command::Arguments args) +{ + if (args.size() <= 3) { + return CMakeCommandUsage(args[0]); + } + cmSystemTools::InitializeCMake(args[0].c_str()); + char const* knownFormats[] = { + "7zip", "gnutar", "pax", "paxr", "raw", "zip" + }; + + std::string const& flags = args[2]; + std::string const& outFile = args[3]; + std::vector<std::string> files; + std::string mtime; + std::string format; + int numThreads = 1; + int compressionLevel = 0; + bool compressionLevelFlagPassed = false; + cmSystemTools::cmTarExtractTimestamps extractTimestamps = + cmSystemTools::cmTarExtractTimestamps::Yes; + cmSystemTools::cmTarCompression compress = cmSystemTools::TarCompressAuto; + int nCompress = 0; + bool doing_options = true; + std::string encoding = "UTF-8"; + for (auto const& arg : cmMakeRange(args).advance(4)) { + if (doing_options && cmHasLiteralPrefix(arg, "--")) { + if (arg == "--") { + doing_options = false; + } else if (arg == "--zstd") { + compress = cmSystemTools::TarCompressZstd; + ++nCompress; + } else if (arg == "--lzma") { + compress = cmSystemTools::TarCompressLZMA; + ++nCompress; + } else if (cmHasLiteralPrefix(arg, "--mtime=")) { + mtime = arg.substr(8); + } else if (cmHasLiteralPrefix(arg, "--cmake-tar-threads=")) { + std::string const& numThreadsStr = arg.substr(20); + long numThreadsLong = 0; + if (!cmStrToLong(numThreadsStr, &numThreadsLong)) { + cmSystemTools::Error(cmStrCat("Invalid --cmake-tar-threads value: '", + numThreadsStr, "' - not a number")); + return 1; + } + if (numThreadsLong > + std::numeric_limits<decltype(numThreads)>::max()) { + cmSystemTools::Error(cmStrCat("Invalid --cmake-tar-threads value: '", + numThreadsStr, "' - too large")); + return 1; + } + if (numThreadsLong < + std::numeric_limits<decltype(numThreads)>::min()) { + cmSystemTools::Error(cmStrCat("Invalid --cmake-tar-threads value: '", + numThreadsStr, "' - too small")); + return 1; + } + + numThreads = static_cast<decltype(numThreads)>(numThreadsLong); + } else if (cmHasLiteralPrefix(arg, "--cmake-tar-encoding=")) { + encoding = arg.substr(21); + if (encoding.empty()) { + cmSystemTools::Error( + "Encoding value is empty - it must be filled if passed"); + return 1; + } + } else if (cmHasLiteralPrefix(arg, "--cmake-tar-compression-level=")) { + std::string const& compressionLevelStr = arg.substr(30); + long compressionLevelLong = 0; + if (!cmStrToLong(compressionLevelStr, &compressionLevelLong)) { + cmSystemTools::Error( + cmStrCat("Invalid --cmake-tar-compression-level value: '", + compressionLevelStr, "' - not a number")); + return 1; + } + if (compressionLevelLong > + std::numeric_limits<decltype(compressionLevel)>::max()) { + cmSystemTools::Error( + cmStrCat("Invalid --cmake-tar-compression-level value: '", + compressionLevelStr, "' - too large")); + return 1; + } + if (compressionLevelLong < + std::numeric_limits<decltype(compressionLevel)>::min()) { + cmSystemTools::Error( + cmStrCat("Invalid --cmake-tar-compression-level value: '", + compressionLevelStr, "' - too small")); + return 1; + } + + compressionLevel = + static_cast<decltype(compressionLevel)>(compressionLevelLong); + compressionLevelFlagPassed = true; + } else if (cmHasLiteralPrefix(arg, "--cmake-tar-compression-method=")) { + std::string const& compressionMethodStr = arg.substr(31); + if (compressionMethodStr == "none" || + compressionMethodStr == "store") { + compress = cmSystemTools::TarCompressNone; + ++nCompress; + } else if (compressionMethodStr == "deflate" || + compressionMethodStr == "gzip") { + compress = cmSystemTools::TarCompressGZip; + ++nCompress; + } else if (compressionMethodStr == "bzip2") { + compress = cmSystemTools::TarCompressBZip2; + ++nCompress; + } else if (compressionMethodStr == "lzma") { + compress = cmSystemTools::TarCompressLZMA; + ++nCompress; + } else if (compressionMethodStr == "lzma2" || + compressionMethodStr == "xz") { + compress = cmSystemTools::TarCompressXZ; + ++nCompress; + } else if (compressionMethodStr == "zstd") { + compress = cmSystemTools::TarCompressZstd; + ++nCompress; + } else if (compressionMethodStr == "ppmd") { + compress = cmSystemTools::TarCompressPPMd; + ++nCompress; + } else { + cmSystemTools::Error( + cmStrCat("Unknown --cmake-tar-compression-method value: '", + compressionMethodStr, '\'')); + return 1; + } + } else if (cmHasLiteralPrefix(arg, "--files-from=")) { + std::string const& files_from = arg.substr(13); + if (!cmTarFilesFrom(files_from, files)) { + return 1; + } + } else if (cmHasLiteralPrefix(arg, "--format=")) { + format = arg.substr(9); + if (!cm::contains(knownFormats, format)) { + cmSystemTools::Error("Unknown -E tar --format= argument: " + format); + return 1; + } + } else if (arg == "--touch") { + extractTimestamps = cmSystemTools::cmTarExtractTimestamps::No; + } else { + cmSystemTools::Error("Unknown option to -E tar: " + arg); + return 1; + } + } else { + files.push_back(arg); + } + } + cmSystemTools::cmTarAction action = cmSystemTools::TarActionNone; + bool verbose = false; + + for (auto flag : flags) { + switch (flag) { + case '-': + case 'f': { + // Keep for backward compatibility. Ignored + } break; + case 'j': { + compress = cmSystemTools::TarCompressBZip2; + ++nCompress; + } break; + case 'J': { + compress = cmSystemTools::TarCompressXZ; + ++nCompress; + } break; + case 'z': { + compress = cmSystemTools::TarCompressGZip; + ++nCompress; + } break; + case 'v': { + verbose = true; + } break; + case 't': { + action = cmSystemTools::TarActionList; + } break; + case 'c': { + action = cmSystemTools::TarActionCreate; + } break; + case 'x': { + action = cmSystemTools::TarActionExtract; + } break; + default: { + std::cerr << "tar: Unknown argument: " << flag << '\n'; + } + } + } + if (nCompress > 1) { + cmSystemTools::Error("Can only compress a tar file one way; " + "at most one flag of z, j, or J may be used"); + return 1; + } + if (compressionLevelFlagPassed) { + if (nCompress == 0 && format != "zip" && format != "7zip") { + cmSystemTools::Error("Can not use --cmake-tar-compression-level " + "without compression algorithm selection"); + return 1; + } + + constexpr int minCompressionLevel = 0; + int maxCompressionLevel = 9; + if (compress == cmSystemTools::TarCompressZstd && format != "zip") { + maxCompressionLevel = 19; + } + + if (compressionLevel < minCompressionLevel || + compressionLevel > maxCompressionLevel) { + cmSystemTools::Error( + cmStrCat("Compression level must be between ", minCompressionLevel, + " and ", maxCompressionLevel, ". Got ", compressionLevel)); + return 1; + } + } + + if (action == cmSystemTools::TarActionList) { + if (!cmSystemTools::ListTar(outFile, files, {}, encoding, verbose)) { + cmSystemTools::Error("Problem listing tar: " + outFile); + return 1; + } + } else if (action == cmSystemTools::TarActionCreate) { + if (files.empty()) { + std::cerr << "tar: No files or directories specified\n"; + } + if (!cmSystemTools::CreateTar(outFile, files, {}, {}, compress, encoding, + verbose, mtime, format, compressionLevel, + numThreads)) { + cmSystemTools::Error(cmStrCat("Problem creating tar:\n ", outFile)); + return 1; + } + } else if (action == cmSystemTools::TarActionExtract) { + if (!cmSystemTools::ExtractTar(outFile, files, {}, extractTimestamps, + encoding, verbose)) { + cmSystemTools::Error(cmStrCat("Problem extracting tar:\n ", outFile)); + return 1; + } +#ifdef _WIN32 + // OK, on windows 7 after we untar some files, + // sometimes we can not rename the directory after + // the untar is done. This breaks the external project + // untar and rename code. So, by default we will wait + // 1/10th of a second after the untar. If CMAKE_UNTAR_DELAY + // is set in the env, its value will be used instead of 100. + int delay = 100; + std::string delayVar; + if (cmSystemTools::GetEnv("CMAKE_UNTAR_DELAY", delayVar)) { + delay = atoi(delayVar.c_str()); + } + if (delay) { + cmSystemTools::Delay(delay); + } +#endif + } else { + cmSystemTools::Error("tar: No action specified. Please choose: 't' " + "(list), 'c' (create) or 'x' (extract)"); + return 1; + } + return 0; +} +Command constexpr cmake_E_tar{ + "tar"_s, + "[cxt][vf][zjJ] file.tar [file/dir1 file/dir2 ...]"_s, + "create or extract a tar or zip archive"_s, + _cmake_E_tar, + Group::Common, +}; + +// bin2c +int _cmake_E_bin2c(Command::Arguments args) +{ + cmSystemTools::InitializeCMake(args[0].c_str()); + auto const usage = []() { + std::cerr << "bin2c Usage: -E bin2c " + "[<options>...] " + "[--] [<input-file> [<output-file>]]\n"; + return 1; + }; + auto const isFilename = [](std::string const& arg) -> bool { + return arg == "-"_s || !cmHasPrefix(arg, '-'); + }; + + static char const validPlaceholderChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789/_.+-"; + + std::string inputFile = "-"; + std::string outputFile = "-"; + cm::optional<cm::string_view> templateFilename; + cm::optional<cm::string_view> templateArrayPlaceholder; + cm::optional<cm::string_view> templateLengthPlaceholder; + bool printTrailingComma = false; + bool printSigned = false; + auto base = Bin2CBase::Hex; + + using CommandArgument = + cmCommandLineArgument<bool(std::string const& value)>; + std::vector<CommandArgument> arguments = { + CommandArgument{ "--template-file", CommandArgument::Values::One, + [&templateFilename](std::string const& arg) -> bool { + templateFilename = arg; + return true; + } }, + CommandArgument{ + "--template-array-placeholder", CommandArgument::Values::One, + [&templateArrayPlaceholder](std::string const& arg) -> bool { + if (arg.find_first_not_of(validPlaceholderChars) != + std::string::npos) { + std::cerr << "Invalid array placeholder name: \"" << arg << "\"\n"; + return false; + } + templateArrayPlaceholder = arg; + return true; + } }, + CommandArgument{ + "--template-length-placeholder", CommandArgument::Values::One, + [&templateLengthPlaceholder](std::string const& arg) -> bool { + if (arg.find_first_not_of(validPlaceholderChars) != + std::string::npos) { + std::cerr << "Invalid length placeholder name: \"" << arg << "\"\n"; + return false; + } + templateLengthPlaceholder = arg; + return true; + } }, + CommandArgument{ "--trailing-comma", CommandArgument::Values::Zero, + CommandArgument::setToTrue(printTrailingComma) }, + CommandArgument{ "--signed", CommandArgument::Values::Zero, + CommandArgument::setToTrue(printSigned) }, + CommandArgument{ "--decimal", CommandArgument::Values::Zero, + [&base](std::string const&) -> bool { + base = Bin2CBase::Decimal; + return true; + } }, + }; + + size_t i; + for (i = 2; i < args.size(); i++) { + bool matched = false; + auto const& arg = args[i]; + if (arg == "--"_s) { + i++; + break; + } + for (auto const& argument : arguments) { + if (argument.matches(arg)) { + matched = true; + if (!argument.parse(arg, i, args)) { + std::cerr << "\n"; + return usage(); + } + break; + } + } + + if (isFilename(arg)) { + break; + } + if (!matched) { + return usage(); + } + } + + if (i < args.size() - 2) { + return usage(); + } + if (i < args.size()) { + if (!isFilename(args[i])) { + return usage(); + } + inputFile = args[i]; + i++; + } + if (i < args.size()) { + if (!isFilename(args[i])) { + return usage(); + } + outputFile = args[i]; + i++; + } + + cm::optional<Bin2CTemplateFile> templateFile; + cmsys::ifstream templateStream; + if (templateFilename) { + templateStream.open(templateFilename->data()); + if (!templateStream) { + std::cerr << "Could not open template file for reading: \"" + << *templateFilename << "\"\n"; + return 1; + } + templateFile = + Bin2CTemplateFile{ &templateStream, + templateArrayPlaceholder.value_or("array"_s), + templateLengthPlaceholder.value_or("length"_s) }; + } else { + if (templateArrayPlaceholder) { + std::cerr << "Cannot use --template-array-placeholder without " + "--template-file\n\n"; + return usage(); + } + if (templateLengthPlaceholder) { + std::cerr << "Cannot use --template-length-placeholder without " + "--template-file\n\n"; + return usage(); + } + } + + std::istream* sin = &std::cin; + cmsys::ifstream fin; + if (inputFile != "-"_s) { + fin.open(inputFile.c_str(), std::ios::in | std::ios::binary); + if (!fin) { + std::cerr << "Could not open file for reading: \"" << inputFile + << "\"\n"; + return 1; + } + sin = &fin; +#ifdef _WIN32 + } else { + _setmode(fileno(stdin), _O_BINARY); +#endif + } + + std::ostream* sout = &std::cout; + cmGeneratedFileStream fout; + if (outputFile != "-"_s) { + fout.Open(outputFile); + if (!fout) { + std::cerr << "Could not open file for writing: \"" << outputFile + << "\"\n"; + return 1; + } + fout.SetCopyIfDifferent(true); + sout = &fout; + } + + if (!Bin2C(*sout, *sin, templateFile, printTrailingComma, printSigned, + base)) { + return 1; + } + + return 0; +} +Command constexpr cmake_E_bin2c{ + "bin2c"_s, ""_s, "Turn a binary file into a C array"_s, + _cmake_E_bin2c, Group::Common, +}; + +int _cmake_E_server(Command::Arguments) +{ + cmSystemTools::Error( + "CMake server mode has been removed in favor of the file-api."); + return 1; +} +Command constexpr cmake_E_server{ + "server"_s, ""_s, ""_s, _cmake_E_server, Group::Internal, +}; + +#if !defined(CMAKE_BOOTSTRAP) +// Internal CMake Fortran module support. +int _cmake_E_cmake_copy_f90_mod(Command::Arguments args) +{ + if (args.size() < 4) { + return CMakeCommandUsage(args[0]); + } + cmSystemTools::InitializeCMake(args[0].c_str()); + return cmDependsFortran::CopyModule(args) ? 0 : 1; +} +#else +std::nullptr_t constexpr _cmake_E_cmake_copy_f90_mod = nullptr; +#endif +Command constexpr cmake_E_cmake_copy_f90_mod{ + "cmake_copy_f90_mod"_s, ""_s, ""_s, _cmake_E_cmake_copy_f90_mod, + Group::Internal, +}; + +#if defined(_WIN32) && !defined(__CYGWIN__) +// Write registry value +int _cmake_E_write_regv(Command::Arguments args) +{ + if (args.size() <= 3) { + return CMakeCommandUsage(args[0]); + } + cmSystemTools::InitializeCMake(args[0].c_str()); + return cmSystemTools::WriteRegistryValue(args[2], args[3]) ? 0 : 1; +} + +// Delete registry value +int _cmake_E_delete_regv(Command::Arguments args) +{ + if (args.size() <= 2) { + return CMakeCommandUsage(args[0]); + } + cmSystemTools::InitializeCMake(args[0].c_str()); + return cmSystemTools::DeleteRegistryValue(args[2]) ? 0 : 1; +} + +int _cmake_E_comspec(Command::Arguments args) +{ + if (args.size() <= 2) { + return CMakeCommandUsage(args[0]); + } + std::cerr << "Win9x helper \"cmake -E comspec\" no longer supported\n"; return 1; } -int cmcmd::HashSumFile(std::vector<std::string> const& args, - cmCryptoHash::Algo algo) +int _cmake_E_env_vs8_wince(Command::Arguments args) +{ + if (args.size() != 3) { + return CMakeCommandUsage(args[0]); + } + cmSystemTools::InitializeCMake(args[0].c_str()); + return WindowsCEEnvironment("8.0", args[2]); +} + +int _cmake_E_env_vs9_wince(Command::Arguments args) +{ + if (args.size() != 3) { + return CMakeCommandUsage(args[0]); + } + cmSystemTools::InitializeCMake(args[0].c_str()); + return WindowsCEEnvironment("9.0", args[2]); +} +#else +std::nullptr_t constexpr _cmake_E_write_regv = nullptr; +std::nullptr_t constexpr _cmake_E_delete_regv = nullptr; +std::nullptr_t constexpr _cmake_E_comspec = nullptr; +std::nullptr_t constexpr _cmake_E_env_vs8_wince = nullptr; +std::nullptr_t constexpr _cmake_E_env_vs9_wince = nullptr; +#endif + +Command constexpr cmake_E_write_regv{ + "write_regv"_s, "key value"_s, "write registry value"_s, + _cmake_E_write_regv, Group::Windows, +}; +Command constexpr cmake_E_delete_regv{ + "delete_regv"_s, "key"_s, "delete registry value"_s, + _cmake_E_delete_regv, Group::Windows, +}; +Command constexpr cmake_E_comspec{ + "comspec"_s, ""_s, ""_s, _cmake_E_comspec, Group::Internal, +}; +Command constexpr cmake_E_env_vs8_wince{ + "env_vs8_wince"_s, + "sdkname"_s, + "displays a batch file which sets the environment for the provided " + "Windows CE SDK installed in VS2005"_s, + _cmake_E_env_vs8_wince, + Group::Windows, +}; +Command constexpr cmake_E_env_vs9_wince{ + "env_vs9_wince"_s, + "sdkname"_s, + "displays a batch file which sets the environment for the provided " + "Windows CE SDK installed in VS2008"_s, + _cmake_E_env_vs9_wince, + Group::Windows, +}; + +// Internal depfile transformation +int _cmake_E_cmake_transform_depfile(Command::Arguments args) +{ + if (args.size() != 10) { + return CMakeCommandUsage(args[0]); + } + cmSystemTools::InitializeCMake(args[0].c_str()); + auto format = cmDepfileFormat::GccDepfile; + if (args[3] == "gccdepfile") { + format = cmDepfileFormat::GccDepfile; + } else if (args[3] == "makedepfile") { + format = cmDepfileFormat::MakeDepfile; + } else if (args[3] == "MSBuildAdditionalInputs") { + format = cmDepfileFormat::MSBuildAdditionalInputs; + } else { + return 1; + } + // Create a cmake object instance to process dependencies. + // All we need is the `set` command. + cmake cm(cmState::Role::Script); + std::string homeDir; + std::string startDir; + std::string homeOutDir; + std::string startOutDir; + homeDir = cmSystemTools::ToNormalizedPathOnDisk(args[4]); + startDir = cmSystemTools::ToNormalizedPathOnDisk(args[5]); + homeOutDir = cmSystemTools::ToNormalizedPathOnDisk(args[6]); + startOutDir = cmSystemTools::ToNormalizedPathOnDisk(args[7]); + cm.SetHomeDirectory(homeDir); + cm.SetHomeOutputDirectory(homeOutDir); + cm.GetCurrentSnapshot().SetDefaultDefinitions(); + if (auto ggd = cm.CreateGlobalGenerator(args[2])) { + cm.SetGlobalGenerator(std::move(ggd)); + cmStateSnapshot snapshot = cm.GetCurrentSnapshot(); + snapshot.GetDirectory().SetCurrentBinary(startOutDir); + snapshot.GetDirectory().SetCurrentSource(startDir); + cmMakefile mf(cm.GetGlobalGenerator(), snapshot); + auto lgd = cm.GetGlobalGenerator()->CreateLocalGenerator(&mf); + + // FIXME: With advanced add_subdirectory usage, these are + // not necessarily the same as the generator originally used. + // We should pass all these directories through an info file. + lgd->SetRelativePathTop(homeDir, homeOutDir); + + return cmTransformDepfile(format, *lgd, args[8], args[9]) ? 0 : 2; + } + return 1; +} +Command constexpr cmake_E_cmake_transform_depfile{ + "cmake_transform_depfile"_s, + ""_s, + ""_s, + _cmake_E_cmake_transform_depfile, + Group::Internal, +}; + +// Order by `LC_COLLATE=C sort` to search using `std::lower_bound`. +std::array<Command, 63> const Commands{ { + cmake_E___create_def, + cmake_E___run_co_compile, + cmake_E_bin2c, + cmake_E_capabilities, + cmake_E_cat, + cmake_E_chdir, + cmake_E_cmake_autogen, + cmake_E_cmake_autorcc, + cmake_E_cmake_cl_compile_depends, + cmake_E_cmake_copy_f90_mod, + cmake_E_cmake_depends, + cmake_E_cmake_echo_color, + cmake_E_cmake_fastbuild_check_depends, + cmake_E_cmake_link_script, + cmake_E_cmake_llvm_rc, + cmake_E_cmake_module_compile_db, + cmake_E_cmake_ninja_depends, + cmake_E_cmake_ninja_dyndep, + cmake_E_cmake_progress_report, + cmake_E_cmake_progress_start, + cmake_E_cmake_symlink_executable, + cmake_E_cmake_symlink_library, + cmake_E_cmake_transform_depfile, + cmake_E_cmake_unimplemented_variable, + cmake_E_compare_files, + cmake_E_comspec, + cmake_E_copy, + cmake_E_copy_directory, + cmake_E_copy_directory_if_different, + cmake_E_copy_directory_if_newer, + cmake_E_copy_if_different, + cmake_E_copy_if_newer, + cmake_E_create_hardlink, + cmake_E_create_symlink, + cmake_E_delete_regv, + cmake_E_echo, + cmake_E_echo_append, + cmake_E_env, + cmake_E_env_vs8_wince, + cmake_E_env_vs9_wince, + cmake_E_environment, + cmake_E_false, + cmake_E_make_directory, + cmake_E_md5sum, + cmake_E_remove, + cmake_E_remove_directory, + cmake_E_rename, + cmake_E_rm, + cmake_E_server, + cmake_E_sha1sum, + cmake_E_sha224sum, + cmake_E_sha256sum, + cmake_E_sha384sum, + cmake_E_sha512sum, + cmake_E_sleep, + cmake_E_tar, + cmake_E_time, + cmake_E_touch, + cmake_E_touch_nocreate, + cmake_E_true, + cmake_E_vs_link_dll, + cmake_E_vs_link_exe, + cmake_E_write_regv, +} }; + +std::vector<std::string> CommandNames() +{ + std::vector<std::string> names; + names.reserve(Commands.size()); + for (Command const& c : Commands) { + if (c.Impl) { + names.emplace_back(c.Name); + } + } + return names; +} + +std::string FormatCommandLineHelp(cm::string_view header, Group group) +{ + std::size_t const helpColumn = 28; + std::string result = cmStrCat(header, ":\n"); + for (Command const& entry : Commands) { + if (entry.Group != group || !entry.Impl) { + continue; + } + std::string invocation{ entry.Name }; + if (!entry.Usage.empty()) { + invocation = cmStrCat(std::move(invocation), ' ', entry.Usage); + } + std::string line = cmStrCat(" ", invocation); + if (line.size() + 2 <= helpColumn) { + line.resize(helpColumn, ' '); + result = cmStrCat(std::move(result), line, "- ", entry.Help, '\n'); + } else { + result = cmStrCat(std::move(result), line, '\n', + std::string(helpColumn, ' '), "- ", entry.Help, '\n'); + } + } + return result; +} + +int CMakeCommandUsage(std::string const& program) +{ + /* clang-format off */ + std::string help_screen = cmStrCat( +#ifndef CMAKE_BOOTSTRAP + "cmake version " + , cmVersion::GetCMakeVersion() + , "\n" +#else + "cmake bootstrap\n" +#endif + "Usage: " + , program + , " -E <command> [arguments...]\n" + , FormatCommandLineHelp("Available commands", Group::Common) +#if defined(_WIN32) && !defined(__CYGWIN__) + , FormatCommandLineHelp("Available on Windows only", + Group::Windows) +#endif + ); + /* clang-format on */ + cmSystemTools::Error(help_screen); + return 1; +} + +} + +namespace cmcmd { + +int ExecuteCMakeCommand(std::vector<std::string> args_, + cm::optional<cm::StdIo::Console> console) +{ + Command::Arguments args(std::move(args_), std::move(console)); + if (args.size() > 1) { + // NOLINTNEXTLINE(readability-qualified-auto) + auto i = std::lower_bound(Commands.begin(), Commands.end(), args[1]); + if (i != Commands.end() && i->Name == args[1] && i->Impl) { + return i->Impl(std::move(args)); + } + + std::string error = cmStrCat("Unknown command \"", args[1], "\"."); + std::string const suggestion = + cmFindClosestString(args[1], CommandNames()); + if (!suggestion.empty()) { + error = + cmStrCat(std::move(error), " Did you mean \"", suggestion, "\"?"); + } + cmSystemTools::Error(error); + } + + return CMakeCommandUsage(args[0]); +} + +} + +namespace { + +int HashSumFile(std::vector<std::string> const& args, cmCryptoHash::Algo algo) { if (args.size() < 3) { return -1; @@ -2587,7 +3194,7 @@ return retval; } -int cmcmd::SymlinkLibrary(std::vector<std::string> const& args) +int SymlinkLibrary(std::vector<std::string> const& args) { int result = 0; std::string realName = args[2]; @@ -2597,7 +3204,7 @@ cmSystemTools::ConvertToUnixSlashes(soName); cmSystemTools::ConvertToUnixSlashes(name); if (soName != realName) { - cmsys::Status status = cmcmd::SymlinkInternal(realName, soName); + cmsys::Status status = SymlinkInternal(realName, soName); if (!status) { cmSystemTools::Error( cmStrCat("cmake_symlink_library: System Error: ", status.GetString())); @@ -2605,7 +3212,7 @@ } } if (name != soName) { - cmsys::Status status = cmcmd::SymlinkInternal(soName, name); + cmsys::Status status = SymlinkInternal(soName, name); if (!status) { cmSystemTools::Error( cmStrCat("cmake_symlink_library: System Error: ", status.GetString())); @@ -2615,13 +3222,13 @@ return result; } -int cmcmd::SymlinkExecutable(std::vector<std::string> const& args) +int SymlinkExecutable(std::vector<std::string> const& args) { int result = 0; std::string const& realName = args[2]; std::string const& name = args[3]; if (name != realName) { - cmsys::Status status = cmcmd::SymlinkInternal(realName, name); + cmsys::Status status = SymlinkInternal(realName, name); if (!status) { cmSystemTools::Error(cmStrCat("cmake_symlink_executable: System Error: ", status.GetString())); @@ -2631,8 +3238,7 @@ return result; } -cmsys::Status cmcmd::SymlinkInternal(std::string const& file, - std::string const& link) +cmsys::Status SymlinkInternal(std::string const& file, std::string const& link) { if (cmSystemTools::PathExists(link)) { cmSystemTools::RemoveFile(link); @@ -2655,7 +3261,7 @@ #endif } -static void cmcmdProgressReport(std::string const& dir, std::string const& num) +void cmcmdProgressReport(std::string const& dir, std::string const& num) { std::string dirName = cmStrCat(dir, "/Progress"); std::string fName; @@ -2699,7 +3305,7 @@ } } -int cmcmd::ExecuteEchoColor(std::vector<std::string> const& args) +int ExecuteEchoColor(std::vector<std::string> const& args) { // The arguments are // args[0] == <cmake-executable> @@ -2762,7 +3368,7 @@ return 0; } -int cmcmd::ExecuteLinkScript(std::vector<std::string> const& args) +int ExecuteLinkScript(std::vector<std::string> const& args) { // The arguments are // args[0] == <cmake-executable> @@ -2843,9 +3449,10 @@ return result; } -int cmcmd::WindowsCEEnvironment(char const* version, std::string const& name) +#if defined(_WIN32) && !defined(__CYGWIN__) +int WindowsCEEnvironment(char const* version, std::string const& name) { -#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) && !defined(__CYGWIN__) +# if !defined(CMAKE_BOOTSTRAP) cmVisualStudioWCEPlatformParser parser(name.c_str()); parser.ParseVersion(version); if (parser.Found()) { @@ -2858,16 +3465,17 @@ /* clang-format on */ return 0; } -#else +# else (void)version; -#endif +# endif std::cerr << "Could not find " << name; return -1; } +#endif -int cmcmd::RunPreprocessor(std::vector<std::string> const& command, - std::string const& intermediate_file) +int RunPreprocessor(std::vector<std::string> const& command, + std::string const& intermediate_file) { cmUVProcessChainBuilder builder; @@ -2900,7 +3508,7 @@ return 0; } -int cmcmd::RunLLVMRC(std::vector<std::string> const& args) +int RunLLVMRC(std::vector<std::string> const& args) { // The arguments are // args[0] == <cmake-executable> @@ -3061,8 +3669,8 @@ // For visual studio 2005 and newer manifest files need to be embedded into // exe and dll's. This code does that in such a way that incremental linking // still works. -int cmcmd::VisualStudioLink(std::vector<std::string> const& args, int type, - cm::optional<cm::StdIo::Console> console) +int VisualStudioLink(std::vector<std::string> const& args, int type, + cm::optional<cm::StdIo::Console> console) { // MSVC tools print output in the language specified by the VSLANG // environment variable, and encoded in the console output code page. @@ -3114,8 +3722,8 @@ { } }; -static std::ostream& operator<<(std::ostream& stream, - NumberFormatter const& formatter) +std::ostream& operator<<(std::ostream& stream, + NumberFormatter const& formatter) { auto const& flags = stream.flags(); if (formatter.Format == FORMAT_DECIMAL) { @@ -3127,10 +3735,9 @@ return stream; } -static bool RunCommand(char const* comment, - std::vector<std::string> const& command, bool verbose, - NumberFormat exitFormat, int* retCodeOut = nullptr, - bool (*retCodeOkay)(int) = nullptr) +bool RunCommand(char const* comment, std::vector<std::string> const& command, + bool verbose, NumberFormat exitFormat, + int* retCodeOut = nullptr, bool (*retCodeOkay)(int) = nullptr) { // See comment in VisualStudioLink for why we suppress encoding conversion. cmProcessOutput::Encoding const encoding = cmProcessOutput::None; @@ -3280,7 +3887,7 @@ return this->LinkNonIncremental(); } -static bool mtRetIsUpdate(int mtRet) +bool mtRetIsUpdate(int mtRet) { // 'mt /notify_update' returns a special value (differing between // Windows and POSIX hosts) when it updated the manifest file. @@ -3475,3 +4082,5 @@ } return mtRet; } + +}
diff --git a/Source/cmcmd.h b/Source/cmcmd.h index e3f9a18..783c53f 100644 --- a/Source/cmcmd.h +++ b/Source/cmcmd.h
@@ -9,41 +9,17 @@ #include <cm/optional> -#include "cmsys/Status.hxx" - -#include "cmCryptoHash.h" - namespace cm { namespace StdIo { class Console; } } -class cmcmd -{ -public: - /** - * Execute commands during the build process. Supports options such - * as echo, remove file etc. - */ - static int ExecuteCMakeCommand(std::vector<std::string> const&, - cm::optional<cm::StdIo::Console> console); - -protected: - static int HandleCoCompileCommands(std::vector<std::string> const& args); - static int HashSumFile(std::vector<std::string> const& args, - cmCryptoHash::Algo algo); - static int SymlinkLibrary(std::vector<std::string> const& args); - static int SymlinkExecutable(std::vector<std::string> const& args); - static cmsys::Status SymlinkInternal(std::string const& file, - std::string const& link); - static int ExecuteEchoColor(std::vector<std::string> const& args); - static int ExecuteLinkScript(std::vector<std::string> const& args); - static int WindowsCEEnvironment(char const* version, - std::string const& name); - static int RunPreprocessor(std::vector<std::string> const& command, - std::string const& intermediate_file); - static int RunLLVMRC(std::vector<std::string> const& args); - static int VisualStudioLink(std::vector<std::string> const& args, int type, - cm::optional<cm::StdIo::Console> console); -}; +namespace cmcmd { +/** + * Execute commands during the build process. Supports options such + * as echo, remove file etc. + */ +int ExecuteCMakeCommand(std::vector<std::string> args, + cm::optional<cm::StdIo::Console> console); +}
diff --git a/Source/ctest.cxx b/Source/ctest.cxx index 396991e..f1cf3e3 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx
@@ -166,6 +166,8 @@ "CPU load threshold for starting new parallel tests." }, { "--tomorrow-tag", "Nightly or experimental starts with next day tag." }, { "--overwrite <option-name>", "Overwrite CTest configuration option." }, + { "--output-dir <path>", + "Specify the directory in which to write output files." }, { "--extra-submit <file>[;<file>]", "Submit extra files to the dashboard." }, { "--http-header <header>", "Append HTTP header when submitting" }, { "--schedule-random", "Use a random order for scheduling tests" }, @@ -198,8 +200,7 @@ argc = encoding_args.argc(); argv = encoding_args.argv(); - cmSystemTools::InitializeLibUV(); - cmSystemTools::FindCMakeResources(argv[0]); + cmSystemTools::InitializeCMake(argv[0]); // Dispatch 'ctest --launch' mode directly. if (argc >= 2 && strcmp(argv[1], "--launch") == 0) {
diff --git a/Source/kwsys/EncodingCXX.cxx b/Source/kwsys/EncodingCXX.cxx index 1d1eed8..24ca1d0 100644 --- a/Source/kwsys/EncodingCXX.cxx +++ b/Source/kwsys/EncodingCXX.cxx
@@ -31,8 +31,89 @@ // Windows API. #if defined(_WIN32) # include <windows.h> +#endif -# include <shellapi.h> +#ifdef _WIN32 +namespace { +// Split a command line into arguments using the same rules as +// CommandLineToArgvW, which is in shell32.dll. Loading shell32.dll +// also loads user32.dll, gdi32.dll and others, and costs several +// milliseconds at the start of every process that uses this class. +std::vector<std::wstring> SplitCommandLine(wchar_t const* p) +{ + std::vector<std::wstring> args; + if (!*p) { + // An empty command line gives the path of the executable. + std::wstring path(MAX_PATH, L'\0'); + DWORD n; + while ((n = GetModuleFileNameW(nullptr, &path[0], + static_cast<DWORD>(path.size()))) == + path.size()) { + path.resize(path.size() * 2); + } + path.resize(n); + args.emplace_back(std::move(path)); + return args; + } + // The program name is taken as is, up to the closing quote if it + // starts with one, or else up to the first space or tab. + std::wstring arg; + if (*p == L'"') { + for (++p; *p && *p != L'"'; ++p) { + arg += *p; + } + if (*p == L'"') { + ++p; + } + } else { + for (; *p && *p != L' ' && *p != L'\t'; ++p) { + arg += *p; + } + } + args.emplace_back(std::move(arg)); + for (;;) { + while (*p == L' ' || *p == L'\t') { + ++p; + } + if (!*p) { + break; + } + arg.clear(); + bool quoted = false; + for (;;) { + size_t backslashes = 0; + while (*p == L'\\') { + ++backslashes; + ++p; + } + if (*p == L'"') { + arg.append(backslashes / 2, L'\\'); + if (backslashes % 2) { + arg += L'"'; + ++p; + } else if (quoted && p[1] == L'"') { + // A doubled quote inside quotes is a literal quote, and ends + // the quoted part. + arg += L'"'; + p += 2; + quoted = false; + } else { + quoted = !quoted; + ++p; + } + continue; + } + arg.append(backslashes, L'\\'); + if (!*p || (!quoted && (*p == L' ' || *p == L'\t'))) { + break; + } + arg += *p++; + } + args.emplace_back(std::move(arg)); + } + return args; +} +} #endif namespace KWSYS_NAMESPACE { @@ -44,8 +125,8 @@ (void)argc; (void)argv; - int ac; - LPWSTR* w_av = CommandLineToArgvW(GetCommandLineW(), &ac); + std::vector<std::wstring> w_av = SplitCommandLine(GetCommandLineW()); + int ac = static_cast<int>(w_av.size()); std::vector<std::string> av1(ac); std::vector<char const*> av2(ac); @@ -53,7 +134,6 @@ av1[i] = ToNarrow(w_av[i]); av2[i] = av1[i].c_str(); } - LocalFree(w_av); return CommandLineArguments(ac, &av2[0]); #else return CommandLineArguments(argc, argv);
diff --git a/Templates/CTestScript.cmake.in b/Templates/CTestScript.cmake.in index 4282a01..74608af 100644 --- a/Templates/CTestScript.cmake.in +++ b/Templates/CTestScript.cmake.in
@@ -8,6 +8,12 @@ set(CTEST_SOURCE_DIRECTORY "@PROJECT_SOURCE_DIR@") set(CTEST_BINARY_DIRECTORY "@PROJECT_BINARY_DIR@") +# Where CTest writes its output files. May be set on the command line to +# keep separate ctest runs over one build tree from overwriting each other. +if(NOT DEFINED CTEST_OUTPUT_DIRECTORY) + set(CTEST_OUTPUT_DIRECTORY "${CTEST_BINARY_DIRECTORY}/Testing") +endif() + # CTest Update Step set(CTEST_UPDATE_COMMAND "@UPDATE_COMMAND@") set(CTEST_UPDATE_OPTIONS "@UPDATE_OPTIONS@") @@ -92,7 +98,7 @@ set(_exit_code 0) -if("Start" IN_LIST ACTIONS OR NOT EXISTS "${CTEST_BINARY_DIRECTORY}/Testing/TAG") +if("Start" IN_LIST ACTIONS OR NOT EXISTS "${CTEST_OUTPUT_DIRECTORY}/TAG") ctest_start("${MODEL}") else() ctest_start("${MODEL}" APPEND) @@ -148,7 +154,7 @@ endif() file(GLOB notes_files LIST_DIRECTORIES OFF - "${CTEST_BINARY_DIRECTORY}/Testing/Notes/*") + "${CTEST_OUTPUT_DIRECTORY}/Notes/*") if(notes_files) list(APPEND CTEST_NOTES_FILES "${notes_files}") endif()
diff --git a/Tests/FindJNI/AWT/CMakeLists.txt b/Tests/FindJNI/AWT/CMakeLists.txt index bdf49ea..d1ba4e8 100644 --- a/Tests/FindJNI/AWT/CMakeLists.txt +++ b/Tests/FindJNI/AWT/CMakeLists.txt
@@ -16,7 +16,7 @@ foreach (test AWTTgt AWTVar) add_test (NAME Compile${test} COMMAND ${Java_JAVAC_EXECUTABLE} ${TestAWT_SOURCE_DIR}/${test}.java) - add_test (NAME Remove${test} COMMAND ${CMAKE_COMMAND} -E remove + add_test (NAME Remove${test} COMMAND ${CMAKE_COMMAND} -E rm -f ${TestAWT_SOURCE_DIR}/${test}.class) add_test (NAME ${test} COMMAND ${Java_JAVA_EXECUTABLE}
diff --git a/Tests/FindJNI/JVM/CMakeLists.txt b/Tests/FindJNI/JVM/CMakeLists.txt index cead6ae..942d39c 100644 --- a/Tests/FindJNI/JVM/CMakeLists.txt +++ b/Tests/FindJNI/JVM/CMakeLists.txt
@@ -16,7 +16,7 @@ foreach (test JVMTgt JVMVar) add_test (NAME Compile${test} COMMAND ${Java_JAVAC_EXECUTABLE} ${TestJVM_SOURCE_DIR}/${test}.java) - add_test (NAME Remove${test} COMMAND ${CMAKE_COMMAND} -E remove + add_test (NAME Remove${test} COMMAND ${CMAKE_COMMAND} -E rm -f ${TestJVM_SOURCE_DIR}/${test}.class) add_test (NAME ${test} COMMAND ${Java_JAVA_EXECUTABLE}
diff --git a/Tests/FindJNI/Minimal/CMakeLists.txt b/Tests/FindJNI/Minimal/CMakeLists.txt index 03cf88b..cd89a05 100644 --- a/Tests/FindJNI/Minimal/CMakeLists.txt +++ b/Tests/FindJNI/Minimal/CMakeLists.txt
@@ -22,7 +22,7 @@ foreach (test MinimalTgt MinimalVar) add_test (NAME Compile${test} COMMAND ${Java_JAVAC_EXECUTABLE} ${TestMinimal_SOURCE_DIR}/${test}.java) - add_test (NAME Remove${test} COMMAND ${CMAKE_COMMAND} -E remove + add_test (NAME Remove${test} COMMAND ${CMAKE_COMMAND} -E rm -f ${TestMinimal_SOURCE_DIR}/${test}.class) add_test (NAME ${test} COMMAND ${Java_JAVA_EXECUTABLE}
diff --git a/Tests/FindOpenMP/Test/CMakeLists.txt b/Tests/FindOpenMP/Test/CMakeLists.txt index bf87e62..9aee098 100644 --- a/Tests/FindOpenMP/Test/CMakeLists.txt +++ b/Tests/FindOpenMP/Test/CMakeLists.txt
@@ -44,6 +44,16 @@ endif() endif() +# Clang should use the OpenMP runtime next to it, not MSVC's from LIB. +if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_SIMULATE_ID STREQUAL "MSVC") + get_filename_component(clang_lib_dir "${CMAKE_C_COMPILER}" DIRECTORY) + get_filename_component(clang_lib_dir "${clang_lib_dir}/../lib" ABSOLUTE) + get_filename_component(omp_lib_dir "${OpenMP_libomp_LIBRARY}" DIRECTORY) + if(EXISTS "${clang_lib_dir}/libomp.lib" AND NOT omp_lib_dir STREQUAL clang_lib_dir) + message(FATAL_ERROR "OpenMP_libomp_LIBRARY not from '${clang_lib_dir}': '${OpenMP_libomp_LIBRARY}'") + endif() +endif() + # FIXME(#26701) Needed to check target offload conditions foreach(c C CXX Fortran) if(NOT "${OpenMP_TEST_${c}}")
diff --git a/Tests/Fuzzing/CMakeLists.txt b/Tests/Fuzzing/CMakeLists.txt index 06392e5..750d0e3 100644 --- a/Tests/Fuzzing/CMakeLists.txt +++ b/Tests/Fuzzing/CMakeLists.txt
@@ -62,6 +62,9 @@ # Generator expression fuzzer add_fuzzer(cmGeneratorExpressionFuzzer cmGeneratorExpressionFuzzer.cxx) +# Generator expression evaluation fuzzer +add_fuzzer(cmGeneratorExpressionEvalFuzzer cmGeneratorExpressionEvalFuzzer.cxx) + # Math expression parser fuzzer add_fuzzer(cmExprParserFuzzer cmExprParserFuzzer.cxx)
diff --git a/Tests/Fuzzing/cmGeneratorExpressionEval.dict b/Tests/Fuzzing/cmGeneratorExpressionEval.dict new file mode 100644 index 0000000..8cd78f0 --- /dev/null +++ b/Tests/Fuzzing/cmGeneratorExpressionEval.dict
@@ -0,0 +1,196 @@ +# CMake generator expression evaluation dictionary + +# Syntax +"$<" +">" +":" +"," +";" + +# Logic and comparison +"$<0:" +"$<1:" +"$<BOOL:" +"$<AND:" +"$<OR:" +"$<NOT:" +"$<IF:" +"$<STREQUAL:" +"$<STRLESS:" +"$<STRGREATER_EQUAL:" +"$<EQUAL:" +"$<IN_LIST:" +"$<VERSION_LESS:" +"$<VERSION_GREATER:" +"$<VERSION_EQUAL:" +"$<VERSION_LESS_EQUAL:" +"$<PATH_EQUAL:" + +# String, list and path +"$<STRING:" +"$<LIST:" +"$<PATH:" +"$<JOIN:" +"$<FILTER:" +"$<REMOVE_DUPLICATES:" +"$<LOWER_CASE:" +"$<UPPER_CASE:" +"$<MAKE_C_IDENTIFIER:" +"$<SHELL_PATH:" +"$<ANGLE-R>" +"$<COMMA>" +"$<SEMICOLON>" +"$<QUOTE>" +"LENGTH" +"SUBSTRING" +"FIND" +"MATCH" +"REPLACE" +"APPEND" +"PREPEND" +"TOLOWER" +"TOUPPER" +"STRIP" +"HEX" +"HASH" +"UUID" +"GET" +"SUBLIST" +"INSERT" +"POP_BACK" +"POP_FRONT" +"REMOVE_ITEM" +"REMOVE_AT" +"TRANSFORM" +"REVERSE" +"SORT" +"ORDER:DESCENDING" +"COMPARE:NATURAL" +"INCLUDE" +"EXCLUDE" +"GET_FILENAME" +"GET_EXTENSION" +"GET_PARENT_PATH" +"REPLACE_EXTENSION" +"NORMAL_PATH" +"RELATIVE_PATH" +"ABSOLUTE_PATH" +"CMAKE_PATH" +"IS_PREFIX" + +# Context +"$<CONFIG>" +"$<CONFIG:" +"$<CONFIGURATION>" +"$<PLATFORM_ID:" +"$<COMPILE_LANGUAGE>" +"$<COMPILE_LANGUAGE:" +"$<COMPILE_LANG_AND_ID:" +"$<LINK_LANGUAGE>" +"$<LINK_LANGUAGE:" +"$<LINK_LANG_AND_ID:" +"$<COMPILE_FEATURES:" +"$<C_COMPILER_ID>" +"$<CXX_COMPILER_ID:" +"$<CXX_COMPILER_VERSION>" +"$<CXX_COMPILER_FRONTEND_VARIANT>" +"$<CXX_COMPILER_LINKER_ID>" +"$<HOST_LINK:" +"$<DEVICE_LINK:" +"$<BUILD_INTERFACE:" +"$<BUILD_LOCAL_INTERFACE:" +"$<INSTALL_INTERFACE:" +"$<INSTALL_PREFIX>" +"$<GENEX_EVAL:" +"$<TARGET_GENEX_EVAL:" +"$<LINK_ONLY:" +"$<COMPILE_ONLY:" +"$<LINK_LIBRARY:" +"$<LINK_GROUP:" +"WHOLE_ARCHIVE" +"RESCAN" + +# Targets +"$<TARGET_PROPERTY:" +"$<TARGET_EXISTS:" +"$<TARGET_NAME_IF_EXISTS:" +"$<TARGET_NAME:" +"$<TARGET_POLICY:" +"$<TARGET_OBJECTS:" +"$<TARGET_FILE:" +"$<TARGET_FILE_NAME:" +"$<TARGET_FILE_DIR:" +"$<TARGET_FILE_BASE_NAME:" +"$<TARGET_FILE_PREFIX:" +"$<TARGET_FILE_SUFFIX:" +"$<TARGET_LINKER_FILE:" +"$<TARGET_LINKER_FILE_NAME:" +"$<TARGET_LINKER_IMPORT_FILE:" +"$<TARGET_IMPORT_FILE:" +"$<TARGET_SONAME_FILE:" +"$<TARGET_PDB_FILE:" +"$<TARGET_BUNDLE_DIR:" +"$<TARGET_INTERMEDIATE_DIR:" +"$<TARGET_RUNTIME_DLLS:" +"$<GLOBAL_PROPERTY:" +"$<SOURCE_PROPERTY:" +"$<SOURCE_EXISTS:" +"$<FILE_SET_EXISTS:" +"$<FILE_SET_PROPERTY:" +"TARGET:" +"DIRECTORY:" +"TARGET_DIRECTORY:" +"SOURCE_FILES:" + +# Fixture names +"fuzz_exe" +"fuzz_static" +"Fuzz::static" +"fuzz_obj" +"fuzz_iface" +"fuzz_dep" +"fuzz_imported_exe" +"fuzz_imported_static" +"fuzz_imported_shared" +"Fuzz::shared" +"fuzz_custom" +"fuzz.c" +"fuzz.cpp" +"HEADERS" +"Debug" +"Release" +"RelWithDebInfo" +"GNU" +"Clang" +"CXX" +"C" +"cxx_std_17" +"c_std_11" + +# Properties +"COMPILE_DEFINITIONS" +"COMPILE_OPTIONS" +"INCLUDE_DIRECTORIES" +"LINK_OPTIONS" +"LINK_LIBRARIES" +"LINK_DIRECTORIES" +"SOURCES" +"TYPE" +"NAME" +"OUTPUT_NAME" +"LINKER_LANGUAGE" +"POSITION_INDEPENDENT_CODE" +"IMPORTED_LOCATION" +"ALIASED_TARGET" +"ALIAS_GLOBAL" +"INTERFACE_COMPILE_DEFINITIONS" +"INTERFACE_INCLUDE_DIRECTORIES" +"INTERFACE_LINK_LIBRARIES" +"INTERFACE_FUZZ_CUSTOM" +"FUZZ_BOOL" +"FUZZ_STRING" +"FUZZ_NUMBER" +"FUZZ_CUSTOM" +"FUZZ_GLOBAL" +"HEADER_SET" +"CMP0004"
diff --git a/Tests/Fuzzing/cmGeneratorExpressionEvalFuzzer.cxx b/Tests/Fuzzing/cmGeneratorExpressionEvalFuzzer.cxx new file mode 100644 index 0000000..0b94ba6 --- /dev/null +++ b/Tests/Fuzzing/cmGeneratorExpressionEvalFuzzer.cxx
@@ -0,0 +1,449 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file LICENSE.rst or https://cmake.org/licensing for details. */ + +/* + * Fuzzer for generator expression evaluation. + * + * cmGeneratorExpressionFuzzer only tokenizes and preprocesses $<...>, and + * cmScriptFuzzer runs in script mode where no generator exists, so the + * evaluator (cmGeneratorExpressionNode.cxx, the DAG checker, and the + * transitive-property / link-interface code in cmGeneratorTarget) is never + * reached by any fuzzer. + * + * Each input gets a fresh project-mode fixture: a base cmGlobalGenerator, a + * makefile populated from a fixed listfile (interface, imported, alias, + * object, static, executable and custom targets with genex-bearing usage + * requirements), and generator targets created the same way as + * "cmake --find-package" does. C and CXX are marked enabled with + * GNU-like compiler variables so that language- and compiler-dependent + * expressions have something to evaluate against. No compiler is run. + * + * Input layout: + * byte 0: bits 0-1 mode, bits 2-4 head target, bits 5-6 config, + * bit 7 EvaluateForBuildsystem + * byte 1: bits 0-2 language, bits 3-4 property, bits 5-7 current target + * rest: generator expression (or property value in Injection mode) + * + * Modes (see Mode below): + * Evaluate cmGeneratorExpression::Evaluate + * Compiled Parse once, evaluate for two configs, query collected + * metadata Interpreter cmGeneratorExpressionInterpreter with a + * transitive-property DAG Injection Store the input in a usage-requirement + * property of a fixture target, then read it back through a consumer so it is + * evaluated transitively + */ + +#include <cstddef> +#include <cstdint> +#include <cstdio> +#include <cstdlib> +#include <map> +#include <memory> +#include <string> +#include <utility> + +#include <cm/memory> + +#include "cmGenExContext.h" +#include "cmGeneratorExpression.h" +#include "cmGlobalGenerator.h" +#include "cmLocalGenerator.h" +#include "cmMakefile.h" +#include "cmMessageMetadata.h" +#include "cmState.h" +#include "cmStateDirectory.h" +#include "cmStateSnapshot.h" +#include "cmSystemTools.h" +#include "cmTarget.h" +#include "cmake.h" + +static constexpr size_t kHeaderSize = 2; +// Evaluation is recursive in nesting depth; keep inputs short. +static constexpr size_t kMaxExprSize = 4 * 1024; + +static std::string g_srcDir; +static std::string g_binDir; + +namespace { + +// Stand-in for the variables project() would load after compiler detection. +char const kToolchain[] = R"cmake( +cmake_minimum_required(VERSION 4.0) +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR x86_64) +set(CMAKE_BUILD_TYPE Debug) +set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE) +set(CMAKE_STATIC_LIBRARY_PREFIX lib) +set(CMAKE_STATIC_LIBRARY_SUFFIX .a) +set(CMAKE_SHARED_LIBRARY_PREFIX lib) +set(CMAKE_SHARED_LIBRARY_SUFFIX .so) +set(CMAKE_SHARED_MODULE_PREFIX lib) +set(CMAKE_SHARED_MODULE_SUFFIX .so) +set(CMAKE_EXECUTABLE_SUFFIX "") +foreach(lang IN ITEMS C CXX) + set(CMAKE_${lang}_COMPILER_ID GNU) + set(CMAKE_${lang}_COMPILER_VERSION 13.2.0) + set(CMAKE_${lang}_COMPILER_FRONTEND_VARIANT GNU) + set(CMAKE_${lang}_COMPILER_LINKER_ID GNU) + set(CMAKE_${lang}_COMPILER_LINKER_FRONTEND_VARIANT GNU) + set(CMAKE_${lang}_OUTPUT_EXTENSION .o) + set(CMAKE_${lang}_STANDARD_DEFAULT 17) +endforeach() +set(CMAKE_C_COMPILER /usr/bin/cc) +set(CMAKE_C_SOURCE_FILE_EXTENSIONS c m) +set(CMAKE_C_IGNORE_EXTENSIONS h H o O obj OBJ def DEF rc RC) +set(CMAKE_C_LINKER_PREFERENCE 10) +set(CMAKE_C_COMPILE_FEATURES + c_std_90 c_std_99 c_std_11 c_std_17 c_std_23 + c_function_prototypes c_restrict c_static_assert c_variadic_macros) +set(CMAKE_CXX_COMPILER /usr/bin/c++) +set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS + C M c++ cc cpp cxx mm mpp CPP ixx cppm ccm cxxm c++m) +set(CMAKE_CXX_IGNORE_EXTENSIONS inl h hpp HPP H o O obj OBJ def DEF rc RC) +set(CMAKE_CXX_LINKER_PREFERENCE 30) +set(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1) +set(CMAKE_CXX_COMPILE_FEATURES + cxx_std_98 cxx_std_11 cxx_std_14 cxx_std_17 cxx_std_20 cxx_std_23 + cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_variadic_templates) +)cmake"; + +char const kProject[] = R"cmake( +cmake_minimum_required(VERSION 4.0) + +add_library(fuzz_iface INTERFACE) +target_compile_definitions(fuzz_iface INTERFACE + IFACE_DEF=1 + $<$<CONFIG:Debug>:IFACE_DEBUG> + $<$<COMPILE_LANGUAGE:CXX>:IFACE_CXX>) +target_include_directories(fuzz_iface INTERFACE + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> + $<INSTALL_INTERFACE:include>) +target_compile_options(fuzz_iface INTERFACE + $<$<COMPILE_LANG_AND_ID:CXX,GNU,Clang>:-Wall>) +target_link_options(fuzz_iface INTERFACE + $<$<LINK_LANGUAGE:CXX>:-Wl,--as-needed>) +target_sources(fuzz_iface INTERFACE + FILE_SET HEADERS BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES ${CMAKE_CURRENT_SOURCE_DIR}/fuzz.h) +set_target_properties(fuzz_iface PROPERTIES + INTERFACE_FUZZ_BOOL ON + INTERFACE_FUZZ_STRING fuzz + INTERFACE_FUZZ_NUMBER 3 + INTERFACE_FUZZ_CUSTOM "custom;$<CONFIG>" + COMPATIBLE_INTERFACE_BOOL FUZZ_BOOL + COMPATIBLE_INTERFACE_STRING FUZZ_STRING + COMPATIBLE_INTERFACE_NUMBER_MAX FUZZ_NUMBER + TRANSITIVE_COMPILE_PROPERTIES FUZZ_CUSTOM) + +add_library(fuzz_dep INTERFACE) +target_link_libraries(fuzz_dep INTERFACE + fuzz_iface + $<LINK_ONLY:fuzz_imported_static> + $<$<CONFIG:Release>:Fuzz::shared>) + +add_library(fuzz_imported_static STATIC IMPORTED) +set_target_properties(fuzz_imported_static PROPERTIES + IMPORTED_CONFIGURATIONS "DEBUG;RELEASE" + IMPORTED_LOCATION_DEBUG /opt/fuzz/lib/libfuzz_d.a + IMPORTED_LOCATION_RELEASE /opt/fuzz/lib/libfuzz.a + MAP_IMPORTED_CONFIG_RELWITHDEBINFO Release + IMPORTED_LINK_INTERFACE_LANGUAGES C + INTERFACE_COMPILE_DEFINITIONS IMPORTED_STATIC) + +add_library(fuzz_imported_shared SHARED IMPORTED GLOBAL) +set_target_properties(fuzz_imported_shared PROPERTIES + IMPORTED_LOCATION /opt/fuzz/lib/libfuzz_shared.so.1.2.3 + IMPORTED_SONAME libfuzz_shared.so.1 + INTERFACE_INCLUDE_DIRECTORIES /opt/fuzz/include + INTERFACE_LINK_LIBRARIES fuzz_imported_static) +add_library(Fuzz::shared ALIAS fuzz_imported_shared) + +add_executable(fuzz_imported_exe IMPORTED) +set_property(TARGET fuzz_imported_exe PROPERTY + IMPORTED_LOCATION /opt/fuzz/bin/fuzz_tool) + +add_library(fuzz_obj OBJECT fuzz.c fuzz.cpp) +target_compile_definitions(fuzz_obj PRIVATE OBJ_DEF) + +add_library(fuzz_static STATIC fuzz.c) +target_link_libraries(fuzz_static + PUBLIC fuzz_dep + PRIVATE fuzz_obj Fuzz::shared) +set_target_properties(fuzz_static PROPERTIES + OUTPUT_NAME fuzzy + OUTPUT_NAME_DEBUG fuzzy_d + POSITION_INDEPENDENT_CODE ON + COMPILE_DEFINITIONS "STATIC_OWN=$<CONFIG>") +add_library(Fuzz::static ALIAS fuzz_static) + +add_executable(fuzz_exe fuzz.cpp) +target_link_libraries(fuzz_exe PRIVATE Fuzz::static) +set_property(TARGET fuzz_exe PROPERTY FUZZ_STRING fuzz) + +add_custom_target(fuzz_custom + COMMAND fuzz_imported_exe $<TARGET_FILE:fuzz_exe>) + +set_source_files_properties(fuzz.c PROPERTIES + COMPILE_DEFINITIONS "SRC_DEF=$<CONFIG>" + FUZZ_SRC_PROP value) +set_property(GLOBAL PROPERTY FUZZ_GLOBAL "global;value") +set_property(DIRECTORY PROPERTY FUZZ_DIR_PROP dir) +)cmake"; + +char const* const kConfigs[] = { "", "Debug", "Release", "RelWithDebInfo" }; + +char const* const kLanguages[] = { "", "C", "CXX", "CUDA", + "Fortran", "HIP", "OBJC", "Swift" }; + +// Index 0 means "no target". +char const* const kTargets[] = { + nullptr, "fuzz_exe", "fuzz_static", + "fuzz_obj", "fuzz_iface", "fuzz_imported_static", + "Fuzz::shared", "fuzz_custom", +}; + +char const* const kFixtureTargets[] = { + "fuzz_exe", "fuzz_static", "Fuzz::static", + "fuzz_obj", "fuzz_iface", "fuzz_dep", + "fuzz_imported_exe", "fuzz_imported_static", "fuzz_imported_shared", + "Fuzz::shared", "fuzz_custom", +}; + +// Properties that generators pass to cmGeneratorExpressionInterpreter. +char const* const kInterpreterProperties[] = { + "COMPILE_OPTIONS", + "COMPILE_DEFINITIONS", + "INCLUDE_DIRECTORIES", + "COMPILE_FLAGS", +}; + +struct Injection +{ + char const* Target; + char const* Property; + // Evaluated with fuzz_exe as head so the injected value is reached + // through the link closure. + char const* Reader; +}; + +Injection const kInjections[] = { + { "fuzz_dep", "INTERFACE_COMPILE_DEFINITIONS", + "$<TARGET_PROPERTY:COMPILE_DEFINITIONS>" }, + { "fuzz_dep", "INTERFACE_INCLUDE_DIRECTORIES", + "$<TARGET_PROPERTY:INCLUDE_DIRECTORIES>" }, + { "fuzz_dep", "INTERFACE_LINK_LIBRARIES", + "$<TARGET_PROPERTY:COMPILE_OPTIONS>" }, + { "fuzz_exe", "LINK_LIBRARIES", "$<TARGET_PROPERTY:LINK_OPTIONS>" }, +}; + +// Which evaluation entry point the input exercises (bits 0-1 of byte 0). +enum class Mode +{ + Evaluate, // cmGeneratorExpression::Evaluate (one-shot) + Compiled, // Parse once, evaluate for two configs, query metadata + Interpreter, // cmGeneratorExpressionInterpreter (generator property path) + Injection, // Store in a usage requirement, evaluate transitively +}; + +bool WriteFile(std::string const& path, char const* content) +{ + FILE* fp = fopen(path.c_str(), "wb"); + if (!fp) { + return false; + } + bool const ok = fputs(content, fp) >= 0; + fclose(fp); + return ok; +} + +struct Fixture +{ + cmake CMake{ cmState::Role::Project }; + cmGlobalGenerator* GG = nullptr; + cmMakefile* MF = nullptr; + cmLocalGenerator* LG = nullptr; + + bool Build(Injection const* inject, std::string const& value) + { + this->CMake.SetHomeDirectory(g_srcDir); + this->CMake.SetHomeOutputDirectory(g_binDir); + this->CMake.SetGlobalGenerator( + cm::make_unique<cmGlobalGenerator>(&this->CMake)); + this->GG = this->CMake.GetGlobalGenerator(); + + cmStateSnapshot snapshot = this->CMake.GetCurrentSnapshot(); + snapshot.GetDirectory().SetCurrentSource(g_srcDir); + snapshot.GetDirectory().SetCurrentBinary(g_binDir); + snapshot.SetDefaultDefinitions(); + + auto mf = cm::make_unique<cmMakefile>(this->GG, snapshot); + this->MF = mf.get(); + this->GG->AddMakefile(std::move(mf)); + + if (!this->MF->ReadListFileAsString(kToolchain, "fuzz_toolchain.cmake")) { + return false; + } + this->GG->SetLanguageEnabled("C", this->MF); + this->GG->SetLanguageEnabled("CXX", this->MF); + if (!this->MF->ReadListFileAsString(kProject, "CMakeLists.txt") || + cmSystemTools::GetFatalErrorOccurred()) { + return false; + } + + if (inject) { + cmTarget* target = this->MF->FindLocalNonAliasTarget(inject->Target); + if (!target) { + return false; + } + target->SetProperty(inject->Property, value); + } + + this->GG->CreateGenerationObjects(); + if (this->GG->GetLocalGenerators().empty()) { + return false; + } + this->LG = this->GG->GetLocalGenerators().front().get(); + return true; + } + + cmGeneratorTarget const* Find(char const* name) const + { + return name ? this->LG->FindGeneratorTargetToUse(name) : nullptr; + } +}; + +} // namespace + +extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) +{ + (void)argc; + (void)argv; + + char tmpl[] = "/tmp/cmake_fuzz_genex_eval_XXXXXX"; + char* dir = mkdtemp(tmpl); + g_srcDir = dir ? dir : "/tmp/cmake_fuzz_genex_eval"; + g_binDir = g_srcDir + "/build"; + cmSystemTools::MakeDirectory(g_srcDir + "/include"); + cmSystemTools::MakeDirectory(g_binDir); + WriteFile(g_srcDir + "/fuzz.c", "int fuzz_c(void) { return 0; }\n"); + WriteFile(g_srcDir + "/fuzz.cpp", "int main() { return 0; }\n"); + WriteFile(g_srcDir + "/fuzz.h", "#pragma once\n"); + + // A broken fixture would make every input a no-op, so fail loudly here + // while diagnostics are still printed. + { + Fixture fx; + bool ok = fx.Build(nullptr, std::string()) && + !cmSystemTools::GetFatalErrorOccurred(); + for (char const* name : kFixtureTargets) { + if (ok && !fx.Find(name)) { + fprintf(stderr, "fixture target missing: %s\n", name); + ok = false; + } + } + if (!ok) { + fprintf(stderr, "cmGeneratorExpressionEvalFuzzer: fixture failed\n"); + abort(); + } + } + cmSystemTools::ResetErrorOccurredFlag(); + + cmSystemTools::SetMessageCallback( + [](std::string const&, cmMessageMetadata const&) {}); + cmSystemTools::SetStdoutCallback([](std::string const&) {}); + cmSystemTools::SetStderrCallback([](std::string const&) {}); + + return 0; +} + +extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size) +{ + if (size < kHeaderSize || size > kHeaderSize + kMaxExprSize) { + return 0; + } + + uint8_t const sel0 = data[0]; + uint8_t const sel1 = data[1]; + Mode const mode = static_cast<Mode>(sel0 & 0x3u); + char const* const headName = kTargets[(sel0 >> 2) & 0x7u]; + std::string const config = kConfigs[(sel0 >> 5) & 0x3u]; + std::string const otherConfig = kConfigs[((sel0 >> 5) + 1) & 0x3u]; + bool const forBuildsystem = (sel0 & 0x80u) != 0; + std::string const language = kLanguages[sel1 & 0x7u]; + unsigned const propIndex = (sel1 >> 3) & 0x3u; + char const* const currentName = kTargets[(sel1 >> 5) & 0x7u]; + + std::string expr(reinterpret_cast<char const*>(data + kHeaderSize), + size - kHeaderSize); + + // The fatal-error flag is global and would stop the next fixture's + // listfile from running. + cmSystemTools::ResetErrorOccurredFlag(); + { + Fixture fx; + Injection const* inject = + mode == Mode::Injection ? &kInjections[propIndex] : nullptr; + if (fx.Build(inject, expr)) { + cmGeneratorTarget const* head = fx.Find(headName); + + switch (mode) { + case Mode::Evaluate: { + (void)cmGeneratorExpression::Evaluate( + std::move(expr), fx.LG, config, head, nullptr, nullptr, language); + } break; + + case Mode::Compiled: { + cmGeneratorExpression ge(fx.CMake); + std::unique_ptr<cmCompiledGeneratorExpression> cge = + ge.Parse(std::move(expr)); + cge->SetEvaluateForBuildsystem(forBuildsystem); + cmGeneratorTarget const* current = fx.Find(currentName); + + cm::GenEx::Context ctx(fx.LG, config, language); + (void)cge->Evaluate(ctx, nullptr, head, current); + (void)cge->GetTargets(); + (void)cge->GetAllTargetsSeen(); + (void)cge->GetSeenTargetProperties(); + (void)cge->GetHadContextSensitiveCondition(); + (void)cge->GetHadHeadSensitiveCondition(); + (void)cge->GetHadLinkLanguageSensitiveCondition(); + (void)cge->GetSourceSensitiveTargets(); + if (head) { + std::map<std::string, std::string> standards; + cge->GetMaxLanguageStandard(head, standards); + } + + cm::GenEx::Context otherCtx(fx.LG, otherConfig, language); + (void)cge->Evaluate(otherCtx, nullptr, head, current); + } break; + + case Mode::Interpreter: { + if (!head) { + head = fx.Find("fuzz_exe"); + } + cmGeneratorExpressionInterpreter interpreter(fx.LG, config, head, + language); + (void)interpreter.Evaluate(std::move(expr), + kInterpreterProperties[propIndex]); + } break; + + case Mode::Injection: { + Injection const& inj = kInjections[propIndex]; + (void)cmGeneratorExpression::Evaluate(inj.Reader, fx.LG, config, + fx.Find("fuzz_exe"), nullptr, + nullptr, language); + std::string direct = "$<TARGET_PROPERTY:"; + direct += inj.Target; + direct += ','; + direct += inj.Property; + direct += '>'; + (void)cmGeneratorExpression::Evaluate(std::move(direct), fx.LG, + config); + } break; + } + } + } + cmSystemTools::ResetErrorOccurredFlag(); + + return 0; +}
diff --git a/Tests/Fuzzing/cmGeneratorExpressionEvalFuzzer.options b/Tests/Fuzzing/cmGeneratorExpressionEvalFuzzer.options new file mode 100644 index 0000000..d8d6344 --- /dev/null +++ b/Tests/Fuzzing/cmGeneratorExpressionEvalFuzzer.options
@@ -0,0 +1,10 @@ +[libfuzzer] +max_len = 4098 +timeout = 30 +rss_limit_mb = 2048 + +[afl] +timeout = 30 + +[honggfuzz] +timeout = 30
diff --git a/Tests/Fuzzing/corpus/genex_eval/.gitattributes b/Tests/Fuzzing/corpus/genex_eval/.gitattributes new file mode 100644 index 0000000..a304afc --- /dev/null +++ b/Tests/Fuzzing/corpus/genex_eval/.gitattributes
@@ -0,0 +1 @@ +*.bin binary -text -whitespace
diff --git a/Tests/Fuzzing/corpus/genex_eval/compiled_files.bin b/Tests/Fuzzing/corpus/genex_eval/compiled_files.bin new file mode 100644 index 0000000..31d1e4b --- /dev/null +++ b/Tests/Fuzzing/corpus/genex_eval/compiled_files.bin
@@ -0,0 +1 @@ +ÅA$<TARGET_FILE:fuzz_static>;$<TARGET_LINKER_FILE_NAME:Fuzz::shared>;$<TARGET_SONAME_FILE:Fuzz::shared>;$<TARGET_OBJECTS:fuzz_obj>;$<TARGET_FILE_DIR:fuzz_exe> \ No newline at end of file
diff --git a/Tests/Fuzzing/corpus/genex_eval/compiled_genex_eval.bin b/Tests/Fuzzing/corpus/genex_eval/compiled_genex_eval.bin new file mode 100644 index 0000000..63744e8 --- /dev/null +++ b/Tests/Fuzzing/corpus/genex_eval/compiled_genex_eval.bin
@@ -0,0 +1 @@ +i$<TARGET_PROPERTY:fuzz_imported_static,IMPORTED_LOCATION>$<TARGET_GENEX_EVAL:fuzz_iface,$<TARGET_PROPERTY:fuzz_iface,INTERFACE_FUZZ_CUSTOM>>$<GENEX_EVAL:$<CONFIG>> \ No newline at end of file
diff --git a/Tests/Fuzzing/corpus/genex_eval/compiled_sources.bin b/Tests/Fuzzing/corpus/genex_eval/compiled_sources.bin new file mode 100644 index 0000000..782711a --- /dev/null +++ b/Tests/Fuzzing/corpus/genex_eval/compiled_sources.bin
@@ -0,0 +1 @@ +¥a$<SOURCE_PROPERTY:fuzz.c,COMPILE_DEFINITIONS>$<SOURCE_EXISTS:fuzz.c>$<FILE_SET_EXISTS:HEADERS,TARGET:fuzz_iface>$<FILE_SET_PROPERTY:HEADERS,TARGET:fuzz_iface,HEADER_SET> \ No newline at end of file
diff --git a/Tests/Fuzzing/corpus/genex_eval/direct_compat.bin b/Tests/Fuzzing/corpus/genex_eval/direct_compat.bin new file mode 100644 index 0000000..c92234e --- /dev/null +++ b/Tests/Fuzzing/corpus/genex_eval/direct_compat.bin Binary files differ
diff --git a/Tests/Fuzzing/corpus/genex_eval/direct_compiler.bin b/Tests/Fuzzing/corpus/genex_eval/direct_compiler.bin new file mode 100644 index 0000000..f0d97df --- /dev/null +++ b/Tests/Fuzzing/corpus/genex_eval/direct_compiler.bin
@@ -0,0 +1 @@ +$$<COMPILE_LANG_AND_ID:CXX,GNU>$<COMPILE_FEATURES:cxx_std_17>$<VERSION_GREATER:$<CXX_COMPILER_VERSION>,12>$<PLATFORM_ID:Linux> \ No newline at end of file
diff --git a/Tests/Fuzzing/corpus/genex_eval/direct_head_defs.bin b/Tests/Fuzzing/corpus/genex_eval/direct_head_defs.bin new file mode 100644 index 0000000..fd1ecae --- /dev/null +++ b/Tests/Fuzzing/corpus/genex_eval/direct_head_defs.bin
@@ -0,0 +1 @@ +$$<TARGET_PROPERTY:COMPILE_DEFINITIONS> \ No newline at end of file
diff --git a/Tests/Fuzzing/corpus/genex_eval/direct_logic.bin b/Tests/Fuzzing/corpus/genex_eval/direct_logic.bin new file mode 100644 index 0000000..cb11f04 --- /dev/null +++ b/Tests/Fuzzing/corpus/genex_eval/direct_logic.bin Binary files differ
diff --git a/Tests/Fuzzing/corpus/genex_eval/direct_string_list_path.bin b/Tests/Fuzzing/corpus/genex_eval/direct_string_list_path.bin new file mode 100644 index 0000000..7842044 --- /dev/null +++ b/Tests/Fuzzing/corpus/genex_eval/direct_string_list_path.bin Binary files differ
diff --git a/Tests/Fuzzing/corpus/genex_eval/direct_target_queries.bin b/Tests/Fuzzing/corpus/genex_eval/direct_target_queries.bin new file mode 100644 index 0000000..c837819 --- /dev/null +++ b/Tests/Fuzzing/corpus/genex_eval/direct_target_queries.bin Binary files differ
diff --git a/Tests/Fuzzing/corpus/genex_eval/inject_defs.bin b/Tests/Fuzzing/corpus/genex_eval/inject_defs.bin new file mode 100644 index 0000000..1aeec52 --- /dev/null +++ b/Tests/Fuzzing/corpus/genex_eval/inject_defs.bin
@@ -0,0 +1 @@ +#INJ=1;$<$<CONFIG:Debug>:INJ_DEBUG>;$<TARGET_PROPERTY:fuzz_iface,INTERFACE_FUZZ_STRING> \ No newline at end of file
diff --git a/Tests/Fuzzing/corpus/genex_eval/inject_iface_link.bin b/Tests/Fuzzing/corpus/genex_eval/inject_iface_link.bin new file mode 100644 index 0000000..0d71b9a --- /dev/null +++ b/Tests/Fuzzing/corpus/genex_eval/inject_iface_link.bin
@@ -0,0 +1 @@ +#fuzz_iface;$<LINK_ONLY:Fuzz::shared>;$<COMPILE_ONLY:fuzz_imported_static>;-lm \ No newline at end of file
diff --git a/Tests/Fuzzing/corpus/genex_eval/inject_includes.bin b/Tests/Fuzzing/corpus/genex_eval/inject_includes.bin new file mode 100644 index 0000000..4f2c4c4 --- /dev/null +++ b/Tests/Fuzzing/corpus/genex_eval/inject_includes.bin
@@ -0,0 +1 @@ +C/opt/inj/include;$<BUILD_INTERFACE:/opt/inj/build>;$<INSTALL_INTERFACE:inc> \ No newline at end of file
diff --git a/Tests/Fuzzing/corpus/genex_eval/inject_link_libs.bin b/Tests/Fuzzing/corpus/genex_eval/inject_link_libs.bin new file mode 100644 index 0000000..4fb7a2e --- /dev/null +++ b/Tests/Fuzzing/corpus/genex_eval/inject_link_libs.bin
@@ -0,0 +1 @@ +#Fuzz::static;$<LINK_LIBRARY:WHOLE_ARCHIVE,fuzz_imported_static>;$<LINK_GROUP:RESCAN,fuzz_static,fuzz_imported_static> \ No newline at end of file
diff --git a/Tests/Fuzzing/corpus/genex_eval/interp_defs.bin b/Tests/Fuzzing/corpus/genex_eval/interp_defs.bin new file mode 100644 index 0000000..35024de --- /dev/null +++ b/Tests/Fuzzing/corpus/genex_eval/interp_defs.bin
@@ -0,0 +1 @@ +& $<TARGET_PROPERTY:fuzz_iface,INTERFACE_COMPILE_DEFINITIONS>;LOCAL=$<CONFIG> \ No newline at end of file
diff --git a/Tests/Fuzzing/corpus/genex_eval/interp_opts.bin b/Tests/Fuzzing/corpus/genex_eval/interp_opts.bin new file mode 100644 index 0000000..6623fc6 --- /dev/null +++ b/Tests/Fuzzing/corpus/genex_eval/interp_opts.bin
@@ -0,0 +1 @@ +J$<$<COMPILE_LANGUAGE:C>:-O2>;$<TARGET_PROPERTY:COMPILE_OPTIONS> \ No newline at end of file
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 542a049..5d10fbf 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt
@@ -1424,9 +1424,12 @@ list(APPEND CompilerLauncher_ARGS -DCMake_TEST_ISPC=${CMake_TEST_ISPC}) list(APPEND ToolchainWrappers_ARGS -DCMake_TEST_ISPC=${CMake_TEST_ISPC}) endif() + if(DEFINED CMake_TEST_Rust) + list(APPEND CompilerLauncher_ARGS -DCMake_TEST_Rust=${CMake_TEST_Rust}) + endif() add_RunCMake_test(CompilerLauncher) set_property(TEST RunCMake.CompilerLauncher APPEND - PROPERTY LABELS "CUDA" "HIP" "ISPC" "Fortran" "SYCL") + PROPERTY LABELS "CUDA" "HIP" "ISPC" "Fortran" "SYCL" "Rust") add_RunCMake_test(LinkerLauncher) set_property(TEST RunCMake.LinkerLauncher APPEND PROPERTY LABELS "CUDA" "HIP" "Fortran" "SYCL") @@ -1667,7 +1670,8 @@ add_RunCMake_test(PrecompileHeaders -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID} -DCMAKE_C_SIMULATE_ID=${CMAKE_C_SIMULATE_ID} - -DCMAKE_C_COMPILER_VERSION=${CMAKE_C_COMPILER_VERSION}) + -DCMAKE_C_COMPILER_VERSION=${CMAKE_C_COMPILER_VERSION} + -DMSVC_VERSION=${MSVC_VERSION}) add_RunCMake_test(PrecompileHeaders-Reuse -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}) # This test can take a long time due to the number of test cases.
diff --git a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake index b844678..3eac4a5 100644 --- a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake
@@ -170,6 +170,7 @@ run_cmake_presets(InvalidPresetBinaryDir) run_cmake_presets(InvalidVariables) run_cmake_presets(VariableNotObject) +run_cmake_presets(VariableNamedCacheVariables) run_cmake_presets(NoVariableValue) run_cmake_presets(InvalidVariableValue) run_cmake_presets(ExtraRootField)
diff --git a/Tests/RunCMake/CMakePresets/VariableNamedCacheVariables-result.txt b/Tests/RunCMake/CMakePresets/VariableNamedCacheVariables-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/VariableNamedCacheVariables-result.txt
@@ -0,0 +1 @@ +1
diff --git a/Tests/RunCMake/CMakePresets/VariableNamedCacheVariables-stderr.txt b/Tests/RunCMake/CMakePresets/VariableNamedCacheVariables-stderr.txt new file mode 100644 index 0000000..757dad5 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/VariableNamedCacheVariables-stderr.txt
@@ -0,0 +1,5 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/VariableNamedCacheVariables: +CMakePresets\.json:9: Invalid CMake variable "cacheVariables" for preset "VariableNamedCacheVariables" + "cacheVariables": \[\] + \^$
diff --git a/Tests/RunCMake/CMakePresets/VariableNamedCacheVariables.json.in b/Tests/RunCMake/CMakePresets/VariableNamedCacheVariables.json.in new file mode 100644 index 0000000..3d6270e --- /dev/null +++ b/Tests/RunCMake/CMakePresets/VariableNamedCacheVariables.json.in
@@ -0,0 +1,13 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "VariableNamedCacheVariables", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "cacheVariables": [] + } + } + ] +}
diff --git a/Tests/RunCMake/CMakePresetsPackage/InvalidVariable-package-package-variable-result.txt b/Tests/RunCMake/CMakePresetsPackage/InvalidVariable-package-package-variable-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresetsPackage/InvalidVariable-package-package-variable-result.txt
@@ -0,0 +1 @@ +1
diff --git a/Tests/RunCMake/CMakePresetsPackage/InvalidVariable-package-package-variable-stderr.txt b/Tests/RunCMake/CMakePresetsPackage/InvalidVariable-package-package-variable-stderr.txt new file mode 100644 index 0000000..8659f3d --- /dev/null +++ b/Tests/RunCMake/CMakePresetsPackage/InvalidVariable-package-package-variable-stderr.txt
@@ -0,0 +1,5 @@ +^CPack Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresetsPackage/InvalidVariable: +CMakePresets\.json:15: Invalid CMake variable "VAR" for preset "package-variable" + "VAR": \[\] + \^$
diff --git a/Tests/RunCMake/CMakePresetsPackage/InvalidVariable.json.in b/Tests/RunCMake/CMakePresetsPackage/InvalidVariable.json.in new file mode 100644 index 0000000..e970363 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsPackage/InvalidVariable.json.in
@@ -0,0 +1,19 @@ +{ + "version": 6, + "configurePresets": [ + { + "name": "default", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ], + "packagePresets": [ + { + "name": "package-variable", + "configurePreset": "default", + "variables": { + "VAR": [] + } + } + ] +}
diff --git a/Tests/RunCMake/CMakePresetsPackage/InvalidVariableNamedCacheVariables-package-package-cache-variables-result.txt b/Tests/RunCMake/CMakePresetsPackage/InvalidVariableNamedCacheVariables-package-package-cache-variables-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresetsPackage/InvalidVariableNamedCacheVariables-package-package-cache-variables-result.txt
@@ -0,0 +1 @@ +1
diff --git a/Tests/RunCMake/CMakePresetsPackage/InvalidVariableNamedCacheVariables-package-package-cache-variables-stderr.txt b/Tests/RunCMake/CMakePresetsPackage/InvalidVariableNamedCacheVariables-package-package-cache-variables-stderr.txt new file mode 100644 index 0000000..388db53 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsPackage/InvalidVariableNamedCacheVariables-package-package-cache-variables-stderr.txt
@@ -0,0 +1,5 @@ +^CPack Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresetsPackage/InvalidVariableNamedCacheVariables: +CMakePresets\.json:15: Invalid CMake variable "cacheVariables" for preset "package-cache-variables" + "cacheVariables": false + \^$
diff --git a/Tests/RunCMake/CMakePresetsPackage/InvalidVariableNamedCacheVariables.json.in b/Tests/RunCMake/CMakePresetsPackage/InvalidVariableNamedCacheVariables.json.in new file mode 100644 index 0000000..5ea7125 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsPackage/InvalidVariableNamedCacheVariables.json.in
@@ -0,0 +1,19 @@ +{ + "version": 6, + "configurePresets": [ + { + "name": "default", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ], + "packagePresets": [ + { + "name": "package-cache-variables", + "configurePreset": "default", + "variables": { + "cacheVariables": false + } + } + ] +}
diff --git a/Tests/RunCMake/CMakePresetsPackage/InvalidVariables-package-package-variables-result.txt b/Tests/RunCMake/CMakePresetsPackage/InvalidVariables-package-package-variables-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresetsPackage/InvalidVariables-package-package-variables-result.txt
@@ -0,0 +1 @@ +1
diff --git a/Tests/RunCMake/CMakePresetsPackage/InvalidVariables-package-package-variables-stderr.txt b/Tests/RunCMake/CMakePresetsPackage/InvalidVariables-package-package-variables-stderr.txt new file mode 100644 index 0000000..9065479 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsPackage/InvalidVariables-package-package-variables-stderr.txt
@@ -0,0 +1,5 @@ +^CPack Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresetsPackage/InvalidVariables: +CMakePresets\.json:14: Invalid CMake variable for preset "package-variables" + "variables": \[\] + \^$
diff --git a/Tests/RunCMake/CMakePresetsPackage/InvalidVariables.json.in b/Tests/RunCMake/CMakePresetsPackage/InvalidVariables.json.in new file mode 100644 index 0000000..d4fff00 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsPackage/InvalidVariables.json.in
@@ -0,0 +1,17 @@ +{ + "version": 6, + "configurePresets": [ + { + "name": "default", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ], + "packagePresets": [ + { + "name": "package-variables", + "configurePreset": "default", + "variables": [] + } + ] +}
diff --git a/Tests/RunCMake/CMakePresetsPackage/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresetsPackage/RunCMakeTest.cmake index 330cd4c..6ac2881 100644 --- a/Tests/RunCMake/CMakePresetsPackage/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMakePresetsPackage/RunCMakeTest.cmake
@@ -124,3 +124,7 @@ set(CMakePresetsPackage_NO_BUILD 1) run_cmake_package_presets(InvalidConfigurePreset "" "" "package-release") run_cmake_package_presets(ConfigurePresetUnreachable "" "" "package-child") +set(CMakePresets_SCHEMA_EXPECTED_RESULT 1) +run_cmake_package_presets(InvalidVariable "" "" "package-variable") +run_cmake_package_presets(InvalidVariableNamedCacheVariables "" "" "package-cache-variables") +run_cmake_package_presets(InvalidVariables "" "" "package-variables")
diff --git a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake index d0f42e6..0cc361c 100644 --- a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
@@ -1379,3 +1379,26 @@ run_TestMaxWidthLong(MaxWidthLongUnset "") run_TestMaxWidthLong(MaxWidthLong70 "-W 70") run_TestMaxWidthLong(MaxWidthLong30 "-W 30") + +# Test --output-dir. This project only calls enable_testing(), so nothing +# creates the default "Testing" directory under the build tree. +block() + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SetOutputDir-build) + set(OUTPUT_DIR "${RunCMake_TEST_BINARY_DIR}/CLIOutputDir") + run_cmake(SetOutputDir-cmake) + set(RunCMake_TEST_NO_CLEAN 1) + run_cmake_command(SetOutputDir-ctest + ${CMAKE_CTEST_COMMAND} -C Debug --output-dir ${OUTPUT_DIR}) +endblock() + +# Test --output-dir. This project calls include(CTest), which creates the +# default "Testing" directory at configure time, so check that it is left +# unused rather than absent. +block() + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SetOutputDirConfigured-build) + set(OUTPUT_DIR "${RunCMake_TEST_BINARY_DIR}/CLIOutputDir") + run_cmake(SetOutputDirConfigured-cmake) + set(RunCMake_TEST_NO_CLEAN 1) + run_cmake_command(SetOutputDirConfigured-ctest + ${CMAKE_CTEST_COMMAND} -C Debug --output-dir ${OUTPUT_DIR}) +endblock()
diff --git a/Tests/RunCMake/CTestCommandLine/SetOutputDir-cmake.cmake b/Tests/RunCMake/CTestCommandLine/SetOutputDir-cmake.cmake new file mode 100644 index 0000000..e252f0f --- /dev/null +++ b/Tests/RunCMake/CTestCommandLine/SetOutputDir-cmake.cmake
@@ -0,0 +1,2 @@ +enable_testing() +add_test(NAME test1 COMMAND "${CMAKE_COMMAND}" -E true)
diff --git a/Tests/RunCMake/CTestCommandLine/SetOutputDir-ctest-check.cmake b/Tests/RunCMake/CTestCommandLine/SetOutputDir-ctest-check.cmake new file mode 100644 index 0000000..97b8786 --- /dev/null +++ b/Tests/RunCMake/CTestCommandLine/SetOutputDir-ctest-check.cmake
@@ -0,0 +1,14 @@ +# This project only calls enable_testing(), so the default output +# directory should never be created at all. +set(DEFAULT_OUTPUT_DIR "${RunCMake_TEST_BINARY_DIR}/Testing") + +if(EXISTS "${DEFAULT_OUTPUT_DIR}") + string(APPEND RunCMake_TEST_FAILED + "Default output directory should not exist:\n ${DEFAULT_OUTPUT_DIR}\n") +elseif(NOT EXISTS "${OUTPUT_DIR}") + set(RunCMake_TEST_FAILED + "Expected output directory ${OUTPUT_DIR} does not exist.") +elseif(NOT EXISTS "${OUTPUT_DIR}/Temporary/LastTest.log") + set(RunCMake_TEST_FAILED + "Expected ${OUTPUT_DIR}/Temporary/LastTest.log to exist.") +endif()
diff --git a/Tests/RunCMake/CTestCommandLine/SetOutputDirConfigured-cmake.cmake b/Tests/RunCMake/CTestCommandLine/SetOutputDirConfigured-cmake.cmake new file mode 100644 index 0000000..7ba0056 --- /dev/null +++ b/Tests/RunCMake/CTestCommandLine/SetOutputDirConfigured-cmake.cmake
@@ -0,0 +1,2 @@ +include(CTest) +add_test(NAME test1 COMMAND "${CMAKE_COMMAND}" -E true)
diff --git a/Tests/RunCMake/CTestCommandLine/SetOutputDirConfigured-ctest-check.cmake b/Tests/RunCMake/CTestCommandLine/SetOutputDirConfigured-ctest-check.cmake new file mode 100644 index 0000000..8a101b8 --- /dev/null +++ b/Tests/RunCMake/CTestCommandLine/SetOutputDirConfigured-ctest-check.cmake
@@ -0,0 +1,27 @@ +# The project calls include(CTest), which creates the default output +# directory at configure time. It must still be left unused. +set(DEFAULT_OUTPUT_DIR "${RunCMake_TEST_BINARY_DIR}/Testing") + +if(NOT EXISTS "${DEFAULT_OUTPUT_DIR}") + set(RunCMake_TEST_FAILED + "Expected include(CTest) to create ${DEFAULT_OUTPUT_DIR}.") + return() +endif() + +file(GLOB_RECURSE DEFAULT_OUTPUT_FILES "${DEFAULT_OUTPUT_DIR}/*") +if(DEFAULT_OUTPUT_FILES) + string(REPLACE ";" "\n " DEFAULT_OUTPUT_FILES "${DEFAULT_OUTPUT_FILES}") + string(APPEND RunCMake_TEST_FAILED + "Default output directory should not have been used:\n" + " ${DEFAULT_OUTPUT_DIR}\n" + "It contains:\n ${DEFAULT_OUTPUT_FILES}\n") + return() +endif() + +if(NOT EXISTS "${OUTPUT_DIR}") + set(RunCMake_TEST_FAILED + "Expected output directory ${OUTPUT_DIR} does not exist.") +elseif(NOT EXISTS "${OUTPUT_DIR}/Temporary/LastTest.log") + set(RunCMake_TEST_FAILED + "Expected ${OUTPUT_DIR}/Temporary/LastTest.log to exist.") +endif()
diff --git a/Tests/RunCMake/CXXModulesCompile/RunCMakeTest.cmake b/Tests/RunCMake/CXXModulesCompile/RunCMakeTest.cmake index 9383733..a508c7e 100644 --- a/Tests/RunCMake/CXXModulesCompile/RunCMakeTest.cmake +++ b/Tests/RunCMake/CXXModulesCompile/RunCMakeTest.cmake
@@ -233,6 +233,7 @@ run_cxx_module_test(imp-from-object) run_cxx_module_test(circular) run_cxx_module_test(try-compile) + run_cxx_module_test(try-compile-ext) run_cxx_module_test(try-run) unset(RunCMake_CXXModules_NO_TEST) run_cxx_module_test(same-src-name)
diff --git a/Tests/RunCMake/CXXModulesCompile/try-compile-ext/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/try-compile-ext/CMakeLists.txt new file mode 100644 index 0000000..c7bdb67 --- /dev/null +++ b/Tests/RunCMake/CXXModulesCompile/try-compile-ext/CMakeLists.txt
@@ -0,0 +1,37 @@ +cmake_minimum_required(VERSION 3.24...3.28) +project(cxx_modules_try_compile_ext CXX) + +include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake") + +# The module sources reside outside of the project's source directory. +set(srcdir "${CMAKE_CURRENT_LIST_DIR}/../try-compile") + +set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY") +try_compile(can_use_modules_sources + SOURCES_TYPE CXX_MODULE + SOURCES + "${srcdir}/importable.cxx" + SOURCES_TYPE NORMAL + SOURCES + "${srcdir}/use_importable.cxx" + CXX_STANDARD 20) + +if (NOT can_use_modules_sources) + message(FATAL_ERROR + "`try_compile` could not compile module sources given by `SOURCES`.") +endif () + +try_compile(can_use_modules_copied + SOURCES_TYPE CXX_MODULE + SOURCE_FROM_FILE + importable.cxx "${srcdir}/importable.cxx" + SOURCES_TYPE NORMAL + SOURCE_FROM_FILE + use_importable.cxx "${srcdir}/use_importable.cxx" + CXX_STANDARD 20) + +if (NOT can_use_modules_copied) + message(FATAL_ERROR + "`try_compile` could not compile module sources given by " + "`SOURCE_FROM_FILE`.") +endif ()
diff --git a/Tests/RunCMake/CommandLine/E_remove-check.cmake b/Tests/RunCMake/CommandLine/E_remove-check.cmake new file mode 100644 index 0000000..ddcf268 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_remove-check.cmake
@@ -0,0 +1,3 @@ +if(EXISTS ${outfile}) + set(RunCMake_TEST_FAILED "${outfile} was not removed") +endif()
diff --git a/Tests/RunCMake/CommandLine/E_remove-stderr.txt b/Tests/RunCMake/CommandLine/E_remove-stderr.txt new file mode 100644 index 0000000..63aec2d --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_remove-stderr.txt
@@ -0,0 +1,3 @@ +^CMake Warning \(deprecated\): + The 'cmake -E remove' command has been superseded\. Use 'cmake -E rm' + instead\.$
diff --git a/Tests/RunCMake/CommandLine/E_remove_directory-directory-with-parent-stderr.txt b/Tests/RunCMake/CommandLine/E_remove_directory-directory-with-parent-stderr.txt index e69de29..2c15178 100644 --- a/Tests/RunCMake/CommandLine/E_remove_directory-directory-with-parent-stderr.txt +++ b/Tests/RunCMake/CommandLine/E_remove_directory-directory-with-parent-stderr.txt
@@ -0,0 +1,3 @@ +^CMake Warning \(deprecated\): + The 'cmake -E remove_directory' command has been superseded\. Use 'cmake -E + rm' instead\.$
diff --git a/Tests/RunCMake/CommandLine/E_remove_directory-symlink-dir-stderr.txt b/Tests/RunCMake/CommandLine/E_remove_directory-symlink-dir-stderr.txt index e69de29..2c15178 100644 --- a/Tests/RunCMake/CommandLine/E_remove_directory-symlink-dir-stderr.txt +++ b/Tests/RunCMake/CommandLine/E_remove_directory-symlink-dir-stderr.txt
@@ -0,0 +1,3 @@ +^CMake Warning \(deprecated\): + The 'cmake -E remove_directory' command has been superseded\. Use 'cmake -E + rm' instead\.$
diff --git a/Tests/RunCMake/CommandLine/E_remove_directory-symlink-file-stderr.txt b/Tests/RunCMake/CommandLine/E_remove_directory-symlink-file-stderr.txt index e69de29..2c15178 100644 --- a/Tests/RunCMake/CommandLine/E_remove_directory-symlink-file-stderr.txt +++ b/Tests/RunCMake/CommandLine/E_remove_directory-symlink-file-stderr.txt
@@ -0,0 +1,3 @@ +^CMake Warning \(deprecated\): + The 'cmake -E remove_directory' command has been superseded\. Use 'cmake -E + rm' instead\.$
diff --git a/Tests/RunCMake/CommandLine/E_remove_directory-three-directories-stderr.txt b/Tests/RunCMake/CommandLine/E_remove_directory-three-directories-stderr.txt index e69de29..2c15178 100644 --- a/Tests/RunCMake/CommandLine/E_remove_directory-three-directories-stderr.txt +++ b/Tests/RunCMake/CommandLine/E_remove_directory-three-directories-stderr.txt
@@ -0,0 +1,3 @@ +^CMake Warning \(deprecated\): + The 'cmake -E remove_directory' command has been superseded\. Use 'cmake -E + rm' instead\.$
diff --git a/Tests/RunCMake/CommandLine/E_remove_directory-two-directories-and-file-stderr.txt b/Tests/RunCMake/CommandLine/E_remove_directory-two-directories-and-file-stderr.txt index e69de29..2c15178 100644 --- a/Tests/RunCMake/CommandLine/E_remove_directory-two-directories-and-file-stderr.txt +++ b/Tests/RunCMake/CommandLine/E_remove_directory-two-directories-and-file-stderr.txt
@@ -0,0 +1,3 @@ +^CMake Warning \(deprecated\): + The 'cmake -E remove_directory' command has been superseded\. Use 'cmake -E + rm' instead\.$
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake index bc5d07f..8dd8573 100644 --- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -792,6 +792,16 @@ unset(out) unset(outfile) +set(out ${RunCMake_BINARY_DIR}/remove_output) +set(outfile ${out}/file_for_test.txt) +file(REMOVE_RECURSE "${out}") +file(MAKE_DIRECTORY ${out}) +file(WRITE ${outfile} "") +run_cmake_command(E_remove ${CMAKE_COMMAND} -E remove ${outfile}) + +unset(out) +unset(outfile) + set(out ${RunCMake_BINARY_DIR}/rm_tests) file(REMOVE_RECURSE "${out}") file(MAKE_DIRECTORY ${out}) @@ -1290,6 +1300,14 @@ unset(ENV{CMAKE_CONFIG_DIR}) unset(ENV{XDG_CONFIG_HOME}) run_cmake_command(${config_dir_test} ${CMAKE_COMMAND} "--print-config-dir") + if(WIN32) + set(localappdata "$ENV{LOCALAPPDATA}") + set(ENV{LOCALAPPDATA} "C:/cmake-localappdata") + run_cmake_command(print-config-dir-win-localappdata ${CMAKE_COMMAND} "--print-config-dir") + set(ENV{LOCALAPPDATA} "relative") + run_cmake_command(print-config-dir-win-localappdata-relative ${CMAKE_COMMAND} "--print-config-dir") + set(ENV{LOCALAPPDATA} "${localappdata}") + endif() endif() set(ENV{CMAKE_CONFIG_DIR} cmake_config_dir) run_cmake_command(print-config-dir-env ${CMAKE_COMMAND} "--print-config-dir")
diff --git a/Tests/RunCMake/CommandLine/print-config-dir-win-localappdata-relative-stdout.txt b/Tests/RunCMake/CommandLine/print-config-dir-win-localappdata-relative-stdout.txt new file mode 100644 index 0000000..9df0671 --- /dev/null +++ b/Tests/RunCMake/CommandLine/print-config-dir-win-localappdata-relative-stdout.txt
@@ -0,0 +1 @@ +.*AppData\\Local\\CMake$
diff --git a/Tests/RunCMake/CommandLine/print-config-dir-win-localappdata-stdout.txt b/Tests/RunCMake/CommandLine/print-config-dir-win-localappdata-stdout.txt new file mode 100644 index 0000000..86c0da0 --- /dev/null +++ b/Tests/RunCMake/CommandLine/print-config-dir-win-localappdata-stdout.txt
@@ -0,0 +1 @@ +^C:\\cmake-localappdata\\CMake$
diff --git a/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake b/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake index 7c810c2..23f0192 100644 --- a/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake +++ b/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake
@@ -1,6 +1,6 @@ include(RunCMake) -if(CMake_TEST_SYCL) +if(CMake_TEST_SYCL OR CMake_TEST_Rust) list(APPEND RunCMake_TEST_OPTIONS -Wno-experimental) endif() @@ -49,6 +49,9 @@ if(CMake_TEST_OBJC) list(APPEND langs OBJC OBJCXX) endif() +if(CMake_TEST_Rust) + list(APPEND langs Rust) +endif() foreach(lang ${langs}) run_compiler_launcher(${lang})
diff --git a/Tests/RunCMake/CompilerLauncher/Rust-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/Rust-Build-stdout.txt new file mode 100644 index 0000000..3313e31 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/Rust-Build-stdout.txt
@@ -0,0 +1 @@ +.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/CompilerLauncher/Rust-common.cmake b/Tests/RunCMake/CompilerLauncher/Rust-common.cmake new file mode 100644 index 0000000..b4af205 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/Rust-common.cmake
@@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 4.2) + +set(CMAKE_EXPERIMENTAL_RUST "628f8f9f-d7dc-4a06-9aaf-d4ede4426ddf") + +enable_language(Rust) +set(CMAKE_VERBOSE_MAKEFILE TRUE) +add_library(main OBJECT main.rs)
diff --git a/Tests/RunCMake/CompilerLauncher/Rust-env-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/Rust-env-Build-stdout.txt new file mode 100644 index 0000000..8148c4f --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/Rust-env-Build-stdout.txt
@@ -0,0 +1 @@ +.*-E env USED_LAUNCHER=1 TARGET_NAME=main LANGUAGE=Rust.*
diff --git a/Tests/RunCMake/CompilerLauncher/Rust-env.cmake b/Tests/RunCMake/CompilerLauncher/Rust-env.cmake new file mode 100644 index 0000000..378b941 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/Rust-env.cmake
@@ -0,0 +1 @@ +include(Rust-common.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/Rust-launch-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/Rust-launch-Build-stdout.txt new file mode 100644 index 0000000..3313e31 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/Rust-launch-Build-stdout.txt
@@ -0,0 +1 @@ +.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/CompilerLauncher/Rust-launch-env-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/Rust-launch-env-Build-stdout.txt new file mode 100644 index 0000000..8148c4f --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/Rust-launch-env-Build-stdout.txt
@@ -0,0 +1 @@ +.*-E env USED_LAUNCHER=1 TARGET_NAME=main LANGUAGE=Rust.*
diff --git a/Tests/RunCMake/CompilerLauncher/Rust-launch-env.cmake b/Tests/RunCMake/CompilerLauncher/Rust-launch-env.cmake new file mode 100644 index 0000000..21b995f --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/Rust-launch-env.cmake
@@ -0,0 +1,3 @@ +set(CTEST_USE_LAUNCHERS 1) +include(CTestUseLaunchers) +include(Rust-env.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/Rust-launch.cmake b/Tests/RunCMake/CompilerLauncher/Rust-launch.cmake new file mode 100644 index 0000000..54df59d --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/Rust-launch.cmake
@@ -0,0 +1,3 @@ +set(CTEST_USE_LAUNCHERS 1) +include(CTestUseLaunchers) +include(Rust.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/Rust.cmake b/Tests/RunCMake/CompilerLauncher/Rust.cmake new file mode 100644 index 0000000..176a83c --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/Rust.cmake
@@ -0,0 +1,2 @@ +set(CMAKE_Rust_COMPILER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1") +include(Rust-common.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/main.rs b/Tests/RunCMake/CompilerLauncher/main.rs new file mode 100644 index 0000000..f328e4d --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/main.rs
@@ -0,0 +1 @@ +fn main() {}
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_MODVERSION_VARIABLE.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_MODVERSION_VARIABLE.cmake new file mode 100644 index 0000000..025797a --- /dev/null +++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_MODVERSION_VARIABLE.cmake
@@ -0,0 +1,59 @@ +set(PKG_CONFIG_EXECUTABLE "${CMAKE_COMMAND}") +set(PKG_CONFIG_ARGN "-P;${CMAKE_CURRENT_SOURCE_DIR}/pkg-config-static-requery.cmake;--") +set(ENV{FAKE_PKG_CONFIG_FLAVOR} "${flavor}") +find_package(PkgConfig REQUIRED) + +set(log "${CMAKE_CURRENT_BINARY_DIR}/pkg-config.log") +set(ENV{FAKE_PKG_CONFIG_LOG} "${log}") + +function(check var expect) + if(NOT "${${var}}" STREQUAL "${expect}") + message(SEND_ERROR "Expected ${var} to be \"${expect}\", got \"${${var}}\"") + endif() +endfunction() + +# Check whether the prefix was queried separately from --modversion +function(check_prefix_query expect) + file(STRINGS "${log}" calls REGEX " --variable=prefix") + list(FILTER calls EXCLUDE REGEX " --modversion") + list(LENGTH calls count) + if(NOT count EQUAL expect) + message(SEND_ERROR "Expected ${expect} separate prefix queries, got ${count}") + endif() + file(REMOVE "${log}") +endfunction() + +if(flavor STREQUAL "pkgconf") + set(separate 0) +else() + set(separate 1) +endif() + +pkg_check_modules(NORMAL REQUIRED normal) +check(NORMAL_FOUND 1) +check(NORMAL_VERSION "1.2.3") +check(NORMAL_PREFIX "/fake/normal") +check(NORMAL_INCLUDEDIR "/fake/normal/include") +check(NORMAL_LIBDIR "/fake/normal/lib") +check(NORMAL_LIBRARIES "normal") +check_prefix_query(${separate}) + +pkg_check_modules(CONSTRAINT REQUIRED "normal>=1.0") +check(CONSTRAINT_VERSION "1.2.3") +check(CONSTRAINT_PREFIX "/fake/normal") +check_prefix_query(${separate}) + +pkg_check_modules(EMPTY REQUIRED emptyversion) +check(EMPTY_FOUND 1) +check(EMPTY_VERSION "") +check(EMPTY_PREFIX "/fake/emptyversion") +check(EMPTY_LIBRARIES "emptyversion") +check_prefix_query(${separate}) + +pkg_check_modules(BOTH REQUIRED normal emptyversion) +check(BOTH_normal_VERSION "1.2.3") +check(BOTH_normal_PREFIX "/fake/normal") +check(BOTH_emptyversion_VERSION "") +check(BOTH_emptyversion_PREFIX "/fake/emptyversion") +math(EXPR separate_both "${separate} * 2") +check_prefix_query(${separate_both})
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_STATIC_REQUERY.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_STATIC_REQUERY.cmake index d790867..d8913c1 100644 --- a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_STATIC_REQUERY.cmake +++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_STATIC_REQUERY.cmake
@@ -1,11 +1,11 @@ -if(WIN32) - set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}/pkg-config-static-requery.bat") -else() - set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}/pkg-config-static-requery.sh") -endif() +set(PKG_CONFIG_EXECUTABLE "${CMAKE_COMMAND}") +set(PKG_CONFIG_ARGN "-P;${CMAKE_CURRENT_SOURCE_DIR}/pkg-config-static-requery.cmake;--") find_package(PkgConfig REQUIRED) pkg_check_modules(P REQUIRED good) +if(NOT P_PREFIX STREQUAL "/fake;prefix") + message(FATAL_ERROR "Expected semicolon in prefix, got: ${P_PREFIX}") +endif() if(NOT P_STATIC_LIBRARIES STREQUAL "good;dep") message(FATAL_ERROR "Expected static libraries from first query, got: ${P_STATIC_LIBRARIES}")
diff --git a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake index ce10861..c9d7c1f 100644 --- a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake +++ b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
@@ -19,6 +19,12 @@ endif() run_cmake(FindPkgConfig_extract_frameworks) +foreach(flavor IN ITEMS pkg-config pkgconf) + set(RunCMake_TEST_VARIANT_DESCRIPTION "-${flavor}") + run_cmake_with_options(FindPkgConfig_MODVERSION_VARIABLE -Dflavor=${flavor}) +endforeach() +unset(RunCMake_TEST_VARIANT_DESCRIPTION) +run_cmake(FindPkgConfig_STATIC_REQUERY) if(APPLE) run_cmake(FindPkgConfig_extract_frameworks_target) @@ -57,7 +63,6 @@ run_cmake(FindPkgConfig_GET_VARIABLE_MULTIPLE_VALUES) run_cmake(FindPkgConfig_cache_variables) run_cmake(FindPkgConfig_IMPORTED_TARGET) - run_cmake(FindPkgConfig_STATIC_REQUERY) run_cmake(FindPkgConfig_VERSION_OPERATORS) run_cmake(FindPkgConfig_GET_MATCHING_MODULE_NAME) run_cmake(FindPkgConfig_empty_target)
diff --git a/Tests/RunCMake/FindPkgConfig/pkg-config-static-requery.bat b/Tests/RunCMake/FindPkgConfig/pkg-config-static-requery.bat deleted file mode 100755 index 4583882..0000000 --- a/Tests/RunCMake/FindPkgConfig/pkg-config-static-requery.bat +++ /dev/null
@@ -1,99 +0,0 @@ -@ECHO OFF - -set static=false -set mode= -set pkg= -set variable= - -:LOOP -IF "%~1"=="" GOTO RUN - -IF "%~1"=="--version" ( - ECHO 1.0 - EXIT /B 0 -) -IF "%~1"=="--static" ( - set static=true - SHIFT - GOTO LOOP -) -IF "%~1"=="--modversion" ( - set mode=modversion - SHIFT - GOTO LOOP -) -IF "%~1"=="--cflags" ( - set mode=cflags - SHIFT - GOTO LOOP -) -IF "%~1"=="--libs" ( - set mode=libs - SHIFT - GOTO LOOP -) -IF "%~1"=="--print-errors" ( - SHIFT - GOTO LOOP -) -IF "%~1"=="--short-errors" ( - SHIFT - GOTO LOOP -) - -set arg=%~1 -IF "%arg:~0,11%"=="--variable=" ( - set mode=variable - set variable=%arg:~11% -) ELSE ( - set pkg=%~1 -) -SHIFT -GOTO LOOP - -:RUN -IF "%mode%"=="modversion" ( - IF "%pkg%"=="good" GOTO VERSION - IF "%pkg%"=="bad" GOTO VERSION -) -IF "%mode%"=="variable" ( - IF "%pkg%"=="good" GOTO VARIABLE - IF "%pkg%"=="bad" GOTO VARIABLE -) -IF "%mode%"=="cflags" ( - IF "%pkg%"=="good" GOTO CFLAGS - IF "%pkg%"=="bad" GOTO CFLAGS -) -IF "%mode%"=="libs" ( - IF "%pkg%"=="good" GOTO GOOD_LIBS - IF "%pkg%"=="bad" GOTO BAD_LIBS -) -EXIT /B 1 - -:VERSION -ECHO 1.0 -EXIT /B 0 - -:VARIABLE -ECHO /fake-%variable% -EXIT /B 0 - -:CFLAGS -ECHO -I/fake-include -EXIT /B 0 - -:GOOD_LIBS -IF "%static%"=="true" ( - ECHO -lgood -ldep -) ELSE ( - ECHO -lgood -) -EXIT /B 0 - -:BAD_LIBS -IF "%static%"=="true" ( - EXIT /B 1 -) ELSE ( - ECHO -lbad -) -EXIT /B 0
diff --git a/Tests/RunCMake/FindPkgConfig/pkg-config-static-requery.cmake b/Tests/RunCMake/FindPkgConfig/pkg-config-static-requery.cmake new file mode 100644 index 0000000..18d749a --- /dev/null +++ b/Tests/RunCMake/FindPkgConfig/pkg-config-static-requery.cmake
@@ -0,0 +1,113 @@ +# Emulate pkg-config for the static requery and modversion/variable tests. +# CMAKE_ARGV0..3 are: cmake -P <this file> -- + +macro(print_stdout value) + execute_process(COMMAND "${CMAKE_COMMAND}" -E echo "${value}") +endmacro() + +set(static FALSE) +set(mode "") +set(pkg "") +set(variable "") +set(call "") + +math(EXPR last_arg "${CMAKE_ARGC} - 1") +foreach(i RANGE 4 ${last_arg}) + set(arg "${CMAKE_ARGV${i}}") + string(APPEND call " ${arg}") + + if(arg STREQUAL "--version") + set(mode version) + elseif(arg STREQUAL "--static") + set(static TRUE) + elseif(arg STREQUAL "--modversion") + set(mode modversion) + elseif(arg MATCHES "^--variable=(.*)$") + if(NOT mode STREQUAL "modversion") + set(mode variable) + endif() + set(variable "${CMAKE_MATCH_1}") + elseif(arg STREQUAL "--cflags") + set(mode cflags) + elseif(arg STREQUAL "--libs") + set(mode libs) + elseif(NOT arg MATCHES "^--(print-errors|short-errors)$") + string(REGEX REPLACE " .*" "" pkg "${arg}") + endif() +endforeach() + +if(NOT "$ENV{FAKE_PKG_CONFIG_LOG}" STREQUAL "") + file(APPEND "$ENV{FAKE_PKG_CONFIG_LOG}" "${call}\n") +endif() + +if(mode STREQUAL "version") + if("$ENV{FAKE_PKG_CONFIG_FLAVOR}" STREQUAL "pkg-config") + print_stdout("0.29.2") + elseif("$ENV{FAKE_PKG_CONFIG_FLAVOR}" STREQUAL "pkgconf") + print_stdout("2.1.0") + else() + print_stdout("1.0") + endif() + return() +endif() + +if(pkg STREQUAL "good" OR pkg STREQUAL "bad") + set(version "1.0") + set(prefix "/fake;prefix") +elseif(pkg STREQUAL "normal") + set(version "1.2.3") + set(prefix "/fake/normal") +elseif(pkg STREQUAL "emptyversion") + set(version "") + set(prefix "/fake/emptyversion") +else() + cmake_language(EXIT 1) +endif() + +if(mode STREQUAL "modversion") + print_stdout("${version}") + if(NOT variable STREQUAL "") + if("$ENV{FAKE_PKG_CONFIG_FLAVOR}" STREQUAL "pkg-config") + message("Ignoring incompatible output option \"--variable\"") + else() + print_stdout("${prefix}") + endif() + endif() + return() +elseif(mode STREQUAL "variable") + if(variable STREQUAL "prefix") + print_stdout("${prefix}") + elseif(pkg STREQUAL "good" OR pkg STREQUAL "bad") + print_stdout("/fake-${variable}") + elseif(variable STREQUAL "includedir") + print_stdout("/fake/${pkg}/include") + elseif(variable STREQUAL "libdir") + print_stdout("/fake/${pkg}/lib") + endif() + return() +elseif(mode STREQUAL "cflags") + if(pkg STREQUAL "good" OR pkg STREQUAL "bad") + print_stdout("-I/fake-include") + else() + print_stdout("-I/fake/${pkg}/include") + endif() + return() +elseif(mode STREQUAL "libs") + if(pkg STREQUAL "good") + if(static) + print_stdout("-lgood -ldep") + else() + print_stdout("-lgood") + endif() + elseif(pkg STREQUAL "bad") + if(static) + cmake_language(EXIT 1) + endif() + print_stdout("-lbad") + else() + print_stdout("-L/fake/${pkg}/lib -l${pkg}") + endif() + return() +else() + cmake_language(EXIT 1) +endif()
diff --git a/Tests/RunCMake/FindPkgConfig/pkg-config-static-requery.sh b/Tests/RunCMake/FindPkgConfig/pkg-config-static-requery.sh deleted file mode 100755 index 87e98bb..0000000 --- a/Tests/RunCMake/FindPkgConfig/pkg-config-static-requery.sh +++ /dev/null
@@ -1,64 +0,0 @@ -#!/bin/sh - -static=false -mode= -pkg= - -for arg in "$@"; do - case "$arg" in - --version) - echo "1.0" - exit 0 - ;; - --static) - static=true - ;; - --modversion) - mode=modversion - ;; - --variable=*) - mode=variable - variable="${arg#--variable=}" - ;; - --cflags) - mode=cflags - ;; - --libs) - mode=libs - ;; - --print-errors|--short-errors) - ;; - *) - pkg="$arg" - ;; - esac -done - -case "$mode:$pkg" in - modversion:good|modversion:bad) - echo "1.0" - ;; - variable:good|variable:bad) - echo "/fake-$variable" - ;; - cflags:good|cflags:bad) - echo "-I/fake-include" - ;; - libs:good) - if $static; then - echo "-lgood -ldep" - else - echo "-lgood" - fi - ;; - libs:bad) - if $static; then - exit 1 - else - echo "-lbad" - fi - ;; - *) - exit 1 - ;; -esac
diff --git a/Tests/RunCMake/FindTCL/FindTCLTest.cmake b/Tests/RunCMake/FindTCL/FindTCLTest.cmake index eb68c83..974caa9 100644 --- a/Tests/RunCMake/FindTCL/FindTCLTest.cmake +++ b/Tests/RunCMake/FindTCL/FindTCLTest.cmake
@@ -3,13 +3,10 @@ set(CMAKE_FIND_USE_CMAKE_SYSTEM_PATH OFF) set(CMAKE_FIND_FRAMEWORK NEVER) -# FIXME: Avoid unchecked construction of TCLTK_POSSIBLE_BIN_PATHS -# and TCLTK_POSSIBLE_LIB_PATHS. Fix FindTclsh and FindTCL later. -set(CMAKE_IGNORE_PATH /bin /lib) - function(check_layout name) cmake_parse_arguments(PARSE_ARGV 1 arg "" - "ARCH;TCL_LIBRARY;TK_LIBRARY;INCLUDE_PATH" "PREFIXES;SUFFIXES;FILES") + "ARCH;TCL_LIBRARY;TK_LIBRARY;INCLUDE_PATH" + "PREFIXES;SUFFIXES;FILES;PREFIX_PATH;SYSTEM_PREFIX_PATH") set(prefix "${CMAKE_CURRENT_BINARY_DIR}/${name}") file(REMOVE_RECURSE "${prefix}") @@ -22,7 +19,17 @@ set(CMAKE_FIND_LIBRARY_PREFIXES "${arg_PREFIXES}") set(CMAKE_FIND_LIBRARY_SUFFIXES "${arg_SUFFIXES}") set(CMAKE_LIBRARY_ARCHITECTURE "${arg_ARCH}") - set(CMAKE_PREFIX_PATH "${prefix}") + if(arg_PREFIX_PATH OR arg_SYSTEM_PREFIX_PATH) + # The layout stands in for the whole filesystem, root-level /lib included + set(CMAKE_FIND_ROOT_PATH "${prefix}") + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + set(CMAKE_PREFIX_PATH "${arg_PREFIX_PATH}") + set(CMAKE_SYSTEM_PREFIX_PATH "${arg_SYSTEM_PREFIX_PATH}") + set(CMAKE_FIND_USE_CMAKE_SYSTEM_PATH ON) + else() + set(CMAKE_PREFIX_PATH "${prefix}") + endif() # Empty skips the host tclsh/wish search, and FindTclsh running tclsh set(TCL_TCLSH "") set(TK_WISH "") @@ -114,3 +121,24 @@ TK_LIBRARY lib/x86_64-linux-gnu/libtk.so INCLUDE_PATH include/tcl ) + +# Plain names in /lib and /include, which nothing found points to, lose. +check_layout(Tk9-stray-root + PREFIXES lib SUFFIXES .so SYSTEM_PREFIX_PATH /usr + FILES include/tcl.h include/tk.h lib/libtcl.so lib/libtk.so + usr/include/tcl.h usr/include/tk.h + usr/lib/libtcl9.0.so usr/lib/libtcl9tk9.0.so + TCL_LIBRARY usr/lib/libtcl9.0.so TK_LIBRARY usr/lib/libtcl9tk9.0.so + INCLUDE_PATH usr/include + ) + +# Libraries follow prefix order, like headers, not the newest name. +check_layout(Tk86-Tk9-prefix-order + PREFIXES "" SUFFIXES .lib PREFIX_PATH /opt/tcl86 /opt/tcl90 + FILES opt/tcl86/include/tcl.h opt/tcl86/include/tk.h + opt/tcl86/lib/tcl86t.lib opt/tcl86/lib/tk86t.lib + opt/tcl90/include/tcl.h opt/tcl90/include/tk.h + opt/tcl90/lib/tcl90.lib opt/tcl90/lib/tcl9tk90.lib + TCL_LIBRARY opt/tcl86/lib/tcl86t.lib TK_LIBRARY opt/tcl86/lib/tk86t.lib + INCLUDE_PATH opt/tcl86/include + )
diff --git a/Tests/RunCMake/MSVCDefaultFlags/CMP0197-NEW-config.txt b/Tests/RunCMake/MSVCDefaultFlags/CMP0197-NEW-config.txt index cd5b09f..024d896 100644 --- a/Tests/RunCMake/MSVCDefaultFlags/CMP0197-NEW-config.txt +++ b/Tests/RunCMake/MSVCDefaultFlags/CMP0197-NEW-config.txt
@@ -1,2 +1,3 @@ -[ ,][/-][Mm][Aa][Cc][Hh][Ii][Nn][Ee]:[A-Za-z0-9_]+[ ]|[Vv][Cc](98|7)\\\\[Bb][Ii][Nn]\\\\[Ll][Ii][Nn][Kk]\.[Ee][Xx][Ee]"? [^ +[" ,][/-][Mm][Aa][Cc][Hh][Ii][Nn][Ee]:[A-Za-z0-9_]+([ "]| +|$)|[Vv][Cc](98|7)\\\\[Bb][Ii][Nn]\\\\[Ll][Ii][Nn][Kk]\.[Ee][Xx][Ee]"? [^ ]*@[^ ]+\\\\nm
diff --git a/Tests/RunCMake/MSVCDefaultFlags/CMP0197-OLD-config.txt b/Tests/RunCMake/MSVCDefaultFlags/CMP0197-OLD-config.txt index caa568d..1dbe4ae 100644 --- a/Tests/RunCMake/MSVCDefaultFlags/CMP0197-OLD-config.txt +++ b/Tests/RunCMake/MSVCDefaultFlags/CMP0197-OLD-config.txt
@@ -1 +1,2 @@ -[" ,]/[Mm][Aa][Cc][Hh][Ii][Nn][Ee]:[A-Za-z0-9_]+[ "] +[" ,][/-][Mm][Aa][Cc][Hh][Ii][Nn][Ee]:[A-Za-z0-9_]+([ "]| +|$)
diff --git a/Tests/RunCMake/MSVCDefaultFlags/CMP0197-WARN-config.txt b/Tests/RunCMake/MSVCDefaultFlags/CMP0197-WARN-config.txt index caa568d..1dbe4ae 100644 --- a/Tests/RunCMake/MSVCDefaultFlags/CMP0197-WARN-config.txt +++ b/Tests/RunCMake/MSVCDefaultFlags/CMP0197-WARN-config.txt
@@ -1 +1,2 @@ -[" ,]/[Mm][Aa][Cc][Hh][Ii][Nn][Ee]:[A-Za-z0-9_]+[ "] +[" ,][/-][Mm][Aa][Cc][Hh][Ii][Nn][Ee]:[A-Za-z0-9_]+([ "]| +|$)
diff --git a/Tests/RunCMake/MSVCDefaultFlags/CMP0197-build-stdout.txt b/Tests/RunCMake/MSVCDefaultFlags/CMP0197-build-stdout.txt index bdd31e7..1dbe4ae 100644 --- a/Tests/RunCMake/MSVCDefaultFlags/CMP0197-build-stdout.txt +++ b/Tests/RunCMake/MSVCDefaultFlags/CMP0197-build-stdout.txt
@@ -1 +1,2 @@ -[ ,][/-][Mm][Aa][Cc][Hh][Ii][Nn][Ee]:[A-Za-z0-9_]+[ ] +[" ,][/-][Mm][Aa][Cc][Hh][Ii][Nn][Ee]:[A-Za-z0-9_]+([ "]| +|$)
diff --git a/Tests/RunCMake/PrecompileHeaders/PchWarnings-check.cmake b/Tests/RunCMake/PrecompileHeaders/PchWarnings-check.cmake new file mode 100644 index 0000000..e77e9ed --- /dev/null +++ b/Tests/RunCMake/PrecompileHeaders/PchWarnings-check.cmake
@@ -0,0 +1,40 @@ +if (RunCMake_GENERATOR STREQUAL "Xcode" OR + NOT CMAKE_C_COMPILER_ID MATCHES "^(GNU|LCC|Clang|AppleClang|IntelLLVM|MSVC)$") + return() +endif() + +# MSVC defines the system header pragma only for toolset 14.13 from VS 2017 15.6. +if (CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND MSVC_VERSION LESS 1913) + return() +endif() + +function(check_system_header_pragma target expected) + set(pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/${target}.dir/cmake_pch.h") + if (RunCMake_GENERATOR_IS_MULTI_CONFIG) + set(pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/${target}.dir/Debug/cmake_pch.h") + endif() + + if (NOT EXISTS "${pch_header}") + set(RunCMake_TEST_FAILED + "Generated pch file for '${target}'\n ${pch_header}\ndoes not exist" + PARENT_SCOPE) + return() + endif() + + file(STRINGS "${pch_header}" pch_header_strings REGEX "system_header") + if (expected AND NOT pch_header_strings) + set(RunCMake_TEST_FAILED + "Generated pch file for '${target}' is missing the system header pragma" + PARENT_SCOPE) + elseif (NOT expected AND pch_header_strings) + set(RunCMake_TEST_FAILED + "Generated pch file for '${target}' has an unexpected system header pragma" + PARENT_SCOPE) + endif() +endfunction() + +check_system_header_pragma(empty ON) +if (RunCMake_TEST_FAILED) + return() +endif() +check_system_header_pragma(foo OFF)
diff --git a/Tests/RunCMake/PrecompileHeaders/PchWarnings.cmake b/Tests/RunCMake/PrecompileHeaders/PchWarnings.cmake new file mode 100644 index 0000000..b394e32 --- /dev/null +++ b/Tests/RunCMake/PrecompileHeaders/PchWarnings.cmake
@@ -0,0 +1,16 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY FULL CACHE STRING "" FORCE) + +enable_language(C) + +add_library(empty empty.c) +target_precompile_headers(empty PUBLIC + <stdio.h> + <string.h> +) + +add_library(foo foo.c) +target_precompile_headers(foo PUBLIC + <stdio.h> + <string.h> +) +set_target_properties(foo PROPERTIES PCH_WARNINGS ON)
diff --git a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake index 48f1484..85a7672 100644 --- a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake +++ b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
@@ -24,6 +24,7 @@ endif () run_test(PchInterfaceUnity) run_cmake(PchPrologueEpilogue) +run_cmake(PchWarnings) run_test(SkipPrecompileHeaders) run_test(CXXnotC) run_cmake(PchMultilanguage)
diff --git a/Tests/RunCMake/Rust/Editions.cmake b/Tests/RunCMake/Rust/Editions.cmake index 95b408f..9fcb627 100644 --- a/Tests/RunCMake/Rust/Editions.cmake +++ b/Tests/RunCMake/Rust/Editions.cmake
@@ -1,4 +1,4 @@ -set(CMAKE_EXPERIMENTAL_RUST "b6fdddce-bf66-41a5-bc5f-077f6fa4d2a1") +set(CMAKE_EXPERIMENTAL_RUST "628f8f9f-d7dc-4a06-9aaf-d4ede4426ddf") enable_language(Rust) # No Edition set, rustc defaults to 2015.
diff --git a/Tests/RunCMake/Rust/Enable.cmake b/Tests/RunCMake/Rust/Enable.cmake index 9bdff73..4e34ea2 100644 --- a/Tests/RunCMake/Rust/Enable.cmake +++ b/Tests/RunCMake/Rust/Enable.cmake
@@ -1,3 +1,3 @@ -set(CMAKE_EXPERIMENTAL_RUST "b6fdddce-bf66-41a5-bc5f-077f6fa4d2a1") +set(CMAKE_EXPERIMENTAL_RUST "628f8f9f-d7dc-4a06-9aaf-d4ede4426ddf") enable_language(Rust) message(STATUS "CMAKE_Rust_COMPILER='${CMAKE_Rust_COMPILER}'")
diff --git a/Tests/RunCMake/ctest_build/RunCMakeTest.cmake b/Tests/RunCMake/ctest_build/RunCMakeTest.cmake index 612a199..89159e1 100644 --- a/Tests/RunCMake/ctest_build/RunCMakeTest.cmake +++ b/Tests/RunCMake/ctest_build/RunCMakeTest.cmake
@@ -215,3 +215,10 @@ run_NinjaLauncherSignalBuildFailure() endif() endif() + +block() + set(CASE SetOutputDir) + set(DEFAULT_OUTPUT_DIR "${RunCMake_BINARY_DIR}/${CASE}-build/Testing") + set(OUTPUT_DIR "${RunCMake_BINARY_DIR}/${CASE}-build/CTestBuildOutputDir") + run_ctest_build(${CASE}) +endblock()
diff --git a/Tests/RunCMake/ctest_build/SetOutputDir-check.cmake b/Tests/RunCMake/ctest_build/SetOutputDir-check.cmake new file mode 100644 index 0000000..9d8aaab --- /dev/null +++ b/Tests/RunCMake/ctest_build/SetOutputDir-check.cmake
@@ -0,0 +1,39 @@ +# ctest_configure() runs include(CTest), which creates the default output +# directory at configure time. Check that nothing was written into it. +file(GLOB_RECURSE DEFAULT_OUTPUT_FILES "${DEFAULT_OUTPUT_DIR}/*") +if(DEFAULT_OUTPUT_FILES) + string(REPLACE ";" "\n " DEFAULT_OUTPUT_FILES "${DEFAULT_OUTPUT_FILES}") + string(APPEND RunCMake_TEST_FAILED + "Default output directory should not have been used:\n" + " ${DEFAULT_OUTPUT_DIR}\n" + "It contains:\n ${DEFAULT_OUTPUT_FILES}\n") + return() +endif() + +set(TAG_PATH "${OUTPUT_DIR}/TAG") +if(NOT EXISTS "${TAG_PATH}") + set(RunCMake_TEST_FAILED "Expected ${TAG_PATH} file to exist.") + return() +endif() + +file(STRINGS "${TAG_PATH}" TAG_CONTENTS) +if(TAG_CONTENTS STREQUAL "") + set(RunCMake_TEST_FAILED "${TAG_PATH} is empty.") + return() +endif() + +list(GET TAG_CONTENTS 0 TAG) +set(EXPECTED_FILES + "${OUTPUT_DIR}/Temporary/LastStart.log" + "${OUTPUT_DIR}/Temporary/LastConfigure_${TAG}.log" + "${OUTPUT_DIR}/Temporary/LastBuild_${TAG}.log" + "${OUTPUT_DIR}/${TAG}/Configure.xml" + "${OUTPUT_DIR}/${TAG}/Build.xml" +) + +foreach(EXP_FILE IN LISTS EXPECTED_FILES) + if(NOT EXISTS "${EXP_FILE}") + set(RunCMake_TEST_FAILED "Expected ${EXP_FILE} file to exist.") + return() + endif() +endforeach()
diff --git a/Tests/RunCMake/ctest_build/test.cmake.in b/Tests/RunCMake/ctest_build/test.cmake.in index 98bd8ac..5a1eaaf 100644 --- a/Tests/RunCMake/ctest_build/test.cmake.in +++ b/Tests/RunCMake/ctest_build/test.cmake.in
@@ -13,6 +13,9 @@ if (@RunCMake_USE_CUSTOM_BUILD_COMMAND@) set(CTEST_BUILD_COMMAND "\"@RunCMake_BUILD_COMMAND@\"") endif() +if("@CASE_NAME@" MATCHES "^SetOutputDir$") + set(CTEST_OUTPUT_DIRECTORY "@OUTPUT_DIR@") +endif() set(ctest_build_args "@CASE_CTEST_BUILD_ARGS@") ctest_start(Experimental)
diff --git a/Tests/RunCMake/ctest_coverage/RunCMakeTest.cmake b/Tests/RunCMake/ctest_coverage/RunCMakeTest.cmake index dd443fc..95c359b 100644 --- a/Tests/RunCMake/ctest_coverage/RunCMakeTest.cmake +++ b/Tests/RunCMake/ctest_coverage/RunCMakeTest.cmake
@@ -8,3 +8,10 @@ endfunction() run_ctest_coverage(CoverageQuiet QUIET) + +block() + set(CASE SetOutputDir) + set(DEFAULT_OUTPUT_DIR "${RunCMake_BINARY_DIR}/${CASE}-build/Testing") + set(OUTPUT_DIR "${RunCMake_BINARY_DIR}/${CASE}-build/CTestCoverageOutputDir") + run_ctest_coverage(${CASE} QUIET) +endblock()
diff --git a/Tests/RunCMake/ctest_coverage/SetOutputDir-check.cmake b/Tests/RunCMake/ctest_coverage/SetOutputDir-check.cmake new file mode 100644 index 0000000..c175962 --- /dev/null +++ b/Tests/RunCMake/ctest_coverage/SetOutputDir-check.cmake
@@ -0,0 +1,42 @@ +# ctest_configure() runs include(CTest), which creates the default output +# directory at configure time. Check that nothing was written into it. +file(GLOB_RECURSE DEFAULT_OUTPUT_FILES "${DEFAULT_OUTPUT_DIR}/*") +if(DEFAULT_OUTPUT_FILES) + string(REPLACE ";" "\n " DEFAULT_OUTPUT_FILES "${DEFAULT_OUTPUT_FILES}") + string(APPEND RunCMake_TEST_FAILED + "Default output directory should not have been used:\n" + " ${DEFAULT_OUTPUT_DIR}\n" + "It contains:\n ${DEFAULT_OUTPUT_FILES}\n") + return() +endif() + +set(TAG_PATH "${OUTPUT_DIR}/TAG") +if(NOT EXISTS "${TAG_PATH}") + set(RunCMake_TEST_FAILED "Expected ${TAG_PATH} file to exist.") + return() +endif() + +file(STRINGS "${TAG_PATH}" TAG_CONTENTS) +if(TAG_CONTENTS STREQUAL "") + set(RunCMake_TEST_FAILED "${TAG_PATH} is empty.") + return() +endif() + +list(GET TAG_CONTENTS 0 TAG) +set(EXPECTED_FILES + "${OUTPUT_DIR}/Temporary/LastStart.log" + "${OUTPUT_DIR}/Temporary/LastConfigure_${TAG}.log" + "${OUTPUT_DIR}/Temporary/LastBuild_${TAG}.log" + "${OUTPUT_DIR}/${TAG}/Configure.xml" + "${OUTPUT_DIR}/${TAG}/Build.xml" + # Produced from the coverage data the test script leaves in the build tree. + "${OUTPUT_DIR}/${TAG}/Coverage.xml" + "${OUTPUT_DIR}/${TAG}/CoverageLog-0.xml" +) + +foreach(EXP_FILE IN LISTS EXPECTED_FILES) + if(NOT EXISTS "${EXP_FILE}") + set(RunCMake_TEST_FAILED "Expected ${EXP_FILE} file to exist.") + return() + endif() +endforeach()
diff --git a/Tests/RunCMake/ctest_coverage/test.cmake.in b/Tests/RunCMake/ctest_coverage/test.cmake.in index c7a86b4..838cff3 100644 --- a/Tests/RunCMake/ctest_coverage/test.cmake.in +++ b/Tests/RunCMake/ctest_coverage/test.cmake.in
@@ -9,10 +9,28 @@ set(CTEST_CMAKE_GENERATOR_TOOLSET "@RunCMake_GENERATOR_TOOLSET@") set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}") set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@") +if("@CASE_NAME@" MATCHES "^SetOutputDir$") + set(CTEST_OUTPUT_DIRECTORY "@OUTPUT_DIR@") +endif() set(ctest_coverage_args "@CASE_CTEST_COVERAGE_ARGS@") ctest_start(Experimental) ctest_configure() ctest_build() ctest_test() +if("@CASE_NAME@" MATCHES "^SetOutputDir$") + # Leave Cobertura-style coverage data in the build tree so that + # ctest_coverage() produces real output files to check. No coverage + # tool runs; the handler just parses what it finds. + file(WRITE "${CTEST_BINARY_DIRECTORY}/covsrc/main.cpp" "int main(){return 0;}\n") + file(WRITE "${CTEST_BINARY_DIRECTORY}/coverage.xml" +"<?xml version=\"1.0\"?> +<coverage> + <sources><source>${CTEST_BINARY_DIRECTORY}/covsrc</source></sources> + <packages><package><classes> + <class filename=\"main.cpp\"><lines><line number=\"1\" hits=\"1\"/></lines></class> + </classes></package></packages> +</coverage> +") +endif() ctest_coverage(${ctest_coverage_args})
diff --git a/Tests/RunCMake/ctest_start/RunCMakeTest.cmake b/Tests/RunCMake/ctest_start/RunCMakeTest.cmake index f11f1ec..57e8fea 100644 --- a/Tests/RunCMake/ctest_start/RunCMakeTest.cmake +++ b/Tests/RunCMake/ctest_start/RunCMakeTest.cmake
@@ -51,6 +51,13 @@ run_ctest_start(NoStartTimeExperimental Experimental) run_ctest_start(NoStartTimeNightly Nightly) +block() + set(CASE SetOutputDir) + set(DEFAULT_OUTPUT_DIR "${RunCMake_BINARY_DIR}/${CASE}-build/Testing") + set(OUTPUT_DIR "${RunCMake_BINARY_DIR}/${CASE}-build/CTestStartOutputDir") + run_ctest_start(${CASE} Experimental) +endblock() + function(run_ConfigInBuild) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ConfigInBuild-build) set(RunCMake_TEST_NO_CLEAN 1)
diff --git a/Tests/RunCMake/ctest_start/SetOutputDir-check.cmake b/Tests/RunCMake/ctest_start/SetOutputDir-check.cmake new file mode 100644 index 0000000..4196e40 --- /dev/null +++ b/Tests/RunCMake/ctest_start/SetOutputDir-check.cmake
@@ -0,0 +1,16 @@ +# This case never configures the project, so nothing creates the default +# output directory. Check that the run did not create it either. +file(GLOB_RECURSE DEFAULT_OUTPUT_FILES "${DEFAULT_OUTPUT_DIR}/*") +if(DEFAULT_OUTPUT_FILES) + string(REPLACE ";" "\n " DEFAULT_OUTPUT_FILES "${DEFAULT_OUTPUT_FILES}") + string(APPEND RunCMake_TEST_FAILED + "Default output directory should not have been used:\n" + " ${DEFAULT_OUTPUT_DIR}\n" + "It contains:\n ${DEFAULT_OUTPUT_FILES}\n") +elseif(NOT EXISTS "${OUTPUT_DIR}/TAG") + set(RunCMake_TEST_FAILED + "Expected ${OUTPUT_DIR}/TAG file to exist.") +elseif(NOT EXISTS "${OUTPUT_DIR}/Temporary/LastStart.log") + set(RunCMake_TEST_FAILED + "Expected ${OUTPUT_DIR}/Temporary/LastStart.log file to exist.") +endif()
diff --git a/Tests/RunCMake/ctest_start/test.cmake.in b/Tests/RunCMake/ctest_start/test.cmake.in index ec1265f..0a1071a 100644 --- a/Tests/RunCMake/ctest_start/test.cmake.in +++ b/Tests/RunCMake/ctest_start/test.cmake.in
@@ -11,6 +11,9 @@ if(NOT "@CASE_NAME@" MATCHES "^NoStartTime") set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC") endif() +if("@CASE_NAME@" MATCHES "^SetOutputDir$") + set(CTEST_OUTPUT_DIRECTORY "@OUTPUT_DIR@") +endif() function(setup_tests) ctest_start(${ctest_start_args})
diff --git a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake index ef5bb67..885ba62 100644 --- a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake +++ b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake
@@ -358,6 +358,16 @@ endfunction() run_CTestTestCoverageTool() +function(run_CTestTestCoverageToolVar) + set(CASE_TEST_PREFIX_CODE [[ +unset(ENV{LLVM_PROFILE_FILE}) +set(CTEST_TEST_COVERAGE_TOOL "LLVM-COV") +]]) + + run_ctest(TestCTestTestCoverageToolVar -VV) +endfunction() +run_CTestTestCoverageToolVar() + # test for OUTPUT_JUNIT run_ctest_test(OutputJUnit OUTPUT_JUNIT junit.xml REPEAT UNTIL_FAIL:2)
diff --git a/Tests/RunCMake/ctest_test/TestCTestTestCoverageToolVar-stdout.txt b/Tests/RunCMake/ctest_test/TestCTestTestCoverageToolVar-stdout.txt new file mode 100644 index 0000000..867efa6 --- /dev/null +++ b/Tests/RunCMake/ctest_test/TestCTestTestCoverageToolVar-stdout.txt
@@ -0,0 +1,3 @@ +1: Using environment variable LLVM_PROFILE_FILE=[^ +]*/Tests/RunCMake/ctest_test/[^ +]*_%p\.profraw
diff --git a/Tests/RunCMake/find_package-CPS/InvalidCps3-stderr.txt b/Tests/RunCMake/find_package-CPS/InvalidCps3-stderr.txt index 1fa4272..4c4764c 100644 --- a/Tests/RunCMake/find_package-CPS/InvalidCps3-stderr.txt +++ b/Tests/RunCMake/find_package-CPS/InvalidCps3-stderr.txt
@@ -4,11 +4,24 @@ InvalidCps3\.cmake:10 \(find_package\) CMakeLists\.txt:3 \(include\) + -CMake Warning in cps/[Cc]orrupt.cps: +CMake Warning in cps/[Cc]orrupt\.cps: + Component "Corrupt::array" is not an object\. +Call Stack \(most recent call first\): + InvalidCps3\.cmake:10 \(find_package\) + CMakeLists\.txt:3 \(include\) ++ +CMake Warning in cps/[Cc]orrupt\.cps: + Component "Corrupt::bad_config_entries" configuration "release" is not an + object\. +Call Stack \(most recent call first\): + InvalidCps3\.cmake:10 \(find_package\) + CMakeLists\.txt:3 \(include\) ++ +CMake Warning in cps/[Cc]orrupt\.cps: Component "Corrupt::badconfigs" attribute "configurations" is not an object\. Call Stack \(most recent call first\): - InvalidCps3.cmake:10 \(find_package\) + InvalidCps3\.cmake:10 \(find_package\) CMakeLists\.txt:3 \(include\) + CMake Warning in cps/[Cc]orrupt\.cps: @@ -23,3 +36,16 @@ Call Stack \(most recent call first\): InvalidCps3\.cmake:10 \(find_package\) CMakeLists\.txt:3 \(include\) ++ +CMake Warning in cps/[Cc]orrupt\.cps: + Component "Corrupt::string" is not an object\. +Call Stack \(most recent call first\): + InvalidCps3\.cmake:10 \(find_package\) + CMakeLists\.txt:3 \(include\) ++ +CMake Warning in cps/[Cc]orrupt@release\.cps: + Component "corrupt" is not an object\. +Call Stack \(most recent call first\): + cps/[Cc]orrupt\.cps + InvalidCps3\.cmake:10 \(find_package\) + CMakeLists\.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_package-CPS/cps/corrupt.cps b/Tests/RunCMake/find_package-CPS/cps/corrupt.cps index afa6742..b61c7ef 100644 --- a/Tests/RunCMake/find_package-CPS/cps/corrupt.cps +++ b/Tests/RunCMake/find_package-CPS/cps/corrupt.cps
@@ -3,6 +3,10 @@ "name": "Corrupt", "license": [], "cps_path": "@prefix@/cps", + "requires": { + "array": [ "" ], + "string": "" + }, "components": { "corrupt": { "type": "archive", @@ -12,6 +16,14 @@ "type": "interface", "configurations": [""] }, + "bad_config_entries": { + "type": "interface", + "configurations": { + "release": [] + } + }, + "array": [ "" ], + "string": "", "invalid": "not-an-object" } }
diff --git a/Tests/RunCMake/find_package-CPS/cps/corrupt@release.cps b/Tests/RunCMake/find_package-CPS/cps/corrupt@release.cps new file mode 100644 index 0000000..b6a464e --- /dev/null +++ b/Tests/RunCMake/find_package-CPS/cps/corrupt@release.cps
@@ -0,0 +1,8 @@ +{ + "cps_version": "0.13.0", + "name": "Corrupt", + "configuration": "release", + "components": { + "corrupt": "not-an-object" + } +}
diff --git a/Tests/RunCMake/install/TARGETS-NAMELINK-No-Tweak.cmake b/Tests/RunCMake/install/TARGETS-NAMELINK-No-Tweak.cmake index 879f4b8..b4497f7 100644 --- a/Tests/RunCMake/install/TARGETS-NAMELINK-No-Tweak.cmake +++ b/Tests/RunCMake/install/TARGETS-NAMELINK-No-Tweak.cmake
@@ -13,7 +13,7 @@ # This verifies that no install tweaks are added for the namelink. set(linker_script "INPUT($<TARGET_SONAME_FILE_NAME:foo>)") add_custom_command(TARGET foo POST_BUILD - COMMAND "${CMAKE_COMMAND}" -E remove "$<TARGET_LINKER_FILE:foo>" + COMMAND "${CMAKE_COMMAND}" -E rm "$<TARGET_LINKER_FILE:foo>" COMMAND "${CMAKE_COMMAND}" -E echo "${linker_script}" > "$<TARGET_LINKER_FILE:foo>" COMMENT "Generating linker script: '${linker_script}' as file $<TARGET_LINKER_FILE:foo>" VERBATIM
diff --git a/Tests/RunCMake/property_init/CompileSources.cmake b/Tests/RunCMake/property_init/CompileSources.cmake index c7dee81..2a8a892 100644 --- a/Tests/RunCMake/property_init/CompileSources.cmake +++ b/Tests/RunCMake/property_init/CompileSources.cmake
@@ -12,6 +12,7 @@ "DISABLE_PRECOMPILE_HEADERS" "ON" "<SAME>" "PCH_WARN_INVALID" "OFF" "<SAME>" "PCH_INSTANTIATE_TEMPLATES" "OFF" "<SAME>" + "PCH_WARNINGS" "ON" "<SAME>" ## Platforms ### Android "ANDROID_API" "9" "<SAME>"
diff --git a/Tests/RustMix/CMakeLists.txt b/Tests/RustMix/CMakeLists.txt index 029f534..c25c610 100644 --- a/Tests/RustMix/CMakeLists.txt +++ b/Tests/RustMix/CMakeLists.txt
@@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 4.2) -set(CMAKE_EXPERIMENTAL_RUST "b6fdddce-bf66-41a5-bc5f-077f6fa4d2a1") +set(CMAKE_EXPERIMENTAL_RUST "628f8f9f-d7dc-4a06-9aaf-d4ede4426ddf") project(RustMix LANGUAGES C CXX Rust)
diff --git a/Tests/RustOnly/CMakeLists.txt b/Tests/RustOnly/CMakeLists.txt index 72b6efa..64e265c 100644 --- a/Tests/RustOnly/CMakeLists.txt +++ b/Tests/RustOnly/CMakeLists.txt
@@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 4.2) -set(CMAKE_EXPERIMENTAL_RUST "b6fdddce-bf66-41a5-bc5f-077f6fa4d2a1") +set(CMAKE_EXPERIMENTAL_RUST "628f8f9f-d7dc-4a06-9aaf-d4ede4426ddf") project(RustOnly LANGUAGES Rust)
diff --git a/Tests/RustPie/CMakeLists.txt b/Tests/RustPie/CMakeLists.txt index 9adc23c..6640dea 100644 --- a/Tests/RustPie/CMakeLists.txt +++ b/Tests/RustPie/CMakeLists.txt
@@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 4.2) -set(CMAKE_EXPERIMENTAL_RUST "b6fdddce-bf66-41a5-bc5f-077f6fa4d2a1") +set(CMAKE_EXPERIMENTAL_RUST "628f8f9f-d7dc-4a06-9aaf-d4ede4426ddf") function(setup PREFIX) add_library(${PREFIX}_static STATIC ../static.rs)
diff --git a/Utilities/Scripts/update-llpkgc.bash b/Utilities/Scripts/update-llpkgc.bash index 455104a..264b0e7 100755 --- a/Utilities/Scripts/update-llpkgc.bash +++ b/Utilities/Scripts/update-llpkgc.bash
@@ -10,7 +10,7 @@ readonly ownership="llpkgc upstream <kwrobot@kitware.com>" readonly subtree="Utilities/cmllpkgc" readonly repo="https://gitlab.kitware.com/utils/llpkgc.git" -readonly tag="12b80381152d003186ee3bddb200743b4ce91ffa" +readonly tag="47bc65ff8ac1001c586f81cbd2784561f4baed47" # v0.0.8 readonly shortlog=false readonly exact_tree_match=false readonly paths="
diff --git a/Utilities/ast-grep/rule-tests/__snapshots__/cmstrcat-not-append-result-snapshot.yml b/Utilities/ast-grep/rule-tests/__snapshots__/cmstrcat-not-append-result-snapshot.yml index a652f3b..4471435 100644 --- a/Utilities/ast-grep/rule-tests/__snapshots__/cmstrcat-not-append-result-snapshot.yml +++ b/Utilities/ast-grep/rule-tests/__snapshots__/cmstrcat-not-append-result-snapshot.yml
@@ -8,7 +8,7 @@ start: 0 end: 15 a += cmStrCat(b, c): - fixed: a = cmStrCat(std::move(a), b, c) + fixed: a = cmStrCat(a, b, c) labels: - source: a += cmStrCat(b, c) style: primary @@ -29,7 +29,7 @@ start: 0 end: 20 a.append(cmStrCat(b, c)): - fixed: a = cmStrCat(std::move(a), b, c) + fixed: a = cmStrCat(a, b, c) labels: - source: a.append(cmStrCat(b, c)) style: primary @@ -43,7 +43,7 @@ start: 0 end: 24 cflags["Swift"] += cmStrCat(' ', defineString): - fixed: cflags["Swift"] = cmStrCat(std::move(cflags["Swift"]), ' ', defineString) + fixed: cflags["Swift"] = cmStrCat(cflags["Swift"], ' ', defineString) labels: - source: cflags["Swift"] += cmStrCat(' ', defineString) style: primary @@ -57,7 +57,7 @@ start: 0 end: 46 obj.field += cmStrCat(b, c);: - fixed: obj.field = cmStrCat(std::move(obj.field), b, c); + fixed: obj.field = cmStrCat(obj.field, b, c); labels: - source: obj.field += cmStrCat(b, c) style: primary
diff --git a/Utilities/cmllpkgc/CMakeLists.txt b/Utilities/cmllpkgc/CMakeLists.txt index c2f1a95..ea0c0d3 100644 --- a/Utilities/cmllpkgc/CMakeLists.txt +++ b/Utilities/cmllpkgc/CMakeLists.txt
@@ -7,18 +7,22 @@ endif() add_library(cmllpkgc STATIC + llpkgc.c llpkgc_file.c llpkgc_file__internal.c llpkgc_frag.c llpkgc_frag__internal.c llpkgc_dep.c llpkgc_dep__internal.c + llpkgc_whitespace__internal.c llpkgc.h + llpkgc_types.h llpkgc_file.h llpkgc_file__internal.h llpkgc_frag.h llpkgc_frag__internal.h llpkgc_dep.h llpkgc_dep__internal.h + llpkgc_whitespace__internal.h )
diff --git a/Utilities/cmllpkgc/llpkgc.c b/Utilities/cmllpkgc/llpkgc.c new file mode 100644 index 0000000..3d49108 --- /dev/null +++ b/Utilities/cmllpkgc/llpkgc.c
@@ -0,0 +1,66 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. + See accompanying file LICENSE.rst for details. */ + +#include <string.h> + +#include "llpkgc.h" + +static int field_equal(const char* name, size_t length, const char* field) { + size_t i; + if(strlen(field) != length) + return 0; + for(i = 0; i < length; i++) { + unsigned char c = (unsigned char) name[i]; + if(c >= 'A' && c <= 'Z') + c += 'a' - 'A'; + if(c != (unsigned char) field[i]) + return 0; + } + return 1; +} + +llpkgc_value_kind_t llpkgc_classify_field(const char* name, size_t length) { + static const char* const fragments[] = { + "cflags", + "cflags.private", + "cflags.shared", + "libs", + "libs.private", + "libs.shared", + }; + static const char* const dependencies[] = { + "conflicts", + "provides", + "requires", + "requires.private", + "requires.internal", + "requires.shared", + }; + size_t i; + for(i = 0; i < sizeof(fragments) / sizeof(*fragments); i++) + if(field_equal(name, length, fragments[i])) + return LLPKGC_VALUE_FRAGMENTS; + for(i = 0; i < sizeof(dependencies) / sizeof(*dependencies); i++) + if(field_equal(name, length, dependencies[i])) + return LLPKGC_VALUE_DEPENDENCIES; + return LLPKGC_VALUE_LITERAL; +} + +const char* llpkgc_dep_comparator_name(llpkgc_dep_comparator_t comparator) { + switch(comparator) { + case LLPKGC_DEP_LESS_THAN: + return "<"; + case LLPKGC_DEP_LESS_THAN_EQUAL: + return "<="; + case LLPKGC_DEP_EQUAL: + return "="; + case LLPKGC_DEP_NOT_EQUAL: + return "!="; + case LLPKGC_DEP_GREATER_THAN: + return ">"; + case LLPKGC_DEP_GREATER_THAN_EQUAL: + return ">="; + default: + return ""; + } +}
diff --git a/Utilities/cmllpkgc/llpkgc.h b/Utilities/cmllpkgc/llpkgc.h index f9df5e3..c4b32db 100644 --- a/Utilities/cmllpkgc/llpkgc.h +++ b/Utilities/cmllpkgc/llpkgc.h
@@ -1,6 +1,25 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file LICENSE.rst for details. */ +#ifndef INCLUDE_LLPKGC_H_ +#define INCLUDE_LLPKGC_H_ + #include "llpkgc_dep.h" #include "llpkgc_file.h" #include "llpkgc_frag.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* ASCII case-insensitive field classification. Unknown fields are literals. */ +LLPKGC_FILE_EXPORT +llpkgc_value_kind_t llpkgc_classify_field(const char* name, size_t length); + +LLPKGC_DEP_EXPORT +const char* llpkgc_dep_comparator_name(llpkgc_dep_comparator_t comparator); + +#ifdef __cplusplus +} +#endif +#endif /* INCLUDE_LLPKGC_H_ */
diff --git a/Utilities/cmllpkgc/llpkgc_dep.c b/Utilities/cmllpkgc/llpkgc_dep.c index c48dc43..59c72e5 100644 --- a/Utilities/cmllpkgc/llpkgc_dep.c +++ b/Utilities/cmllpkgc/llpkgc_dep.c
@@ -1,181 +1,8 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file LICENSE.rst for details. */ -#include <stdint.h> -#include <stdlib.h> -#include <string.h> - #include "llpkgc_dep.h" -#define CALLBACK_MAYBE(PARSER, NAME) \ - do { \ - const llpkgc_dep_settings_t* settings; \ - settings = \ - (const llpkgc_dep_settings_t*) (PARSER)->llpkgc_dep__settings; \ - if(settings == NULL || settings->NAME == NULL) { \ - err = 0; \ - break; \ - } \ - err = settings->NAME((PARSER)); \ - } while(0) - -#define SPAN_CALLBACK_MAYBE(PARSER, NAME, START, LEN) \ - do { \ - const llpkgc_dep_settings_t* settings; \ - settings = \ - (const llpkgc_dep_settings_t*) (PARSER)->llpkgc_dep__settings; \ - if(settings == NULL || settings->NAME == NULL) { \ - err = 0; \ - break; \ - } \ - err = settings->NAME((PARSER), (START), (LEN)); \ - if(err == -1) { \ - err = PDEP_USER; \ - llpkgc_dep_set_error_reason((PARSER), "Span callback error in " #NAME); \ - } \ - } while(0) - -enum llpkgc_dep_state { - PDEP_START = 0, - PDEP_DEP_NAME = 1, - PDEP_DEP_OP = 2, - PDEP_AFTER_OP = 3, - PDEP_DEP_VERSION = 4, -}; - -void llpkgc_dep_init(llpkgc_dep_t* parser, - const llpkgc_dep_settings_t* settings) { - llpkgc_dep__internal_init(parser); - parser->llpkgc_dep__settings = (void*) settings; -} - -void llpkgc_dep_reset(llpkgc_dep_t* parser) { - llpkgc_dep_settings_t* settings = parser->llpkgc_dep__settings; - void* data = parser->data; - llpkgc_dep__internal_init(parser); - parser->llpkgc_dep__settings = settings; - parser->data = data; -} - -void llpkgc_dep_settings_init(llpkgc_dep_settings_t* settings) { - memset(settings, 0, sizeof(*settings)); -} - -llpkgc_dep_errno_t llpkgc_dep_execute(llpkgc_dep_t* parser, const char* data, - size_t len) { - return llpkgc_dep__internal_execute(parser, data, data + len); -} - -llpkgc_dep_errno_t llpkgc_dep_finish(llpkgc_dep_t* parser) { - int err = PDEP_OK; - - if(parser->error != 0) { - return parser->error; - } - - switch(parser->llpkgc_dep__state) { - case PDEP_DEP_NAME: - CALLBACK_MAYBE(parser, on_dep_complete); - if(err != PDEP_OK) { - parser->error = err; - return err; - } - break; - - case PDEP_DEP_OP: - case PDEP_AFTER_OP: - case PDEP_DEP_VERSION: - CALLBACK_MAYBE(parser, on_dep_complete); - if(err != PDEP_OK) { - parser->error = err; - return err; - } - break; - - case PDEP_START: - break; - } - - CALLBACK_MAYBE(parser, on_dep_list_complete); - if(err != PDEP_OK) { - parser->error = err; - return err; - } - - return PDEP_OK; -} - -void llpkgc_dep_pause(llpkgc_dep_t* parser) { - if(parser->error != PDEP_OK) { - return; - } - parser->error = PDEP_PAUSED; - parser->reason = "Paused"; -} - -void llpkgc_dep_resume(llpkgc_dep_t* parser) { - if(parser->error != PDEP_PAUSED) { - return; - } - parser->error = 0; -} - -llpkgc_dep_errno_t llpkgc_dep_get_errno(const llpkgc_dep_t* parser) { - return parser->error; -} - -const char* llpkgc_dep_get_error_reason(const llpkgc_dep_t* parser) { - return parser->reason; -} - -void llpkgc_dep_set_error_reason(llpkgc_dep_t* parser, const char* reason) { - parser->reason = reason; -} - -const char* llpkgc_dep_get_error_pos(const llpkgc_dep_t* parser) { - return parser->error_pos; -} - -const char* llpkgc_dep_errno_name(llpkgc_dep_errno_t err) { - switch(err) { - case PDEP_OK: - return "PDEP_OK"; - case PDEP_INTERNAL: - return "PDEP_INTERNAL"; - case PDEP_PAUSED: - return "PDEP_PAUSED"; - case PDEP_USER: - return "PDEP_USER"; - case PDEP_UNFINISHED: - return "PDEP_UNFINISHED"; - } - return "INVALID_ERRNO"; -} - -int llpkgc_dep__dep_name(llpkgc_dep_t* s, const char* p, - const char* endp) { - int err; - SPAN_CALLBACK_MAYBE(s, on_dep_name, p, endp - p); - return err; -} - -int llpkgc_dep__dep_op(llpkgc_dep_t* s, const char* p, - const char* endp) { - int err; - SPAN_CALLBACK_MAYBE(s, on_dep_op, p, endp - p); - return err; -} - -int llpkgc_dep__dep_version(llpkgc_dep_t* s, const char* p, - const char* endp) { - int err; - SPAN_CALLBACK_MAYBE(s, on_dep_version, p, endp - p); - return err; -} - -int llpkgc_dep__dep_complete(llpkgc_dep_t* s, const char* p, - const char* endp) { - int err; - CALLBACK_MAYBE(s, on_dep_complete); - return err; +llpkgc_dep_comparator_t llpkgc_dep_get_comparator(const llpkgc_dep_t* parser) { + return (llpkgc_dep_comparator_t) parser->comparator; }
diff --git a/Utilities/cmllpkgc/llpkgc_dep.h b/Utilities/cmllpkgc/llpkgc_dep.h index 18a3aa8..b37767e 100644 --- a/Utilities/cmllpkgc/llpkgc_dep.h +++ b/Utilities/cmllpkgc/llpkgc_dep.h
@@ -9,6 +9,7 @@ #include <stddef.h> #include "llpkgc_dep__internal.h" +#include "llpkgc_types.h" #if defined(_MSC_VER) #define LLPKGC_DEP_EXPORT __declspec(dllexport) @@ -19,13 +20,11 @@ typedef llpkgc_dep__internal_t llpkgc_dep_t; typedef struct llpkgc_dep_settings_s llpkgc_dep_settings_t; -typedef int ( - *llpkgc_dep_data_cb)(llpkgc_dep_t*, const char* at, size_t length); +typedef int (*llpkgc_dep_data_cb)(llpkgc_dep_t*, const char* at, size_t length); typedef int (*llpkgc_dep_cb)(llpkgc_dep_t*); struct llpkgc_dep_settings_s { llpkgc_dep_data_cb on_dep_name; - llpkgc_dep_data_cb on_dep_op; llpkgc_dep_data_cb on_dep_version; llpkgc_dep_cb on_dep_complete; @@ -33,11 +32,11 @@ }; enum llpkgc_dep_errno { - PDEP_INTERNAL = -1, PDEP_OK = 0, - PDEP_PAUSED = 1, PDEP_USER = 2, PDEP_UNFINISHED = 3, + PDEP_INVALID = 4, + PDEP_INTERNAL = 5, }; typedef enum llpkgc_dep_errno llpkgc_dep_errno_t; @@ -51,6 +50,8 @@ LLPKGC_DEP_EXPORT void llpkgc_dep_settings_init(llpkgc_dep_settings_t* settings); +/* Successful chunks are fully consumed and may be released immediately. + * Subsequent chunks need not be contiguous. Callback spans are borrowed. */ LLPKGC_DEP_EXPORT llpkgc_dep_errno_t llpkgc_dep_execute(llpkgc_dep_t* parser, const char* data, size_t len); @@ -58,11 +59,9 @@ LLPKGC_DEP_EXPORT llpkgc_dep_errno_t llpkgc_dep_finish(llpkgc_dep_t* parser); +/* Read during on_dep_complete. Unknown/absent operators are ANY. */ LLPKGC_DEP_EXPORT -void llpkgc_dep_pause(llpkgc_dep_t* parser); - -LLPKGC_DEP_EXPORT -void llpkgc_dep_resume(llpkgc_dep_t* parser); +llpkgc_dep_comparator_t llpkgc_dep_get_comparator(const llpkgc_dep_t* parser); LLPKGC_DEP_EXPORT llpkgc_dep_errno_t llpkgc_dep_get_errno(const llpkgc_dep_t* parser);
diff --git a/Utilities/cmllpkgc/llpkgc_dep__internal.c b/Utilities/cmllpkgc/llpkgc_dep__internal.c index eb27e94..bf57866 100644 --- a/Utilities/cmllpkgc/llpkgc_dep__internal.c +++ b/Utilities/cmllpkgc/llpkgc_dep__internal.c
@@ -39,80 +39,114 @@ enum llparse_state_e { s_error, - s_n_llpkgc_dep__internal__n_invoke_llpkgc_dep__dep_complete, - s_n_llpkgc_dep__internal__n_pkgc_dep_dep_version, - s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__dep_version, - s_n_llpkgc_dep__internal__n_pkgc_dep_after_op, - s_n_llpkgc_dep__internal__n_pkgc_dep_dep_op, - s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__dep_op, - s_n_llpkgc_dep__internal__n_invoke_update_llpkgc_dep__state_1, - s_n_llpkgc_dep__internal__n_pkgc_dep_name_ws, - s_n_llpkgc_dep__internal__n_pkgc_dep_dep_name, - s_n_llpkgc_dep__internal__n_pkgc_dep_first_dep_name, - s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__dep_name, - s_n_llpkgc_dep__internal__n_pkgc_dep_start, + s_n_llpkgc_dep__internal__n_invoke_llpkgc_dep__on_dep_complete, + s_n_llpkgc_dep__internal__n_version, + s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__on_dep_version, + s_n_llpkgc_dep__internal__n_before_version, + s_n_llpkgc_dep__internal__n_unknown_operator, + s_n_llpkgc_dep__internal__n_operator_end, + s_n_llpkgc_dep__internal__n_not, + s_n_llpkgc_dep__internal__n_less_than, + s_n_llpkgc_dep__internal__n_greater_than, + s_n_llpkgc_dep__internal__n_operator, + s_n_llpkgc_dep__internal__n_invoke_update_finish_2, + s_n_llpkgc_dep__internal__n_after_name, + s_n_llpkgc_dep__internal__n_invoke_update_finish_1, + s_n_llpkgc_dep__internal__n_invoke_update_finish_21, + s_n_llpkgc_dep__internal__n_name, + s_n_llpkgc_dep__internal__n_first_name_character, + s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__on_dep_name, + s_n_llpkgc_dep__internal__n_start, }; typedef enum llparse_state_e llparse_state_t; -int llpkgc_dep__dep_name( +int llpkgc_dep__on_dep_name( llpkgc_dep__internal_t* s, const unsigned char* p, const unsigned char* endp); -int llpkgc_dep__dep_op( +int llpkgc_dep__on_dep_version( llpkgc_dep__internal_t* s, const unsigned char* p, const unsigned char* endp); -int llpkgc_dep__dep_version( +int llpkgc_dep__internal__c_update_comparator( + llpkgc_dep__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->comparator = 0; + return 0; +} + +int llpkgc_dep__internal__c_update_finish( + llpkgc_dep__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->finish = 1; + return 0; +} + +int llpkgc_dep__on_dep_complete( llpkgc_dep__internal_t* s, const unsigned char* p, const unsigned char* endp); -int llpkgc_dep__internal__c_update_llpkgc_dep__state( +int llpkgc_dep__internal__c_update_finish_6( llpkgc_dep__internal_t* state, const unsigned char* p, const unsigned char* endp) { - state->llpkgc_dep__state = 1; + state->finish = 0; return 0; } -int llpkgc_dep__internal__c_update_llpkgc_dep__state_1( +int llpkgc_dep__internal__c_update_comparator_3( llpkgc_dep__internal_t* state, const unsigned char* p, const unsigned char* endp) { - state->llpkgc_dep__state = 2; + state->comparator = 4; return 0; } -int llpkgc_dep__internal__c_update_llpkgc_dep__state_2( +int llpkgc_dep__internal__c_update_comparator_5( llpkgc_dep__internal_t* state, const unsigned char* p, const unsigned char* endp) { - state->llpkgc_dep__state = 3; + state->comparator = 1; return 0; } -int llpkgc_dep__dep_complete( - llpkgc_dep__internal_t* s, const unsigned char* p, - const unsigned char* endp); - -int llpkgc_dep__internal__c_update_llpkgc_dep__state_3( +int llpkgc_dep__internal__c_update_comparator_7( llpkgc_dep__internal_t* state, const unsigned char* p, const unsigned char* endp) { - state->llpkgc_dep__state = 0; + state->comparator = 2; return 0; } -int llpkgc_dep__internal__c_update_llpkgc_dep__state_4( +int llpkgc_dep__internal__c_update_comparator_8( llpkgc_dep__internal_t* state, const unsigned char* p, const unsigned char* endp) { - state->llpkgc_dep__state = 4; + state->comparator = 3; + return 0; +} + +int llpkgc_dep__internal__c_update_comparator_9( + llpkgc_dep__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->comparator = 5; + return 0; +} + +int llpkgc_dep__internal__c_update_comparator_11( + llpkgc_dep__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->comparator = 6; return 0; } int llpkgc_dep__internal_init(llpkgc_dep__internal_t* state) { memset(state, 0, sizeof(*state)); - state->_current = (void*) (intptr_t) s_n_llpkgc_dep__internal__n_pkgc_dep_start; + state->_current = (void*) (intptr_t) s_n_llpkgc_dep__internal__n_start; return 0; } @@ -122,250 +156,469 @@ const unsigned char* endp) { int match; switch ((llparse_state_t) (intptr_t) state->_current) { - case s_n_llpkgc_dep__internal__n_invoke_llpkgc_dep__dep_complete: - s_n_llpkgc_dep__internal__n_invoke_llpkgc_dep__dep_complete: { - switch (llpkgc_dep__dep_complete(state, p, endp)) { + case s_n_llpkgc_dep__internal__n_invoke_llpkgc_dep__on_dep_complete: + s_n_llpkgc_dep__internal__n_invoke_llpkgc_dep__on_dep_complete: { + switch (llpkgc_dep__on_dep_complete(state, p, endp)) { case 0: - goto s_n_llpkgc_dep__internal__n_invoke_update_llpkgc_dep__state_3; + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_6; + case 5: + goto s_n_llpkgc_dep__internal__n_error_1; default: goto s_n_llpkgc_dep__internal__n_error; } UNREACHABLE; } - case s_n_llpkgc_dep__internal__n_pkgc_dep_dep_version: - s_n_llpkgc_dep__internal__n_pkgc_dep_dep_version: { + case s_n_llpkgc_dep__internal__n_version: + s_n_llpkgc_dep__internal__n_version: { if (p == endp) { - return s_n_llpkgc_dep__internal__n_pkgc_dep_dep_version; + return s_n_llpkgc_dep__internal__n_version; } switch (*p) { case 9: { - goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__dep_version; + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_version; + } + case 10: { + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_version; + } + case 11: { + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_version; + } + case 12: { + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_version; + } + case 13: { + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_version; } case ' ': { - goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__dep_version; + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_version; } case ',': { - goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__dep_version; + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_version; } default: { p++; - goto s_n_llpkgc_dep__internal__n_pkgc_dep_dep_version; + goto s_n_llpkgc_dep__internal__n_version; } } UNREACHABLE; } - case s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__dep_version: - s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__dep_version: { + case s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__on_dep_version: + s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__on_dep_version: { if (p == endp) { - return s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__dep_version; + return s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__on_dep_version; } state->_span_pos0 = (void*) p; - state->_span_cb0 = llpkgc_dep__dep_version; - goto s_n_llpkgc_dep__internal__n_pkgc_dep_dep_version; + state->_span_cb0 = llpkgc_dep__on_dep_version; + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_7; UNREACHABLE; } - case s_n_llpkgc_dep__internal__n_pkgc_dep_after_op: - s_n_llpkgc_dep__internal__n_pkgc_dep_after_op: { + case s_n_llpkgc_dep__internal__n_before_version: + s_n_llpkgc_dep__internal__n_before_version: { if (p == endp) { - return s_n_llpkgc_dep__internal__n_pkgc_dep_after_op; + return s_n_llpkgc_dep__internal__n_before_version; } switch (*p) { case 9: { p++; - goto s_n_llpkgc_dep__internal__n_pkgc_dep_after_op; + goto s_n_llpkgc_dep__internal__n_before_version; + } + case 10: { + p++; + goto s_n_llpkgc_dep__internal__n_before_version; + } + case 11: { + p++; + goto s_n_llpkgc_dep__internal__n_before_version; + } + case 12: { + p++; + goto s_n_llpkgc_dep__internal__n_before_version; + } + case 13: { + p++; + goto s_n_llpkgc_dep__internal__n_before_version; } case ' ': { p++; - goto s_n_llpkgc_dep__internal__n_pkgc_dep_after_op; + goto s_n_llpkgc_dep__internal__n_before_version; } case ',': { - goto s_n_llpkgc_dep__internal__n_invoke_llpkgc_dep__dep_complete; + goto s_n_llpkgc_dep__internal__n_invoke_llpkgc_dep__on_dep_complete; } default: { - goto s_n_llpkgc_dep__internal__n_invoke_update_llpkgc_dep__state_4; + goto s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__on_dep_version; } } UNREACHABLE; } - case s_n_llpkgc_dep__internal__n_pkgc_dep_dep_op: - s_n_llpkgc_dep__internal__n_pkgc_dep_dep_op: { + case s_n_llpkgc_dep__internal__n_unknown_operator: + s_n_llpkgc_dep__internal__n_unknown_operator: { if (p == endp) { - return s_n_llpkgc_dep__internal__n_pkgc_dep_dep_op; + return s_n_llpkgc_dep__internal__n_unknown_operator; } switch (*p) { case '!': { p++; - goto s_n_llpkgc_dep__internal__n_pkgc_dep_dep_op; + goto s_n_llpkgc_dep__internal__n_unknown_operator; } case '<': { p++; - goto s_n_llpkgc_dep__internal__n_pkgc_dep_dep_op; + goto s_n_llpkgc_dep__internal__n_unknown_operator; } case '=': { p++; - goto s_n_llpkgc_dep__internal__n_pkgc_dep_dep_op; + goto s_n_llpkgc_dep__internal__n_unknown_operator; } case '>': { p++; - goto s_n_llpkgc_dep__internal__n_pkgc_dep_dep_op; + goto s_n_llpkgc_dep__internal__n_unknown_operator; } default: { - goto s_n_llpkgc_dep__internal__n_invoke_update_llpkgc_dep__state_2; + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_5; } } UNREACHABLE; } - case s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__dep_op: - s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__dep_op: { + case s_n_llpkgc_dep__internal__n_operator_end: + s_n_llpkgc_dep__internal__n_operator_end: { if (p == endp) { - return s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__dep_op; + return s_n_llpkgc_dep__internal__n_operator_end; } - state->_span_pos0 = (void*) p; - state->_span_cb0 = llpkgc_dep__dep_op; - goto s_n_llpkgc_dep__internal__n_pkgc_dep_dep_op; + switch (*p) { + case '!': { + goto s_n_llpkgc_dep__internal__n_invoke_update_comparator_4; + } + case '<': { + goto s_n_llpkgc_dep__internal__n_invoke_update_comparator_4; + } + case '=': { + goto s_n_llpkgc_dep__internal__n_invoke_update_comparator_4; + } + case '>': { + goto s_n_llpkgc_dep__internal__n_invoke_update_comparator_4; + } + default: { + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_10; + } + } UNREACHABLE; } - case s_n_llpkgc_dep__internal__n_invoke_update_llpkgc_dep__state_1: - s_n_llpkgc_dep__internal__n_invoke_update_llpkgc_dep__state_1: { - switch (llpkgc_dep__internal__c_update_llpkgc_dep__state_1(state, p, endp)) { + case s_n_llpkgc_dep__internal__n_not: + s_n_llpkgc_dep__internal__n_not: { + if (p == endp) { + return s_n_llpkgc_dep__internal__n_not; + } + switch (*p) { + case '!': { + goto s_n_llpkgc_dep__internal__n_invoke_update_comparator_2; + } + case '<': { + goto s_n_llpkgc_dep__internal__n_invoke_update_comparator_2; + } + case '=': { + p++; + goto s_n_llpkgc_dep__internal__n_invoke_update_comparator_3; + } + case '>': { + goto s_n_llpkgc_dep__internal__n_invoke_update_comparator_2; + } + default: { + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_11; + } + } + UNREACHABLE; + } + case s_n_llpkgc_dep__internal__n_less_than: + s_n_llpkgc_dep__internal__n_less_than: { + if (p == endp) { + return s_n_llpkgc_dep__internal__n_less_than; + } + switch (*p) { + case '!': { + goto s_n_llpkgc_dep__internal__n_invoke_update_comparator_6; + } + case '<': { + goto s_n_llpkgc_dep__internal__n_invoke_update_comparator_6; + } + case '=': { + p++; + goto s_n_llpkgc_dep__internal__n_invoke_update_comparator_7; + } + case '>': { + goto s_n_llpkgc_dep__internal__n_invoke_update_comparator_6; + } + default: { + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_15; + } + } + UNREACHABLE; + } + case s_n_llpkgc_dep__internal__n_greater_than: + s_n_llpkgc_dep__internal__n_greater_than: { + if (p == endp) { + return s_n_llpkgc_dep__internal__n_greater_than; + } + switch (*p) { + case '!': { + goto s_n_llpkgc_dep__internal__n_invoke_update_comparator_10; + } + case '<': { + goto s_n_llpkgc_dep__internal__n_invoke_update_comparator_10; + } + case '=': { + p++; + goto s_n_llpkgc_dep__internal__n_invoke_update_comparator_11; + } + case '>': { + goto s_n_llpkgc_dep__internal__n_invoke_update_comparator_10; + } + default: { + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_20; + } + } + UNREACHABLE; + } + case s_n_llpkgc_dep__internal__n_operator: + s_n_llpkgc_dep__internal__n_operator: { + if (p == endp) { + return s_n_llpkgc_dep__internal__n_operator; + } + switch (*p) { + case '!': { + p++; + goto s_n_llpkgc_dep__internal__n_invoke_update_comparator_1; + } + case '<': { + p++; + goto s_n_llpkgc_dep__internal__n_invoke_update_comparator_5; + } + case '=': { + p++; + goto s_n_llpkgc_dep__internal__n_invoke_update_comparator_8; + } + case '>': { + p++; + goto s_n_llpkgc_dep__internal__n_invoke_update_comparator_9; + } + default: { + goto s_n_llpkgc_dep__internal__n_error_2; + } + } + UNREACHABLE; + } + case s_n_llpkgc_dep__internal__n_invoke_update_finish_2: + s_n_llpkgc_dep__internal__n_invoke_update_finish_2: { + switch (llpkgc_dep__internal__c_update_finish(state, p, endp)) { default: - goto s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__dep_op; + goto s_n_llpkgc_dep__internal__n_operator; } UNREACHABLE; } - case s_n_llpkgc_dep__internal__n_pkgc_dep_name_ws: - s_n_llpkgc_dep__internal__n_pkgc_dep_name_ws: { + case s_n_llpkgc_dep__internal__n_after_name: + s_n_llpkgc_dep__internal__n_after_name: { if (p == endp) { - return s_n_llpkgc_dep__internal__n_pkgc_dep_name_ws; + return s_n_llpkgc_dep__internal__n_after_name; } switch (*p) { case 9: { p++; - goto s_n_llpkgc_dep__internal__n_pkgc_dep_name_ws; + goto s_n_llpkgc_dep__internal__n_after_name; + } + case 10: { + p++; + goto s_n_llpkgc_dep__internal__n_after_name; + } + case 11: { + p++; + goto s_n_llpkgc_dep__internal__n_after_name; + } + case 12: { + p++; + goto s_n_llpkgc_dep__internal__n_after_name; + } + case 13: { + p++; + goto s_n_llpkgc_dep__internal__n_after_name; } case ' ': { p++; - goto s_n_llpkgc_dep__internal__n_pkgc_dep_name_ws; + goto s_n_llpkgc_dep__internal__n_after_name; } case '!': { - goto s_n_llpkgc_dep__internal__n_invoke_update_llpkgc_dep__state_1; + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_2; } case '<': { - goto s_n_llpkgc_dep__internal__n_invoke_update_llpkgc_dep__state_1; + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_2; } case '=': { - goto s_n_llpkgc_dep__internal__n_invoke_update_llpkgc_dep__state_1; + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_2; } case '>': { - goto s_n_llpkgc_dep__internal__n_invoke_update_llpkgc_dep__state_1; + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_2; } default: { - goto s_n_llpkgc_dep__internal__n_invoke_llpkgc_dep__dep_complete; + goto s_n_llpkgc_dep__internal__n_invoke_llpkgc_dep__on_dep_complete; } } UNREACHABLE; } - case s_n_llpkgc_dep__internal__n_pkgc_dep_dep_name: - s_n_llpkgc_dep__internal__n_pkgc_dep_dep_name: { + case s_n_llpkgc_dep__internal__n_invoke_update_finish_1: + s_n_llpkgc_dep__internal__n_invoke_update_finish_1: { + switch (llpkgc_dep__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_after_name; + } + UNREACHABLE; + } + case s_n_llpkgc_dep__internal__n_invoke_update_finish_21: + s_n_llpkgc_dep__internal__n_invoke_update_finish_21: { + switch (llpkgc_dep__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_after_name; + } + UNREACHABLE; + } + case s_n_llpkgc_dep__internal__n_name: + s_n_llpkgc_dep__internal__n_name: { if (p == endp) { - return s_n_llpkgc_dep__internal__n_pkgc_dep_dep_name; + return s_n_llpkgc_dep__internal__n_name; } switch (*p) { case 9: { - goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__dep_name_2; + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_name_1; + } + case 10: { + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_name_1; + } + case 11: { + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_name_1; + } + case 12: { + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_name_1; + } + case 13: { + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_name_1; } case ' ': { - goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__dep_name_2; + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_name_1; } case '!': { - goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__dep_name_3; + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_name_2; } case ',': { - goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__dep_name_4; + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_name_1; } case '<': { - goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__dep_name_3; + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_name_2; } case '=': { - goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__dep_name_3; + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_name_2; } case '>': { - goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__dep_name_3; + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_name_2; } default: { p++; - goto s_n_llpkgc_dep__internal__n_pkgc_dep_dep_name; + goto s_n_llpkgc_dep__internal__n_name; } } UNREACHABLE; } - case s_n_llpkgc_dep__internal__n_pkgc_dep_first_dep_name: - s_n_llpkgc_dep__internal__n_pkgc_dep_first_dep_name: { + case s_n_llpkgc_dep__internal__n_first_name_character: + s_n_llpkgc_dep__internal__n_first_name_character: { if (p == endp) { - return s_n_llpkgc_dep__internal__n_pkgc_dep_first_dep_name; + return s_n_llpkgc_dep__internal__n_first_name_character; } switch (*p) { case 9: { - goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__dep_name; + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_name; + } + case 10: { + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_name; + } + case 11: { + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_name; + } + case 12: { + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_name; + } + case 13: { + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_name; } case ' ': { - goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__dep_name; + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_name; } case '!': { p++; - goto s_n_llpkgc_dep__internal__n_pkgc_dep_first_dep_name; + goto s_n_llpkgc_dep__internal__n_first_name_character; } case ',': { - goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__dep_name_1; + goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_name; } case '<': { p++; - goto s_n_llpkgc_dep__internal__n_pkgc_dep_first_dep_name; + goto s_n_llpkgc_dep__internal__n_first_name_character; } case '=': { p++; - goto s_n_llpkgc_dep__internal__n_pkgc_dep_first_dep_name; + goto s_n_llpkgc_dep__internal__n_first_name_character; } case '>': { p++; - goto s_n_llpkgc_dep__internal__n_pkgc_dep_first_dep_name; + goto s_n_llpkgc_dep__internal__n_first_name_character; } default: { - goto s_n_llpkgc_dep__internal__n_invoke_update_llpkgc_dep__state_5; + goto s_n_llpkgc_dep__internal__n_name; } } UNREACHABLE; } - case s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__dep_name: - s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__dep_name: { + case s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__on_dep_name: + s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__on_dep_name: { if (p == endp) { - return s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__dep_name; + return s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__on_dep_name; } state->_span_pos0 = (void*) p; - state->_span_cb0 = llpkgc_dep__dep_name; - goto s_n_llpkgc_dep__internal__n_pkgc_dep_first_dep_name; + state->_span_cb0 = llpkgc_dep__on_dep_name; + goto s_n_llpkgc_dep__internal__n_invoke_update_finish; UNREACHABLE; } - case s_n_llpkgc_dep__internal__n_pkgc_dep_start: - s_n_llpkgc_dep__internal__n_pkgc_dep_start: { + case s_n_llpkgc_dep__internal__n_start: + s_n_llpkgc_dep__internal__n_start: { if (p == endp) { - return s_n_llpkgc_dep__internal__n_pkgc_dep_start; + return s_n_llpkgc_dep__internal__n_start; } switch (*p) { case 9: { p++; - goto s_n_llpkgc_dep__internal__n_pkgc_dep_start; + goto s_n_llpkgc_dep__internal__n_start; + } + case 10: { + p++; + goto s_n_llpkgc_dep__internal__n_start; + } + case 11: { + p++; + goto s_n_llpkgc_dep__internal__n_start; + } + case 12: { + p++; + goto s_n_llpkgc_dep__internal__n_start; + } + case 13: { + p++; + goto s_n_llpkgc_dep__internal__n_start; } case ' ': { p++; - goto s_n_llpkgc_dep__internal__n_pkgc_dep_start; + goto s_n_llpkgc_dep__internal__n_start; } case ',': { p++; - goto s_n_llpkgc_dep__internal__n_pkgc_dep_start; + goto s_n_llpkgc_dep__internal__n_start; } default: { - goto s_n_llpkgc_dep__internal__n_invoke_update_llpkgc_dep__state; + goto s_n_llpkgc_dep__internal__n_invoke_update_comparator; } } UNREACHABLE; @@ -373,158 +626,308 @@ default: UNREACHABLE; } - s_n_llpkgc_dep__internal__n_invoke_update_llpkgc_dep__state_3: { - switch (llpkgc_dep__internal__c_update_llpkgc_dep__state_3(state, p, endp)) { + s_n_llpkgc_dep__internal__n_invoke_update_finish_6: { + switch (llpkgc_dep__internal__c_update_finish_6(state, p, endp)) { default: - goto s_n_llpkgc_dep__internal__n_pkgc_dep_start; + goto s_n_llpkgc_dep__internal__n_start; } UNREACHABLE; } - s_n_llpkgc_dep__internal__n_error: { - state->error = 0x1; - state->reason = "Dep complete error"; + s_n_llpkgc_dep__internal__n_error_1: { + state->error = 0x5; + state->reason = "Internal parser error"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; UNREACHABLE; } - s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__dep_version: { + s_n_llpkgc_dep__internal__n_error: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_version: { const unsigned char* start; int err; start = state->_span_pos0; state->_span_pos0 = NULL; - err = llpkgc_dep__dep_version(state, start, p); + err = llpkgc_dep__on_dep_version(state, start, p); if (err != 0) { state->error = err; state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_dep__internal__n_invoke_llpkgc_dep__dep_complete; + state->_current = (void*) (intptr_t) s_n_llpkgc_dep__internal__n_invoke_llpkgc_dep__on_dep_complete; return s_error; } - goto s_n_llpkgc_dep__internal__n_invoke_llpkgc_dep__dep_complete; + goto s_n_llpkgc_dep__internal__n_invoke_llpkgc_dep__on_dep_complete; UNREACHABLE; } - s_n_llpkgc_dep__internal__n_invoke_update_llpkgc_dep__state_4: { - switch (llpkgc_dep__internal__c_update_llpkgc_dep__state_4(state, p, endp)) { + s_n_llpkgc_dep__internal__n_invoke_update_finish_7: { + switch (llpkgc_dep__internal__c_update_finish(state, p, endp)) { default: - goto s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__dep_version; + goto s_n_llpkgc_dep__internal__n_version; } UNREACHABLE; } - s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__dep_op: { - const unsigned char* start; - int err; - - start = state->_span_pos0; - state->_span_pos0 = NULL; - err = llpkgc_dep__dep_op(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_dep__internal__n_pkgc_dep_after_op; - return s_error; - } - goto s_n_llpkgc_dep__internal__n_pkgc_dep_after_op; - UNREACHABLE; - } - s_n_llpkgc_dep__internal__n_invoke_update_llpkgc_dep__state_2: { - switch (llpkgc_dep__internal__c_update_llpkgc_dep__state_2(state, p, endp)) { + s_n_llpkgc_dep__internal__n_invoke_update_finish_5: { + switch (llpkgc_dep__internal__c_update_finish(state, p, endp)) { default: - goto s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__dep_op; + goto s_n_llpkgc_dep__internal__n_before_version; } UNREACHABLE; } - s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__dep_name: { - const unsigned char* start; - int err; - - start = state->_span_pos0; - state->_span_pos0 = NULL; - err = llpkgc_dep__dep_name(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_dep__internal__n_pkgc_dep_name_ws; - return s_error; - } - goto s_n_llpkgc_dep__internal__n_pkgc_dep_name_ws; - UNREACHABLE; - } - s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__dep_name_1: { - const unsigned char* start; - int err; - - start = state->_span_pos0; - state->_span_pos0 = NULL; - err = llpkgc_dep__dep_name(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_dep__internal__n_invoke_llpkgc_dep__dep_complete; - return s_error; - } - goto s_n_llpkgc_dep__internal__n_invoke_llpkgc_dep__dep_complete; - UNREACHABLE; - } - s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__dep_name_2: { - const unsigned char* start; - int err; - - start = state->_span_pos0; - state->_span_pos0 = NULL; - err = llpkgc_dep__dep_name(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_dep__internal__n_pkgc_dep_name_ws; - return s_error; - } - goto s_n_llpkgc_dep__internal__n_pkgc_dep_name_ws; - UNREACHABLE; - } - s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__dep_name_3: { - const unsigned char* start; - int err; - - start = state->_span_pos0; - state->_span_pos0 = NULL; - err = llpkgc_dep__dep_name(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_dep__internal__n_invoke_update_llpkgc_dep__state_1; - return s_error; - } - goto s_n_llpkgc_dep__internal__n_invoke_update_llpkgc_dep__state_1; - UNREACHABLE; - } - s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__dep_name_4: { - const unsigned char* start; - int err; - - start = state->_span_pos0; - state->_span_pos0 = NULL; - err = llpkgc_dep__dep_name(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_dep__internal__n_invoke_llpkgc_dep__dep_complete; - return s_error; - } - goto s_n_llpkgc_dep__internal__n_invoke_llpkgc_dep__dep_complete; - UNREACHABLE; - } - s_n_llpkgc_dep__internal__n_invoke_update_llpkgc_dep__state_5: { - switch (llpkgc_dep__internal__c_update_llpkgc_dep__state(state, p, endp)) { + s_n_llpkgc_dep__internal__n_invoke_update_finish_4: { + switch (llpkgc_dep__internal__c_update_finish(state, p, endp)) { default: - goto s_n_llpkgc_dep__internal__n_pkgc_dep_dep_name; + goto s_n_llpkgc_dep__internal__n_unknown_operator; } UNREACHABLE; } - s_n_llpkgc_dep__internal__n_invoke_update_llpkgc_dep__state: { - switch (llpkgc_dep__internal__c_update_llpkgc_dep__state(state, p, endp)) { + s_n_llpkgc_dep__internal__n_invoke_update_comparator_2: { + switch (llpkgc_dep__internal__c_update_comparator(state, p, endp)) { default: - goto s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__dep_name; + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_4; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_finish_9: { + switch (llpkgc_dep__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_unknown_operator; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_comparator_4: { + switch (llpkgc_dep__internal__c_update_comparator(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_9; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_finish_10: { + switch (llpkgc_dep__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_before_version; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_finish_8: { + switch (llpkgc_dep__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_operator_end; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_comparator_3: { + switch (llpkgc_dep__internal__c_update_comparator_3(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_8; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_finish_11: { + switch (llpkgc_dep__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_before_version; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_finish_3: { + switch (llpkgc_dep__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_not; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_comparator_1: { + switch (llpkgc_dep__internal__c_update_comparator(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_3; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_finish_13: { + switch (llpkgc_dep__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_unknown_operator; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_comparator_6: { + switch (llpkgc_dep__internal__c_update_comparator(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_13; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_finish_14: { + switch (llpkgc_dep__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_operator_end; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_comparator_7: { + switch (llpkgc_dep__internal__c_update_comparator_7(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_14; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_finish_15: { + switch (llpkgc_dep__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_before_version; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_finish_12: { + switch (llpkgc_dep__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_less_than; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_comparator_5: { + switch (llpkgc_dep__internal__c_update_comparator_5(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_12; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_finish_16: { + switch (llpkgc_dep__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_operator_end; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_comparator_8: { + switch (llpkgc_dep__internal__c_update_comparator_8(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_16; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_finish_18: { + switch (llpkgc_dep__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_unknown_operator; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_comparator_10: { + switch (llpkgc_dep__internal__c_update_comparator(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_18; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_finish_19: { + switch (llpkgc_dep__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_operator_end; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_comparator_11: { + switch (llpkgc_dep__internal__c_update_comparator_11(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_19; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_finish_20: { + switch (llpkgc_dep__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_before_version; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_finish_17: { + switch (llpkgc_dep__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_greater_than; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_comparator_9: { + switch (llpkgc_dep__internal__c_update_comparator_9(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_17; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_error_2: { + state->error = 0x4; + state->reason = "Invalid dependency operator"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_name: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llpkgc_dep__on_dep_name(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llpkgc_dep__internal__n_invoke_update_finish_1; + return s_error; + } + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_1; + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_name_1: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llpkgc_dep__on_dep_name(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llpkgc_dep__internal__n_invoke_update_finish_21; + return s_error; + } + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_21; + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_span_end_llpkgc_dep__on_dep_name_2: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llpkgc_dep__on_dep_name(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llpkgc_dep__internal__n_invoke_update_finish_2; + return s_error; + } + goto s_n_llpkgc_dep__internal__n_invoke_update_finish_2; + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_finish: { + switch (llpkgc_dep__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_first_name_character; + } + UNREACHABLE; + } + s_n_llpkgc_dep__internal__n_invoke_update_comparator: { + switch (llpkgc_dep__internal__c_update_comparator(state, p, endp)) { + default: + goto s_n_llpkgc_dep__internal__n_span_start_llpkgc_dep__on_dep_name; } UNREACHABLE; } @@ -563,3 +966,138 @@ return 0; } +#include <string.h> +#include "llpkgc_dep.h" +int llpkgc_dep__on_dep_complete(llpkgc_dep_t*, const unsigned char*, const unsigned char*); + +int llpkgc_dep__on_dep_list_complete(llpkgc_dep_t* s, const unsigned char* p, const unsigned char* endp) { + const llpkgc_dep_settings_t* settings = s->settings; + int err; + if (settings == NULL || settings->on_dep_list_complete == NULL) return 0; + err = settings->on_dep_list_complete(s); + if (err != 0) { + if (s->reason == NULL) s->reason = "User callback error in on_dep_list_complete"; + s->callback_reason = (void*) s->reason; + return PDEP_USER; + } + return 0; +} + +int llpkgc_dep__on_dep_name(llpkgc_dep_t* s, const unsigned char* p, const unsigned char* endp) { + const llpkgc_dep_settings_t* settings = s->settings; + int err; + if (settings == NULL || settings->on_dep_name == NULL) return 0; + err = settings->on_dep_name(s, (const char*) p, (size_t) (endp - p)); + if (err != 0) { + if (s->reason == NULL) s->reason = "User callback error in on_dep_name"; + s->callback_reason = (void*) s->reason; + return PDEP_USER; + } + return 0; +} + +int llpkgc_dep__on_dep_version(llpkgc_dep_t* s, const unsigned char* p, const unsigned char* endp) { + const llpkgc_dep_settings_t* settings = s->settings; + int err; + if (settings == NULL || settings->on_dep_version == NULL) return 0; + err = settings->on_dep_version(s, (const char*) p, (size_t) (endp - p)); + if (err != 0) { + if (s->reason == NULL) s->reason = "User callback error in on_dep_version"; + s->callback_reason = (void*) s->reason; + return PDEP_USER; + } + return 0; +} + +int llpkgc_dep__on_dep_complete(llpkgc_dep_t* s, const unsigned char* p, const unsigned char* endp) { + const llpkgc_dep_settings_t* settings = s->settings; + int err; + if (settings == NULL || settings->on_dep_complete == NULL) return 0; + err = settings->on_dep_complete(s); + if (err != 0) { + if (s->reason == NULL) s->reason = "User callback error in on_dep_complete"; + s->callback_reason = (void*) s->reason; + return PDEP_USER; + } + return 0; +} + +void llpkgc_dep_init(llpkgc_dep_t* s, const llpkgc_dep_settings_t* settings) { + llpkgc_dep__internal_init(s); + s->settings = (void*) settings; +} +void llpkgc_dep_reset(llpkgc_dep_t* s) { + const llpkgc_dep_settings_t* settings = s->settings; + void* data = s->data; + llpkgc_dep_init(s, settings); + s->data = data; +} +void llpkgc_dep_settings_init(llpkgc_dep_settings_t* settings) { + memset(settings, 0, sizeof(*settings)); +} +llpkgc_dep_errno_t llpkgc_dep_execute(llpkgc_dep_t* s, const char* data, size_t len) { + if (s->error != 0) return s->error; + if (s->done) { + s->reason = "Input after finish"; + s->error_pos = data; + return s->error = PDEP_INVALID; + } + + if (len == 0) return PDEP_OK; + s->end = (void*) (data + len); + { + int err = llpkgc_dep__internal_execute(s, data, data + len); + if (err == PDEP_USER && s->callback_reason != NULL) + s->reason = s->callback_reason; + + return err; + } +} +llpkgc_dep_errno_t llpkgc_dep_finish(llpkgc_dep_t* s) { + int err; + if (s->error != 0) return s->error; + if (s->done) return PDEP_OK; + switch (s->finish) { + case 0: + err = llpkgc_dep__on_dep_list_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + break; +case 1: + err = llpkgc_dep__on_dep_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_dep__on_dep_list_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + break; + default: s->reason = "Invalid finish action"; return s->error = PDEP_INTERNAL; + } + s->done = 1; + return PDEP_OK; +} +llpkgc_dep_errno_t llpkgc_dep_get_errno(const llpkgc_dep_t* s) { return s->error; } +const char* llpkgc_dep_get_error_reason(const llpkgc_dep_t* s) { return s->reason; } +void llpkgc_dep_set_error_reason(llpkgc_dep_t* s, const char* reason) { s->reason = reason; } +const char* llpkgc_dep_get_error_pos(const llpkgc_dep_t* s) { return s->error_pos; } +const char* llpkgc_dep_errno_name(llpkgc_dep_errno_t err) { + switch (err) { + case PDEP_OK: return "PDEP_OK"; + case PDEP_USER: return "PDEP_USER"; + case PDEP_UNFINISHED: return "PDEP_UNFINISHED"; + case PDEP_INVALID: return "PDEP_INVALID"; + + default: return "PDEP_INTERNAL"; + } +} +
diff --git a/Utilities/cmllpkgc/llpkgc_dep__internal.h b/Utilities/cmllpkgc/llpkgc_dep__internal.h index d3bb8ea..89044fd 100644 --- a/Utilities/cmllpkgc/llpkgc_dep__internal.h +++ b/Utilities/cmllpkgc/llpkgc_dep__internal.h
@@ -22,8 +22,12 @@ const char* error_pos; void* data; void* _current; - void* llpkgc_dep__settings; - uint8_t llpkgc_dep__state; + void* settings; + void* end; + void* callback_reason; + uint32_t finish; + uint8_t done; + uint8_t comparator; }; int llpkgc_dep__internal_init(llpkgc_dep__internal_t* s);
diff --git a/Utilities/cmllpkgc/llpkgc_file.c b/Utilities/cmllpkgc/llpkgc_file.c index f56429d..478c151 100644 --- a/Utilities/cmllpkgc/llpkgc_file.c +++ b/Utilities/cmllpkgc/llpkgc_file.c
@@ -1,338 +1,87 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file LICENSE.rst for details. */ -#include <stdint.h> -#include <stdlib.h> -#include <string.h> - #include "llpkgc_file.h" +#include "llpkgc_whitespace__internal.h" -#define CALLBACK_MAYBE(PARSER, NAME) \ - do { \ - const llpkgc_file_settings_t* settings; \ - settings = \ - (const llpkgc_file_settings_t*) (PARSER)->llpkgc_file__settings; \ - if(settings == NULL || settings->NAME == NULL) { \ - err = 0; \ - break; \ - } \ - err = settings->NAME((PARSER)); \ - } while(0) +/* Callback dispatch and EOF recipes are generated from the grammar. Pending + * punctuation is owned by the parser. Deferred whitespace is borrowed only + * under the explicit PFCE_NEED_MORE retention contract. */ +int llpkgc_file__on_ident(llpkgc_file_t*, const unsigned char*, + const unsigned char*); +int llpkgc_file__on_value_literal(llpkgc_file_t*, const unsigned char*, + const unsigned char*); +int llpkgc_file__on_value_literal_complete(llpkgc_file_t*, const unsigned char*, + const unsigned char*); -#define SPAN_CALLBACK_MAYBE(PARSER, NAME, START, LEN) \ - do { \ - const llpkgc_file_settings_t* settings; \ - settings = \ - (const llpkgc_file_settings_t*) (PARSER)->llpkgc_file__settings; \ - if(settings == NULL || settings->NAME == NULL) { \ - err = 0; \ - break; \ - } \ - err = settings->NAME((PARSER), (START), (LEN)); \ - if(err == -1) { \ - err = PFCE_USER; \ - llpkgc_file_set_error_reason((PARSER), "Span callback error in " #NAME); \ - } \ - } while(0) - -enum llpkgc_file_unfinished_state { - PFUS_NONE = 0, - PFUS_IDENT = 1, - PFUS_BAREWORDS = 2, - PFUS_EXPECT_VALUE = 3, - PFUS_VALUE = 4, - PFUS_VALUE_LITERAL = 5, - PFUS_VALUE_SUBSTITUTION = 6, -}; - -void llpkgc_file_init(llpkgc_file_t* parser, - const llpkgc_file_settings_t* settings) { - llpkgc_file__internal_init(parser); - - parser->llpkgc_file__settings = (void*) settings; +int llpkgc_file__mark(llpkgc_file_t* s, const unsigned char* p, + const unsigned char* endp) { + s->mark = *p; + return 0; } -void llpkgc_file_reset(llpkgc_file_t* parser) { - llpkgc_file_settings_t* settings = parser->llpkgc_file__settings; - void* data = parser->data; - - llpkgc_file__internal_init(parser); - - parser->llpkgc_file__settings = settings; - parser->data = data; +int llpkgc_file__emit_ident_mark(llpkgc_file_t* s, const unsigned char* p, + const unsigned char* endp) { + const unsigned char* mark = &s->mark; + return llpkgc_file__on_ident(s, mark, mark + 1); } -void llpkgc_file_settings_init(llpkgc_file_settings_t* settings) { - memset(settings, 0, sizeof(*settings)); +int llpkgc_file__emit_literal_mark(llpkgc_file_t* s, const unsigned char* p, + const unsigned char* endp) { + const unsigned char* mark = &s->mark; + return llpkgc_file__on_value_literal(s, mark, mark + 1); } -llpkgc_file_errno_t llpkgc_file_execute(llpkgc_file_t* parser, const char* data, - size_t len) { - return llpkgc_file__internal_execute(parser, data, data + len); +int llpkgc_file__clear_whitespace(llpkgc_file_t* s, const unsigned char* p, + const unsigned char* endp) { + s->whitespace_start = NULL; + s->whitespace_end = NULL; + return 0; } -int llpkgc_file__line_begin(llpkgc_file_t* s, const char* p, const char* endp); -int llpkgc_file__ident_span(llpkgc_file_t* s, const char* p, const char* endp); - -llpkgc_file_errno_t llpkgc_file_finish(llpkgc_file_t* parser) { - int err = PFCE_OK; - - if(parser->error == PFCE_LOOKAHEAD) { - if(parser->error_pos == NULL) { - parser->error = PFCE_INTERNAL; - parser->reason = "Missing lookahead error position"; - return parser->error; - } - - parser->llpkgc_file__eof = 1; - llpkgc_file_resume(parser); - err = llpkgc_file_execute(parser, parser->error_pos, 1); - parser->llpkgc_file__eof = 0; - - if(err != PFCE_OK) { - return err; - } - - parser->llpkgc_file__lookahead = 0; - } else if(parser->error != 0) { - return parser->error; - } - - switch(parser->llpkgc_file__unfinished) { - case PFUS_IDENT: - case PFUS_BAREWORDS: - CALLBACK_MAYBE(parser, on_barewords_complete); - if(err != PFCE_OK) { - parser->error = err; - return err; - } - - CALLBACK_MAYBE(parser, on_value_complete); - if(err != PFCE_OK) { - parser->error = err; - return err; - } - break; - - case PFUS_EXPECT_VALUE: - case PFUS_VALUE: - CALLBACK_MAYBE(parser, on_value_complete); - if(err != PFCE_OK) { - parser->error = err; - return err; - } - break; - - case PFUS_VALUE_LITERAL: - CALLBACK_MAYBE(parser, on_value_literal_complete); - if(err != PFCE_OK) { - parser->error = err; - return err; - } - - CALLBACK_MAYBE(parser, on_value_complete); - if(err != PFCE_OK) { - parser->error = err; - return err; - } - break; - - case PFUS_VALUE_SUBSTITUTION: - parser->reason = "Invalid EOF state"; - parser->error = PFCE_UNFINISHED; - return PFCE_UNFINISHED; - - case PFUS_NONE: - break; - } - - CALLBACK_MAYBE(parser, on_pkgc_complete); - return err; +int llpkgc_file__whitespace(llpkgc_file_t* s, const unsigned char* p, + const unsigned char* endp) { + if(s->whitespace_start == NULL) + s->whitespace_start = (void*) p; + s->whitespace_end = (void*) endp; + return 0; } -void llpkgc_file_pause(llpkgc_file_t* parser) { - if(parser->error != PFCE_OK) { - return; - } - - parser->error = PFCE_PAUSED; - parser->reason = "Paused"; -} - -void llpkgc_file_resume(llpkgc_file_t* parser) { - if(parser->error != PFCE_PAUSED && parser->error != PFCE_LOOKAHEAD) { - return; - } - - parser->error = 0; -} - -llpkgc_file_errno_t llpkgc_file_get_errno(const llpkgc_file_t* parser) { - return parser->error; -} - -const char* llpkgc_file_get_error_reason(const llpkgc_file_t* parser) { - return parser->reason; -} - -void llpkgc_file_set_error_reason(llpkgc_file_t* parser, const char* reason) { - parser->reason = reason; -} - -const char* llpkgc_file_get_error_pos(const llpkgc_file_t* parser) { - return parser->error_pos; -} - -const char* llpkgc_file_errno_name(llpkgc_file_errno_t err) { - switch(err) { - case PFCE_OK: - return "PFCE_OK"; - case PFCE_INTERNAL: - return "PFCE_INTERNAL"; - case PFCE_PAUSED: - return "PFCE_PAUSED"; - case PFCE_USER: - return "PFCE_USER"; - case PFCE_UNFINISHED: - return "PFCE_UNFINISHED"; - case PFCE_LOOKAHEAD: - return "PFCE_LOOKAHEAD"; - } - return "INVALID_ERRNO"; -} - -int llpkgc_file__lookahead(llpkgc_file_t* s, const char* p, const char* endp) { - if(p == endp) { - llpkgc_file_set_error_reason(s, "Invalid lookahead state"); - return PFCE_INTERNAL; - } - - if(p + 1 == endp) { - if(s->llpkgc_file__eof != 0) { - s->llpkgc_file__lookahead = 0; - return 3; - } - - s->llpkgc_file__lookahead = (uint8_t) *p; - return PFCE_LOOKAHEAD; - } - - s->llpkgc_file__lookahead = 0; - - if(*p != '$') { - llpkgc_file_set_error_reason(s, "Invalid lookahead state"); - return PFCE_INTERNAL; - } - - switch(p[1]) { - case '{': - return 1; - case '$': - return 2; - default: - return 0; - } -} - -int llpkgc_file__lookahead_backslash(llpkgc_file_t* s, const char* p, - const char* endp) { - if(p == endp) { - llpkgc_file_set_error_reason(s, "Invalid lookahead state"); - return PFCE_INTERNAL; - } - - if(p + 1 == endp) { - if(s->llpkgc_file__eof != 0) { - s->llpkgc_file__lookahead = 0; - return 4; - } - - s->llpkgc_file__lookahead = (uint8_t) *p; - return 5; - } - - s->llpkgc_file__lookahead = 0; - - if(*p != '\\') { - llpkgc_file_set_error_reason(s, "Invalid lookahead state"); - return PFCE_INTERNAL; - } - - switch(p[1]) { - case '\r': - case '\n': - return 1; - case '#': - return 2; - case '\\': - return 3; - default: - return 0; - } -} - -int llpkgc_file__line_begin(llpkgc_file_t* s, const char* p, const char* endp) { +/* The private delivery grammar emits each physical range separately. */ +int llpkgc_file__deferred_span(llpkgc_whitespace__internal_t* delivery, + const unsigned char* p, const unsigned char* endp) { + llpkgc_file_t* s = delivery->parent; int err; - CALLBACK_MAYBE(s, on_line_begin); + if(p == endp) + return 0; + err = llpkgc_file__on_value_literal(s, p, endp); + if(err != 0) + return err; + return llpkgc_file__on_value_literal_complete(s, p, endp); +} + +int llpkgc_file__flush_whitespace_all(llpkgc_file_t* s, const unsigned char* p, + const unsigned char* endp) { + llpkgc_whitespace__internal_t delivery; + int err; + if(s->whitespace_start == NULL) + return 0; + llpkgc_whitespace__internal_init(&delivery); + delivery.parent = s; + err = llpkgc_whitespace__internal_execute(&delivery, s->whitespace_start, + s->whitespace_end); + if(err != 0 && s->reason == NULL) + s->reason = delivery.reason; + llpkgc_file__clear_whitespace(s, p, endp); return err; } -int llpkgc_file__ident_span(llpkgc_file_t* s, const char* p, const char* endp) { - int err; - SPAN_CALLBACK_MAYBE(s, on_ident, p, endp - p); - return err; +const char* llpkgc_file_get_retained_start(const llpkgc_file_t* s) { + return s->whitespace_start; } -int llpkgc_file__prop_decl_complete(llpkgc_file_t* s, const char* p, - const char* endp) { - int err; - CALLBACK_MAYBE(s, on_property_complete); - return err; -} - -int llpkgc_file__var_decl_complete(llpkgc_file_t* s, const char* p, - const char* endp) { - int err; - CALLBACK_MAYBE(s, on_variable_complete); - return err; -} - -int llpkgc_file__barewords_decl_complete(llpkgc_file_t* s, const char* p, - const char* endp) { - int err; - CALLBACK_MAYBE(s, on_barewords_complete); - return err; -} - -int llpkgc_file__lit_span(llpkgc_file_t* s, const char* p, const char* endp) { - int err; - SPAN_CALLBACK_MAYBE(s, on_value_literal, p, endp - p); - return err; -} - -int llpkgc_file__lit_complete(llpkgc_file_t* s, const char* p, - const char* endp) { - int err; - CALLBACK_MAYBE(s, on_value_literal_complete); - return err; -} - -int llpkgc_file__sub_span(llpkgc_file_t* s, const char* p, const char* endp) { - int err; - SPAN_CALLBACK_MAYBE(s, on_value_substitution, p, endp - p); - return err; -} - -int llpkgc_file__sub_complete(llpkgc_file_t* s, const char* p, - const char* endp) { - int err; - CALLBACK_MAYBE(s, on_value_substitution_complete); - return err; -} - -int llpkgc_file__val_complete(llpkgc_file_t* s, const char* p, - const char* endp) { - int err; - CALLBACK_MAYBE(s, on_value_complete); - return err; +size_t llpkgc_file_get_retained_length(const llpkgc_file_t* s) { + if(s->whitespace_start == NULL) + return 0; + return (size_t) ((const char*) s->end - (const char*) s->whitespace_start); }
diff --git a/Utilities/cmllpkgc/llpkgc_file.h b/Utilities/cmllpkgc/llpkgc_file.h index c282fc4..26189a4 100644 --- a/Utilities/cmllpkgc/llpkgc_file.h +++ b/Utilities/cmllpkgc/llpkgc_file.h
@@ -28,7 +28,6 @@ llpkgc_file_data_cb on_value_literal; llpkgc_file_data_cb on_value_substitution; - llpkgc_file_cb on_line_begin; llpkgc_file_cb on_property_complete; llpkgc_file_cb on_variable_complete; llpkgc_file_cb on_barewords_complete; @@ -39,12 +38,12 @@ }; enum llpkgc_file_errno { - PFCE_INTERNAL = -1, PFCE_OK = 0, - PFCE_PAUSED = 1, + PFCE_NEED_MORE = 1, PFCE_USER = 2, PFCE_UNFINISHED = 3, - PFCE_LOOKAHEAD = 4, + PFCE_INVALID = 4, + PFCE_INTERNAL = 5, }; typedef enum llpkgc_file_errno llpkgc_file_errno_t; @@ -58,6 +57,9 @@ LLPKGC_FILE_EXPORT void llpkgc_file_settings_init(llpkgc_file_settings_t* settings); +/* OK consumes and releases the supplied input; the next chunk may have + * independent storage/lifetime. NEED_MORE consumes input but retains the + * explicit range below. Callback spans must be copied or retained by callers. */ LLPKGC_FILE_EXPORT llpkgc_file_errno_t llpkgc_file_execute(llpkgc_file_t* parser, const char* data, size_t len); @@ -65,11 +67,13 @@ LLPKGC_FILE_EXPORT llpkgc_file_errno_t llpkgc_file_finish(llpkgc_file_t* parser); +/* On NEED_MORE only: keep this range alive and extend input contiguously, or + * call finish(). Bytes before this range may be released. No input replay. */ LLPKGC_FILE_EXPORT -void llpkgc_file_pause(llpkgc_file_t* parser); +const char* llpkgc_file_get_retained_start(const llpkgc_file_t* parser); LLPKGC_FILE_EXPORT -void llpkgc_file_resume(llpkgc_file_t* parser); +size_t llpkgc_file_get_retained_length(const llpkgc_file_t* parser); LLPKGC_FILE_EXPORT llpkgc_file_errno_t llpkgc_file_get_errno(const llpkgc_file_t* parser);
diff --git a/Utilities/cmllpkgc/llpkgc_file__internal.c b/Utilities/cmllpkgc/llpkgc_file__internal.c index 0198f45..70aab75 100644 --- a/Utilities/cmllpkgc/llpkgc_file__internal.c +++ b/Utilities/cmllpkgc/llpkgc_file__internal.c
@@ -37,316 +37,194 @@ typedef int (*llpkgc_file__internal__span_cb)( llpkgc_file__internal_t*, const char*, const char*); -static const unsigned char llparse_blob0[] = { - '\\', '\\' -}; -static const unsigned char llparse_blob1[] = { - '$', '{' -}; -static const unsigned char llparse_blob2[] = { - '\\', '\\' -}; -static const unsigned char llparse_blob3[] = { - '\\', '\\' -}; - -enum llparse_match_status_e { - kMatchComplete, - kMatchPause, - kMatchMismatch -}; -typedef enum llparse_match_status_e llparse_match_status_t; - -struct llparse_match_s { - llparse_match_status_t status; - const unsigned char* current; -}; -typedef struct llparse_match_s llparse_match_t; - -static llparse_match_t llparse__match_sequence_id( - llpkgc_file__internal_t* s, const unsigned char* p, - const unsigned char* endp, - const unsigned char* seq, uint32_t seq_len) { - uint32_t index; - llparse_match_t res; - - index = s->_index; - for (; p != endp; p++) { - unsigned char current; - - current = *p; - if (current == seq[index]) { - if (++index == seq_len) { - res.status = kMatchComplete; - goto reset; - } - } else { - res.status = kMatchMismatch; - goto reset; - } - } - s->_index = index; - res.status = kMatchPause; - res.current = p; - return res; -reset: - s->_index = 0; - res.current = p; - return res; -} - enum llparse_state_e { s_error, - s_n_llpkgc_file__internal__n_pkgc_file_comment, - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__barewords_decl_complete, - s_n_llpkgc_file__internal__n_pkgc_file_barewords_backslash_literal, - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_1, - s_n_llpkgc_file__internal__n_pkgc_file_barewords_maybe_cr, - s_n_llpkgc_file__internal__n_pkgc_file_barewords_maybe_lf, - s_n_llpkgc_file__internal__n_pkgc_file_barewords_line_end, - s_n_llpkgc_file__internal__n_pkgc_file_barewords_continue_line, - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_2, - s_n_llpkgc_file__internal__n_pkgc_file_barewords_escaped_comment, - s_n_llpkgc_file__internal__n_pkgc_file_barewords_double_backslash, - s_n_llpkgc_file__internal__n_pkgc_file_barewords_backslash_eof, - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_1, - s_n_llpkgc_file__internal__n_pkgc_file_barewords, - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span, - s_n_llpkgc_file__internal__n_pkgc_file_expect_ident_escaped_comment, - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_3, - s_n_llpkgc_file__internal__n_pkgc_file_start_barewords_backslash_eof, - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_4, - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash, - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete, - s_n_llpkgc_file__internal__n_pkgc_file_value_literal_dollar_literal, - s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_doubled_literal, - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_1, - s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_doubled, - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_2, - s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_eof, - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_2, - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_2, - s_n_llpkgc_file__internal__n_pkgc_file_line_maybe_cr, - s_n_llpkgc_file__internal__n_pkgc_file_line_maybe_lf, - s_n_llpkgc_file__internal__n_pkgc_file_line_end, - s_n_llpkgc_file__internal__n_pkgc_file_continue_line, - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_3, - s_n_llpkgc_file__internal__n_pkgc_file_value_escaped_comment, - s_n_llpkgc_file__internal__n_pkgc_file_double_backslash, - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_4, - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_3, - s_n_llpkgc_file__internal__n_pkgc_file_value_backslash_eof, - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_5, - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_2, - s_n_llpkgc_file__internal__n_pkgc_file_value, - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__sub_complete, - s_n_llpkgc_file__internal__n_pkgc_file_substitution, - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__sub_span, - s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_substitution, - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_1, - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_4, - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_5, - s_n_llpkgc_file__internal__n_pkgc_file_value_literal_dollar_eof, - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_1, - s_n_llpkgc_file__internal__n_pkgc_file_backslash_literal, - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_6, - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_7, - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_8, - s_n_llpkgc_file__internal__n_pkgc_file_value_literal_backslash_eof, - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_3, - s_n_llpkgc_file__internal__n_pkgc_file_value_literal, - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span, - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_6, - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead, - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_7, - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_8, - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_4, - s_n_llpkgc_file__internal__n_pkgc_file_expect_value, - s_n_llpkgc_file__internal__n_pkgc_file_maybe_separator_backslash_literal, - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_6, - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_7, - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_5, - s_n_llpkgc_file__internal__n_pkgc_file_maybe_separator, - s_n_llpkgc_file__internal__n_pkgc_file_ident_backslash_literal, - s_n_llpkgc_file__internal__n_pkgc_file_ident_maybe_cr, - s_n_llpkgc_file__internal__n_pkgc_file_ident_maybe_lf, - s_n_llpkgc_file__internal__n_pkgc_file_ident_line_end, - s_n_llpkgc_file__internal__n_pkgc_file_ident_continue_line, - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_8, - s_n_llpkgc_file__internal__n_pkgc_file_ident_escaped_comment, - s_n_llpkgc_file__internal__n_pkgc_file_ident_double_backslash, - s_n_llpkgc_file__internal__n_pkgc_file_ident_backslash_eof, - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_6, - s_n_llpkgc_file__internal__n_pkgc_file_ident, - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_5, - s_n_llpkgc_file__internal__n_pkgc_file_expect_ident, + s_n_llpkgc_file__internal__n_comment, + s_n_llpkgc_file__internal__n_start_lf, + s_n_llpkgc_file__internal__n_start_cr, + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_barewords_complete, + s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident_1, + s_n_llpkgc_file__internal__n_bareword_lf, + s_n_llpkgc_file__internal__n_bareword_cr, + s_n_llpkgc_file__internal__n_bareword_escape, + s_n_llpkgc_file__internal__n_bareword_backslash, + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_1, + s_n_llpkgc_file__internal__n_bareword, + s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident, + s_n_llpkgc_file__internal__n_start_escape, + s_n_llpkgc_file__internal__n_start_backslash, + s_n_llpkgc_file__internal__n_leading_lf, + s_n_llpkgc_file__internal__n_leading_cr, + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__clear_whitespace, + s_n_llpkgc_file__internal__n_whitespace_lf, + s_n_llpkgc_file__internal__n_whitespace_cr, + s_n_llpkgc_file__internal__n_whitespace_escape, + s_n_llpkgc_file__internal__n_whitespace_backslash, + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_3, + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__flush_whitespace_all_3, + s_n_llpkgc_file__internal__n_whitespace, + s_n_llpkgc_file__internal__n_span_start_llpkgc_file__whitespace, + s_n_llpkgc_file__internal__n_substitution_end, + s_n_llpkgc_file__internal__n_substitution, + s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_value_substitution, + s_n_llpkgc_file__internal__n_dollar, + s_n_llpkgc_file__internal__n_dollar_start, + s_n_llpkgc_file__internal__n_value_lf, + s_n_llpkgc_file__internal__n_value_cr, + s_n_llpkgc_file__internal__n_value_escape, + s_n_llpkgc_file__internal__n_value_backslash, + s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_value_literal_1, + s_n_llpkgc_file__internal__n_value, + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_literal_complete, + s_n_llpkgc_file__internal__n_text, + s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_value_literal, + s_n_llpkgc_file__internal__n_leading_escape, + s_n_llpkgc_file__internal__n_leading_backslash, + s_n_llpkgc_file__internal__n_leading_whitespace, + s_n_llpkgc_file__internal__n_separator_lf, + s_n_llpkgc_file__internal__n_separator_cr, + s_n_llpkgc_file__internal__n_separator_escape, + s_n_llpkgc_file__internal__n_separator_backslash, + s_n_llpkgc_file__internal__n_separator, + s_n_llpkgc_file__internal__n_invoke_update_finish_9, + s_n_llpkgc_file__internal__n_identifier_lf, + s_n_llpkgc_file__internal__n_identifier_cr, + s_n_llpkgc_file__internal__n_identifier_escape, + s_n_llpkgc_file__internal__n_identifier_backslash, + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_7, + s_n_llpkgc_file__internal__n_identifier, + s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident_2, + s_n_llpkgc_file__internal__n_start, }; typedef enum llparse_state_e llparse_state_t; -int llpkgc_file__ident_span( +int llpkgc_file__on_ident( llpkgc_file__internal_t* s, const unsigned char* p, const unsigned char* endp); -int llpkgc_file__sub_span( +int llpkgc_file__on_value_literal( llpkgc_file__internal_t* s, const unsigned char* p, const unsigned char* endp); -int llpkgc_file__lit_span( +int llpkgc_file__on_value_substitution( llpkgc_file__internal_t* s, const unsigned char* p, const unsigned char* endp); -int llpkgc_file__lookahead_backslash( +int llpkgc_file__whitespace( llpkgc_file__internal_t* s, const unsigned char* p, const unsigned char* endp); -int llpkgc_file__internal__c_update_llpkgc_file__unfinished( +int llpkgc_file__internal__c_update_finish( llpkgc_file__internal_t* state, const unsigned char* p, const unsigned char* endp) { - state->llpkgc_file__unfinished = 2; + state->finish = 0; return 0; } -int llpkgc_file__barewords_decl_complete( +int llpkgc_file__mark( llpkgc_file__internal_t* s, const unsigned char* p, const unsigned char* endp); -int llpkgc_file__val_complete( +int llpkgc_file__internal__c_update_finish_1( + llpkgc_file__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->finish = 2; + return 0; +} + +int llpkgc_file__internal__c_update_finish_4( + llpkgc_file__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->finish = 1; + return 0; +} + +int llpkgc_file__on_barewords_complete( llpkgc_file__internal_t* s, const unsigned char* p, const unsigned char* endp); -int llpkgc_file__internal__c_update_llpkgc_file__unfinished_1( - llpkgc_file__internal_t* state, - const unsigned char* p, - const unsigned char* endp) { - state->llpkgc_file__unfinished = 0; - return 0; -} - -int llpkgc_file__internal__c_update_llpkgc_file__unfinished_4( - llpkgc_file__internal_t* state, - const unsigned char* p, - const unsigned char* endp) { - state->llpkgc_file__unfinished = 1; - return 0; -} - -int llpkgc_file__prop_decl_complete( +int llpkgc_file__on_value_complete( llpkgc_file__internal_t* s, const unsigned char* p, const unsigned char* endp); -int llpkgc_file__internal__c_update_llpkgc_file__unfinished_5( - llpkgc_file__internal_t* state, - const unsigned char* p, - const unsigned char* endp) { - state->llpkgc_file__unfinished = 3; - return 0; -} - -int llpkgc_file__lookahead( +int llpkgc_file__emit_ident_mark( llpkgc_file__internal_t* s, const unsigned char* p, const unsigned char* endp); -int llpkgc_file__internal__c_update_llpkgc_file__unfinished_6( - llpkgc_file__internal_t* state, - const unsigned char* p, - const unsigned char* endp) { - state->llpkgc_file__unfinished = 5; - return 0; -} - -int llpkgc_file__lit_complete( +int llpkgc_file__on_property_complete( llpkgc_file__internal_t* s, const unsigned char* p, const unsigned char* endp); -int llpkgc_file__internal__c_update_llpkgc_file__unfinished_7( +int llpkgc_file__internal__c_update_finish_10( llpkgc_file__internal_t* state, const unsigned char* p, const unsigned char* endp) { - state->llpkgc_file__unfinished = 6; + state->finish = 3; return 0; } -int llpkgc_file__sub_complete( +int llpkgc_file__internal__c_update_finish_11( + llpkgc_file__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->finish = 5; + return 0; +} + +int llpkgc_file__internal__c_update_finish_15( + llpkgc_file__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->finish = 4; + return 0; +} + +int llpkgc_file__on_value_literal_complete( llpkgc_file__internal_t* s, const unsigned char* p, const unsigned char* endp); -int llpkgc_file__internal__c_update_llpkgc_file__unfinished_8( - llpkgc_file__internal_t* state, - const unsigned char* p, - const unsigned char* endp) { - state->llpkgc_file__unfinished = 4; - return 0; -} - -int llpkgc_file__internal__c_update_llpkgc_file__value_resume( - llpkgc_file__internal_t* state, - const unsigned char* p, - const unsigned char* endp) { - state->llpkgc_file__value_resume = 1; - return 0; -} - -int llpkgc_file__internal__c_update_llpkgc_file__line_resume( - llpkgc_file__internal_t* state, - const unsigned char* p, - const unsigned char* endp) { - state->llpkgc_file__line_resume = 1; - return 0; -} - -int llpkgc_file__internal__c_load_llpkgc_file__line_resume( - llpkgc_file__internal_t* state, - const unsigned char* p, - const unsigned char* endp) { - return state->llpkgc_file__line_resume; -} - -int llpkgc_file__internal__c_load_llpkgc_file__value_resume( - llpkgc_file__internal_t* state, - const unsigned char* p, - const unsigned char* endp) { - return state->llpkgc_file__value_resume; -} - -int llpkgc_file__internal__c_update_llpkgc_file__text_resume( - llpkgc_file__internal_t* state, - const unsigned char* p, - const unsigned char* endp) { - state->llpkgc_file__text_resume = 0; - return 0; -} - -int llpkgc_file__internal__c_load_llpkgc_file__text_resume( - llpkgc_file__internal_t* state, - const unsigned char* p, - const unsigned char* endp) { - return state->llpkgc_file__text_resume; -} - -int llpkgc_file__internal__c_update_llpkgc_file__value_resume_2( - llpkgc_file__internal_t* state, - const unsigned char* p, - const unsigned char* endp) { - state->llpkgc_file__value_resume = 0; - return 0; -} - -int llpkgc_file__var_decl_complete( +int llpkgc_file__clear_whitespace( llpkgc_file__internal_t* s, const unsigned char* p, const unsigned char* endp); -int llpkgc_file__internal__c_update_llpkgc_file__line_resume_3( +int llpkgc_file__flush_whitespace_all( + llpkgc_file__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llpkgc_file__emit_literal_mark( + llpkgc_file__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llpkgc_file__internal__c_update_finish_22( llpkgc_file__internal_t* state, const unsigned char* p, const unsigned char* endp) { - state->llpkgc_file__line_resume = 0; + state->finish = 6; return 0; } +int llpkgc_file__internal__c_update_finish_23( + llpkgc_file__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->finish = 7; + return 0; +} + +int llpkgc_file__on_value_substitution_complete( + llpkgc_file__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llpkgc_file__on_variable_complete( + llpkgc_file__internal_t* s, const unsigned char* p, + const unsigned char* endp); + int llpkgc_file__internal_init(llpkgc_file__internal_t* state) { memset(state, 0, sizeof(*state)); - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_pkgc_file_expect_ident; + state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_start; return 0; } @@ -356,668 +234,427 @@ const unsigned char* endp) { int match; switch ((llparse_state_t) (intptr_t) state->_current) { - case s_n_llpkgc_file__internal__n_pkgc_file_comment: - s_n_llpkgc_file__internal__n_pkgc_file_comment: { + case s_n_llpkgc_file__internal__n_comment: + s_n_llpkgc_file__internal__n_comment: { if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_comment; + return s_n_llpkgc_file__internal__n_comment; } switch (*p) { case 10: { p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_expect_ident; + goto s_n_llpkgc_file__internal__n_invoke_update_finish; } case 13: { p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_expect_ident; + goto s_n_llpkgc_file__internal__n_invoke_update_finish; } default: { p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_comment; + goto s_n_llpkgc_file__internal__n_comment; } } UNREACHABLE; } - case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__barewords_decl_complete: - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__barewords_decl_complete: { - switch (llpkgc_file__barewords_decl_complete(state, p, endp)) { + case s_n_llpkgc_file__internal__n_start_lf: + s_n_llpkgc_file__internal__n_start_lf: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_start_lf; + } + switch (*p) { + case 13: { + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish; + } + default: { + goto s_n_llpkgc_file__internal__n_invoke_update_finish; + } + } + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_start_cr: + s_n_llpkgc_file__internal__n_start_cr: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_start_cr; + } + switch (*p) { + case 10: { + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish; + } + default: { + goto s_n_llpkgc_file__internal__n_invoke_update_finish; + } + } + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_barewords_complete: + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_barewords_complete: { + switch (llpkgc_file__on_barewords_complete(state, p, endp)) { case 0: - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__val_complete; + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_complete; + case 5: + goto s_n_llpkgc_file__internal__n_error_4; default: goto s_n_llpkgc_file__internal__n_error_1; } UNREACHABLE; } - case s_n_llpkgc_file__internal__n_pkgc_file_barewords_backslash_literal: - s_n_llpkgc_file__internal__n_pkgc_file_barewords_backslash_literal: { + case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident_1: + s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident_1: { if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_barewords_backslash_literal; - } - switch (*p) { - case 92: { - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_barewords; - } - default: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_1: - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_1: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_1; + return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident_1; } state->_span_pos0 = (void*) p; - state->_span_cb0 = llpkgc_file__ident_span; - goto s_n_llpkgc_file__internal__n_pkgc_file_barewords; + state->_span_cb0 = llpkgc_file__on_ident; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_4; UNREACHABLE; } - case s_n_llpkgc_file__internal__n_pkgc_file_barewords_maybe_cr: - s_n_llpkgc_file__internal__n_pkgc_file_barewords_maybe_cr: { + case s_n_llpkgc_file__internal__n_bareword_lf: + s_n_llpkgc_file__internal__n_bareword_lf: { if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_barewords_maybe_cr; + return s_n_llpkgc_file__internal__n_bareword_lf; } switch (*p) { case 13: { p++; - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_1; + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident_1; } default: { - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_1; + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident_1; } } UNREACHABLE; } - case s_n_llpkgc_file__internal__n_pkgc_file_barewords_maybe_lf: - s_n_llpkgc_file__internal__n_pkgc_file_barewords_maybe_lf: { + case s_n_llpkgc_file__internal__n_bareword_cr: + s_n_llpkgc_file__internal__n_bareword_cr: { if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_barewords_maybe_lf; + return s_n_llpkgc_file__internal__n_bareword_cr; } switch (*p) { case 10: { p++; - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_1; + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident_1; } default: { - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_1; + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident_1; } } UNREACHABLE; } - case s_n_llpkgc_file__internal__n_pkgc_file_barewords_line_end: - s_n_llpkgc_file__internal__n_pkgc_file_barewords_line_end: { + case s_n_llpkgc_file__internal__n_bareword_escape: + s_n_llpkgc_file__internal__n_bareword_escape: { if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_barewords_line_end; + return s_n_llpkgc_file__internal__n_bareword_escape; } switch (*p) { case 10: { p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_barewords_maybe_cr; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_6; } case 13: { p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_barewords_maybe_lf; - } - default: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_barewords_continue_line: - s_n_llpkgc_file__internal__n_pkgc_file_barewords_continue_line: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_barewords_continue_line; - } - switch (*p) { - case 92: { - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_barewords_line_end; - } - default: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_2: - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_2: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_2; - } - state->_span_pos0 = (void*) p; - state->_span_cb0 = llpkgc_file__ident_span; - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_barewords; - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_barewords_escaped_comment: - s_n_llpkgc_file__internal__n_pkgc_file_barewords_escaped_comment: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_barewords_escaped_comment; - } - switch (*p) { - case 92: { - p++; - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_2; - } - default: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_barewords_double_backslash: - s_n_llpkgc_file__internal__n_pkgc_file_barewords_double_backslash: { - llparse_match_t match_seq; - - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_barewords_double_backslash; - } - match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob0, 2); - p = match_seq.current; - switch (match_seq.status) { - case kMatchComplete: { - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_barewords; - } - case kMatchPause: { - return s_n_llpkgc_file__internal__n_pkgc_file_barewords_double_backslash; - } - case kMatchMismatch: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_barewords_backslash_eof: - s_n_llpkgc_file__internal__n_pkgc_file_barewords_backslash_eof: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_barewords_backslash_eof; - } - switch (*p) { - case 92: { - p++; - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__ident_span; - } - default: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_1: - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_1: { - switch (llpkgc_file__lookahead_backslash(state, p, endp)) { - case 0: - goto s_n_llpkgc_file__internal__n_pkgc_file_barewords_backslash_literal; - case 1: - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__ident_span_1; - case 2: - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__ident_span_2; - case 3: - goto s_n_llpkgc_file__internal__n_pkgc_file_barewords_double_backslash; - case 4: - goto s_n_llpkgc_file__internal__n_pkgc_file_barewords_backslash_eof; - case 5: - goto s_n_llpkgc_file__internal__n_pause; - default: - goto s_n_llpkgc_file__internal__n_error; - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_barewords: - s_n_llpkgc_file__internal__n_pkgc_file_barewords: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_barewords; - } - switch (*p) { - case 10: { - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__ident_span; - } - case 13: { - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__ident_span; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_7; } case '#': { - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__ident_span; + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident; } case 92: { - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_1; + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_ident_mark; } default: { - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_barewords; + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_ident_mark_1; } } UNREACHABLE; } - case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span: - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span: { + case s_n_llpkgc_file__internal__n_bareword_backslash: + s_n_llpkgc_file__internal__n_bareword_backslash: { if (p == endp) { - return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span; + return s_n_llpkgc_file__internal__n_bareword_backslash; } - state->_span_pos0 = (void*) p; - state->_span_cb0 = llpkgc_file__ident_span; p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_barewords; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_5; UNREACHABLE; } - case s_n_llpkgc_file__internal__n_pkgc_file_expect_ident_escaped_comment: - s_n_llpkgc_file__internal__n_pkgc_file_expect_ident_escaped_comment: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_expect_ident_escaped_comment; - } - switch (*p) { - case 92: { - p++; - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished; - } - default: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_3: - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_3: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_3; - } - state->_span_pos0 = (void*) p; - state->_span_cb0 = llpkgc_file__ident_span; - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_barewords_double_backslash; - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_start_barewords_backslash_eof: - s_n_llpkgc_file__internal__n_pkgc_file_start_barewords_backslash_eof: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_start_barewords_backslash_eof; - } - switch (*p) { - case 92: { - p++; - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__ident_span; - } - default: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_4: - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_4: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_4; - } - state->_span_pos0 = (void*) p; - state->_span_cb0 = llpkgc_file__ident_span; - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_start_barewords_backslash_eof; - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash: - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash: { - switch (llpkgc_file__lookahead_backslash(state, p, endp)) { + case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_1: + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_1: { + switch (llpkgc_file__mark(state, p, endp)) { case 0: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished; - case 1: - goto s_n_llpkgc_file__internal__n_pkgc_file_expect_ident; - case 2: - goto s_n_llpkgc_file__internal__n_pkgc_file_expect_ident_escaped_comment; - case 3: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_2; - case 4: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_3; + goto s_n_llpkgc_file__internal__n_bareword_backslash; case 5: - goto s_n_llpkgc_file__internal__n_pause_1; + goto s_n_llpkgc_file__internal__n_error_10; default: - goto s_n_llpkgc_file__internal__n_error; + goto s_n_llpkgc_file__internal__n_error_5; } UNREACHABLE; } - case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete: - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete: { - switch (llpkgc_file__lit_complete(state, p, endp)) { - case 0: - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__val_complete; - default: - goto s_n_llpkgc_file__internal__n_error_4; - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_value_literal_dollar_literal: - s_n_llpkgc_file__internal__n_pkgc_file_value_literal_dollar_literal: { + case s_n_llpkgc_file__internal__n_bareword: + s_n_llpkgc_file__internal__n_bareword: { if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_value_literal_dollar_literal; - } - switch (*p) { - case '$': { - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_value_literal; - } - default: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_doubled_literal: - s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_doubled_literal: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_doubled_literal; - } - switch (*p) { - case '$': { - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_value_literal; - } - default: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_1: - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_1: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_1; - } - state->_span_pos1 = (void*) p; - goto s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_doubled_literal; - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_doubled: - s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_doubled: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_doubled; - } - switch (*p) { - case '$': { - p++; - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_1; - } - default: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_2: - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_2: { - switch (llpkgc_file__lit_complete(state, p, endp)) { - case 0: - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__val_complete; - default: - goto s_n_llpkgc_file__internal__n_error_7; - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_eof: - s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_eof: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_eof; - } - switch (*p) { - case '$': { - p++; - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__lit_span_2; - } - default: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_2: - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_2: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_2; - } - state->_span_pos1 = (void*) p; - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_eof; - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_2: - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_2: { - switch (llpkgc_file__lookahead(state, p, endp)) { - case 0: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_6; - case 1: - goto s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_substitution; - case 2: - goto s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_doubled; - case 3: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_9; - case 4: - goto s_n_llpkgc_file__internal__n_pause_2; - default: - goto s_n_llpkgc_file__internal__n_error; - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_line_maybe_cr: - s_n_llpkgc_file__internal__n_pkgc_file_line_maybe_cr: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_line_maybe_cr; - } - switch (*p) { - case 13: { - p++; - goto s_n_llpkgc_file__internal__n_invoke_load_llpkgc_file__line_resume; - } - default: { - goto s_n_llpkgc_file__internal__n_invoke_load_llpkgc_file__line_resume; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_line_maybe_lf: - s_n_llpkgc_file__internal__n_pkgc_file_line_maybe_lf: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_line_maybe_lf; + return s_n_llpkgc_file__internal__n_bareword; } switch (*p) { case 10: { - p++; - goto s_n_llpkgc_file__internal__n_invoke_load_llpkgc_file__line_resume; - } - default: { - goto s_n_llpkgc_file__internal__n_invoke_load_llpkgc_file__line_resume; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_line_end: - s_n_llpkgc_file__internal__n_pkgc_file_line_end: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_line_end; - } - switch (*p) { - case 10: { - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_line_maybe_cr; + goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_ident; } case 13: { - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_line_maybe_lf; - } - default: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_continue_line: - s_n_llpkgc_file__internal__n_pkgc_file_continue_line: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_continue_line; - } - switch (*p) { - case 92: { - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_line_end; - } - default: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_3: - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_3: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_3; - } - state->_span_pos1 = (void*) p; - goto s_n_llpkgc_file__internal__n_pkgc_file_value_literal; - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_value_escaped_comment: - s_n_llpkgc_file__internal__n_pkgc_file_value_escaped_comment: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_value_escaped_comment; - } - switch (*p) { - case 92: { - p++; - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_10; - } - default: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_double_backslash: - s_n_llpkgc_file__internal__n_pkgc_file_double_backslash: { - llparse_match_t match_seq; - - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_double_backslash; - } - match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob2, 2); - p = match_seq.current; - switch (match_seq.status) { - case kMatchComplete: { - p++; - goto s_n_llpkgc_file__internal__n_invoke_load_llpkgc_file__text_resume; - } - case kMatchPause: { - return s_n_llpkgc_file__internal__n_pkgc_file_double_backslash; - } - case kMatchMismatch: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_4: - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_4: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_4; - } - state->_span_pos1 = (void*) p; - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__text_resume; - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_3: - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_3: { - switch (llpkgc_file__lit_complete(state, p, endp)) { - case 0: - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__val_complete; - default: - goto s_n_llpkgc_file__internal__n_error_8; - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_value_backslash_eof: - s_n_llpkgc_file__internal__n_pkgc_file_value_backslash_eof: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_value_backslash_eof; - } - switch (*p) { - case 92: { - p++; - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__lit_span_3; - } - default: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_5: - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_5: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_5; - } - state->_span_pos1 = (void*) p; - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_value_backslash_eof; - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_2: - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_2: { - switch (llpkgc_file__lookahead_backslash(state, p, endp)) { - case 0: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_6; - case 1: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__value_resume; - case 2: - goto s_n_llpkgc_file__internal__n_pkgc_file_value_escaped_comment; - case 3: - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_4; - case 4: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_11; - case 5: - goto s_n_llpkgc_file__internal__n_pause_3; - default: - goto s_n_llpkgc_file__internal__n_error; - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_value: - s_n_llpkgc_file__internal__n_pkgc_file_value: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_value; - } - switch (*p) { - case 10: { - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__val_complete; - } - case 13: { - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__val_complete; + goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_ident; } case '#': { - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__val_complete; - } - case '$': { - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_2; + goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_ident; } case 92: { - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_2; + goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_ident_1; } default: { - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_10; + p++; + goto s_n_llpkgc_file__internal__n_bareword; } } UNREACHABLE; } - case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__sub_complete: - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__sub_complete: { - switch (llpkgc_file__sub_complete(state, p, endp)) { - case 0: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_8; - default: - goto s_n_llpkgc_file__internal__n_error_6; + case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident: + s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llpkgc_file__on_ident; + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_4; + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_start_escape: + s_n_llpkgc_file__internal__n_start_escape: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_start_escape; + } + switch (*p) { + case 10: { + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_2; + } + case 13: { + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_3; + } + case '#': { + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident; + } + case 92: { + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_ident_mark_2; + } + default: { + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_ident_mark_3; + } } UNREACHABLE; } - case s_n_llpkgc_file__internal__n_pkgc_file_substitution: - s_n_llpkgc_file__internal__n_pkgc_file_substitution: { + case s_n_llpkgc_file__internal__n_start_backslash: + s_n_llpkgc_file__internal__n_start_backslash: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_start_backslash; + } + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_1; + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_leading_lf: + s_n_llpkgc_file__internal__n_leading_lf: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_leading_lf; + } + switch (*p) { + case 13: { + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_13; + } + default: { + goto s_n_llpkgc_file__internal__n_invoke_update_finish_13; + } + } + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_leading_cr: + s_n_llpkgc_file__internal__n_leading_cr: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_leading_cr; + } + switch (*p) { + case 10: { + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_13; + } + default: { + goto s_n_llpkgc_file__internal__n_invoke_update_finish_13; + } + } + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__clear_whitespace: + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__clear_whitespace: { + switch (llpkgc_file__clear_whitespace(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_complete_1; + case 5: + goto s_n_llpkgc_file__internal__n_error_22; + default: + goto s_n_llpkgc_file__internal__n_error_19; + } + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_whitespace_lf: + s_n_llpkgc_file__internal__n_whitespace_lf: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_whitespace_lf; + } + switch (*p) { + case 13: { + p++; + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__whitespace; + } + default: { + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__whitespace; + } + } + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_whitespace_cr: + s_n_llpkgc_file__internal__n_whitespace_cr: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_whitespace_cr; + } + switch (*p) { + case 10: { + p++; + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__whitespace; + } + default: { + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__whitespace; + } + } + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_whitespace_escape: + s_n_llpkgc_file__internal__n_whitespace_escape: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_whitespace_escape; + } + switch (*p) { + case 10: { + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_20; + } + case 13: { + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_21; + } + case '#': { + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__flush_whitespace_all; + } + case 92: { + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__flush_whitespace_all_1; + } + default: { + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__flush_whitespace_all_2; + } + } + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_whitespace_backslash: + s_n_llpkgc_file__internal__n_whitespace_backslash: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_whitespace_backslash; + } + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_19; + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_3: + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_3: { + switch (llpkgc_file__mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_whitespace_backslash; + case 5: + goto s_n_llpkgc_file__internal__n_error_38; + default: + goto s_n_llpkgc_file__internal__n_error_23; + } + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__flush_whitespace_all_3: + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__flush_whitespace_all_3: { + switch (llpkgc_file__flush_whitespace_all(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_invoke_update_finish_16; + case 5: + goto s_n_llpkgc_file__internal__n_error_40; + default: + goto s_n_llpkgc_file__internal__n_error_39; + } + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_whitespace: + s_n_llpkgc_file__internal__n_whitespace: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_whitespace; + } + switch (*p) { + case 9: { + p++; + goto s_n_llpkgc_file__internal__n_whitespace; + } + case 10: { + goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__whitespace; + } + case 11: { + p++; + goto s_n_llpkgc_file__internal__n_whitespace; + } + case 12: { + p++; + goto s_n_llpkgc_file__internal__n_whitespace; + } + case 13: { + goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__whitespace; + } + case ' ': { + p++; + goto s_n_llpkgc_file__internal__n_whitespace; + } + case '#': { + goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__whitespace; + } + case 92: { + goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__whitespace_1; + } + default: { + goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__whitespace_2; + } + } + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__whitespace: + s_n_llpkgc_file__internal__n_span_start_llpkgc_file__whitespace: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__whitespace; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llpkgc_file__whitespace; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_17; + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_substitution_end: + s_n_llpkgc_file__internal__n_substitution_end: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_substitution_end; + } + p++; + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_substitution_complete; + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_substitution: + s_n_llpkgc_file__internal__n_substitution: { static uint8_t lookup_table[] = { 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, @@ -1037,605 +674,513 @@ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_substitution; + return s_n_llpkgc_file__internal__n_substitution; } switch (lookup_table[(uint8_t) *p]) { case 1: { p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_substitution; + goto s_n_llpkgc_file__internal__n_substitution; } case 2: { - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__sub_span; + goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_value_substitution; } default: { - goto s_n_llpkgc_file__internal__n_error_9; + goto s_n_llpkgc_file__internal__n_error_48; } } UNREACHABLE; } - case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__sub_span: - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__sub_span: { + case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_value_substitution: + s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_value_substitution: { if (p == endp) { - return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__sub_span; + return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_value_substitution; } state->_span_pos0 = (void*) p; - state->_span_cb0 = llpkgc_file__sub_span; - goto s_n_llpkgc_file__internal__n_pkgc_file_substitution; + state->_span_cb0 = llpkgc_file__on_value_substitution; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_23; UNREACHABLE; } - case s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_substitution: - s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_substitution: { - llparse_match_t match_seq; - + case s_n_llpkgc_file__internal__n_dollar: + s_n_llpkgc_file__internal__n_dollar: { if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_substitution; - } - match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob1, 2); - p = match_seq.current; - switch (match_seq.status) { - case kMatchComplete: { - p++; - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_7; - } - case kMatchPause: { - return s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_substitution; - } - case kMatchMismatch: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_1: - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_1: { - switch (llpkgc_file__lit_complete(state, p, endp)) { - case 0: - goto s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_substitution; - default: - goto s_n_llpkgc_file__internal__n_error_5; - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_4: - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_4: { - switch (llpkgc_file__lit_complete(state, p, endp)) { - case 0: - goto s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_doubled; - default: - goto s_n_llpkgc_file__internal__n_error_10; - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_5: - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_5: { - switch (llpkgc_file__lit_complete(state, p, endp)) { - case 0: - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__val_complete; - default: - goto s_n_llpkgc_file__internal__n_error_11; - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_value_literal_dollar_eof: - s_n_llpkgc_file__internal__n_pkgc_file_value_literal_dollar_eof: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_value_literal_dollar_eof; + return s_n_llpkgc_file__internal__n_dollar; } switch (*p) { case '$': { p++; - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__lit_span_5; + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_literal_mark_2; + } + case '{': { + p++; + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_value_substitution; } default: { - goto s_n_llpkgc_file__internal__n_error; + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_literal_mark_3; } } UNREACHABLE; } - case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_1: - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_1: { - switch (llpkgc_file__lookahead(state, p, endp)) { - case 0: - goto s_n_llpkgc_file__internal__n_pkgc_file_value_literal_dollar_literal; - case 1: - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__lit_span_1; - case 2: - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__lit_span_4; - case 3: - goto s_n_llpkgc_file__internal__n_pkgc_file_value_literal_dollar_eof; - case 4: - goto s_n_llpkgc_file__internal__n_pause_4; - default: - goto s_n_llpkgc_file__internal__n_error; + case s_n_llpkgc_file__internal__n_dollar_start: + s_n_llpkgc_file__internal__n_dollar_start: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_dollar_start; } + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_22; UNREACHABLE; } - case s_n_llpkgc_file__internal__n_pkgc_file_backslash_literal: - s_n_llpkgc_file__internal__n_pkgc_file_backslash_literal: { + case s_n_llpkgc_file__internal__n_value_lf: + s_n_llpkgc_file__internal__n_value_lf: { if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_backslash_literal; + return s_n_llpkgc_file__internal__n_value_lf; } switch (*p) { - case 92: { + case 13: { p++; - goto s_n_llpkgc_file__internal__n_invoke_load_llpkgc_file__text_resume; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_16; } default: { - goto s_n_llpkgc_file__internal__n_error; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_16; } } UNREACHABLE; } - case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_6: - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_6: { - switch (llpkgc_file__lit_complete(state, p, endp)) { - case 0: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__value_resume_1; - default: - goto s_n_llpkgc_file__internal__n_error_12; - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_7: - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_7: { - switch (llpkgc_file__lit_complete(state, p, endp)) { - case 0: - goto s_n_llpkgc_file__internal__n_pkgc_file_value_escaped_comment; - default: - goto s_n_llpkgc_file__internal__n_error_13; - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_8: - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_8: { - switch (llpkgc_file__lit_complete(state, p, endp)) { - case 0: - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__val_complete; - default: - goto s_n_llpkgc_file__internal__n_error_14; - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_value_literal_backslash_eof: - s_n_llpkgc_file__internal__n_pkgc_file_value_literal_backslash_eof: { + case s_n_llpkgc_file__internal__n_value_cr: + s_n_llpkgc_file__internal__n_value_cr: { if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_value_literal_backslash_eof; - } - switch (*p) { - case 92: { - p++; - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__lit_span_8; - } - default: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_3: - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_3: { - switch (llpkgc_file__lookahead_backslash(state, p, endp)) { - case 0: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__text_resume_1; - case 1: - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__lit_span_6; - case 2: - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__lit_span_7; - case 3: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__text_resume_2; - case 4: - goto s_n_llpkgc_file__internal__n_pkgc_file_value_literal_backslash_eof; - case 5: - goto s_n_llpkgc_file__internal__n_pause_5; - default: - goto s_n_llpkgc_file__internal__n_error; - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_value_literal: - s_n_llpkgc_file__internal__n_pkgc_file_value_literal: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_value_literal; + return s_n_llpkgc_file__internal__n_value_cr; } switch (*p) { case 10: { - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__lit_span; - } - case 13: { - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__lit_span; - } - case '#': { - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__lit_span; - } - case '$': { - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_1; - } - case 92: { - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_3; + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_16; } default: { - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_value_literal; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_16; } } UNREACHABLE; } - case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span: - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span: { + case s_n_llpkgc_file__internal__n_value_escape: + s_n_llpkgc_file__internal__n_value_escape: { if (p == endp) { - return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span; - } - state->_span_pos1 = (void*) p; - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_value_literal; - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_6: - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_6: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_6; - } - state->_span_pos1 = (void*) p; - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_eof; - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead: - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead: { - switch (llpkgc_file__lookahead(state, p, endp)) { - case 0: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_6; - case 1: - goto s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_substitution; - case 2: - goto s_n_llpkgc_file__internal__n_pkgc_file_value_dollar_doubled; - case 3: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_12; - case 4: - goto s_n_llpkgc_file__internal__n_pause_6; - default: - goto s_n_llpkgc_file__internal__n_error; - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_7: - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_7: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_7; - } - state->_span_pos1 = (void*) p; - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__text_resume_3; - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_8: - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_8: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_8; - } - state->_span_pos1 = (void*) p; - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_value_backslash_eof; - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_4: - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_4: { - switch (llpkgc_file__lookahead_backslash(state, p, endp)) { - case 0: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_6; - case 1: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__value_resume_2; - case 2: - goto s_n_llpkgc_file__internal__n_pkgc_file_value_escaped_comment; - case 3: - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_7; - case 4: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_13; - case 5: - goto s_n_llpkgc_file__internal__n_pause_7; - default: - goto s_n_llpkgc_file__internal__n_error; - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_expect_value: - s_n_llpkgc_file__internal__n_pkgc_file_expect_value: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_expect_value; + return s_n_llpkgc_file__internal__n_value_escape; } switch (*p) { case 10: { - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__val_complete; + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_25; } case 13: { - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__val_complete; + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_26; } case '#': { - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__val_complete; - } - case '$': { - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead; + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_value_literal; } case 92: { - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_4; + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_literal_mark_4; } default: { - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_10; + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_literal_mark_5; } } UNREACHABLE; } - case s_n_llpkgc_file__internal__n_pkgc_file_maybe_separator_backslash_literal: - s_n_llpkgc_file__internal__n_pkgc_file_maybe_separator_backslash_literal: { + case s_n_llpkgc_file__internal__n_value_backslash: + s_n_llpkgc_file__internal__n_value_backslash: { if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_maybe_separator_backslash_literal; + return s_n_llpkgc_file__internal__n_value_backslash; + } + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_24; + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_value_literal_1: + s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_value_literal_1: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_value_literal_1; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llpkgc_file__on_value_literal; + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_15; + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_value: + s_n_llpkgc_file__internal__n_value: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_value; } switch (*p) { + case 9: { + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__whitespace; + } + case 10: { + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__clear_whitespace; + } + case 11: { + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__whitespace; + } + case 12: { + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__whitespace; + } + case 13: { + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__clear_whitespace; + } + case ' ': { + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__whitespace; + } + case '#': { + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__clear_whitespace; + } + case '$': { + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_4; + } case 92: { - p++; - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished; + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_5; } default: { - goto s_n_llpkgc_file__internal__n_error; + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_value_literal_1; } } UNREACHABLE; } - case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_6: - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_6: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_6; - } - state->_span_pos0 = (void*) p; - state->_span_cb0 = llpkgc_file__ident_span; - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_barewords_double_backslash; - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_7: - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_7: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_7; - } - state->_span_pos0 = (void*) p; - state->_span_cb0 = llpkgc_file__ident_span; - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_start_barewords_backslash_eof; - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_5: - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_5: { - switch (llpkgc_file__lookahead_backslash(state, p, endp)) { + case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_literal_complete: + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_literal_complete: { + switch (llpkgc_file__on_value_literal_complete(state, p, endp)) { case 0: - goto s_n_llpkgc_file__internal__n_pkgc_file_maybe_separator_backslash_literal; - case 1: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__line_resume_3; - case 2: - goto s_n_llpkgc_file__internal__n_pkgc_file_maybe_separator_backslash_literal; - case 3: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_14; - case 4: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_15; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_16; case 5: - goto s_n_llpkgc_file__internal__n_pause_8; + goto s_n_llpkgc_file__internal__n_error_64; default: - goto s_n_llpkgc_file__internal__n_error; + goto s_n_llpkgc_file__internal__n_error_18; } UNREACHABLE; } - case s_n_llpkgc_file__internal__n_pkgc_file_maybe_separator: - s_n_llpkgc_file__internal__n_pkgc_file_maybe_separator: { + case s_n_llpkgc_file__internal__n_text: + s_n_llpkgc_file__internal__n_text: { if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_maybe_separator; + return s_n_llpkgc_file__internal__n_text; + } + switch (*p) { + case 9: { + goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_value_literal; + } + case 10: { + goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_value_literal; + } + case 11: { + goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_value_literal; + } + case 12: { + goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_value_literal; + } + case 13: { + goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_value_literal; + } + case ' ': { + goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_value_literal; + } + case '#': { + goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_value_literal; + } + case '$': { + goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_value_literal; + } + case 92: { + goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_value_literal; + } + default: { + p++; + goto s_n_llpkgc_file__internal__n_text; + } + } + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_value_literal: + s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_value_literal: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_value_literal; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llpkgc_file__on_value_literal; + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_15; + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_leading_escape: + s_n_llpkgc_file__internal__n_leading_escape: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_leading_escape; + } + switch (*p) { + case 10: { + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_12; + } + case 13: { + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_14; + } + case '#': { + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_value_literal; + } + case 92: { + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_literal_mark_6; + } + default: { + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_literal_mark_7; + } + } + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_leading_backslash: + s_n_llpkgc_file__internal__n_leading_backslash: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_leading_backslash; + } + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_11; + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_leading_whitespace: + s_n_llpkgc_file__internal__n_leading_whitespace: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_leading_whitespace; } switch (*p) { case 9: { p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_maybe_separator; + goto s_n_llpkgc_file__internal__n_leading_whitespace; } - case 10: { - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__barewords_decl_complete; + case 11: { + p++; + goto s_n_llpkgc_file__internal__n_leading_whitespace; } - case 13: { - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__barewords_decl_complete; + case 12: { + p++; + goto s_n_llpkgc_file__internal__n_leading_whitespace; } case ' ': { p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_maybe_separator; + goto s_n_llpkgc_file__internal__n_leading_whitespace; + } + case 92: { + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_2; + } + default: { + goto s_n_llpkgc_file__internal__n_invoke_update_finish_16; + } + } + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_separator_lf: + s_n_llpkgc_file__internal__n_separator_lf: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_separator_lf; + } + switch (*p) { + case 13: { + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_9; + } + default: { + goto s_n_llpkgc_file__internal__n_invoke_update_finish_9; + } + } + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_separator_cr: + s_n_llpkgc_file__internal__n_separator_cr: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_separator_cr; + } + switch (*p) { + case 10: { + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_9; + } + default: { + goto s_n_llpkgc_file__internal__n_invoke_update_finish_9; + } + } + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_separator_escape: + s_n_llpkgc_file__internal__n_separator_escape: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_separator_escape; + } + switch (*p) { + case 10: { + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_29; + } + case 13: { + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_30; } case '#': { - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__barewords_decl_complete; + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident; + } + case 92: { + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_ident_mark_4; + } + default: { + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_ident_mark_5; + } + } + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_separator_backslash: + s_n_llpkgc_file__internal__n_separator_backslash: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_separator_backslash; + } + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_28; + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_separator: + s_n_llpkgc_file__internal__n_separator: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_separator; + } + switch (*p) { + case 9: { + p++; + goto s_n_llpkgc_file__internal__n_separator; + } + case 10: { + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_barewords_complete; + } + case 11: { + p++; + goto s_n_llpkgc_file__internal__n_separator; + } + case 12: { + p++; + goto s_n_llpkgc_file__internal__n_separator; + } + case 13: { + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_barewords_complete; + } + case ' ': { + p++; + goto s_n_llpkgc_file__internal__n_separator; + } + case '#': { + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_barewords_complete; } case ':': { p++; - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__prop_decl_complete; + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_property_complete; } case '=': { p++; - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__var_decl_complete; + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_variable_complete; } case 92: { - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_5; + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_6; } default: { - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished; + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident_1; } } UNREACHABLE; } - case s_n_llpkgc_file__internal__n_pkgc_file_ident_backslash_literal: - s_n_llpkgc_file__internal__n_pkgc_file_ident_backslash_literal: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_ident_backslash_literal; - } - switch (*p) { - case 92: { - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_barewords; - } - default: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_ident_maybe_cr: - s_n_llpkgc_file__internal__n_pkgc_file_ident_maybe_cr: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_ident_maybe_cr; - } - switch (*p) { - case 13: { - p++; - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_5; - } - default: { - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_5; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_ident_maybe_lf: - s_n_llpkgc_file__internal__n_pkgc_file_ident_maybe_lf: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_ident_maybe_lf; - } - switch (*p) { - case 10: { - p++; - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_5; - } - default: { - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_5; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_ident_line_end: - s_n_llpkgc_file__internal__n_pkgc_file_ident_line_end: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_ident_line_end; - } - switch (*p) { - case 10: { - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_ident_maybe_cr; - } - case 13: { - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_ident_maybe_lf; - } - default: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_ident_continue_line: - s_n_llpkgc_file__internal__n_pkgc_file_ident_continue_line: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_ident_continue_line; - } - switch (*p) { - case 92: { - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_ident_line_end; - } - default: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_8: - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_8: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_8; - } - state->_span_pos0 = (void*) p; - state->_span_cb0 = llpkgc_file__ident_span; - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_barewords; - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_ident_escaped_comment: - s_n_llpkgc_file__internal__n_pkgc_file_ident_escaped_comment: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_ident_escaped_comment; - } - switch (*p) { - case 92: { - p++; - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_8; - } - default: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_ident_double_backslash: - s_n_llpkgc_file__internal__n_pkgc_file_ident_double_backslash: { - llparse_match_t match_seq; - - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_ident_double_backslash; - } - match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob3, 2); - p = match_seq.current; - switch (match_seq.status) { - case kMatchComplete: { - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_barewords; - } - case kMatchPause: { - return s_n_llpkgc_file__internal__n_pkgc_file_ident_double_backslash; - } - case kMatchMismatch: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_pkgc_file_ident_backslash_eof: - s_n_llpkgc_file__internal__n_pkgc_file_ident_backslash_eof: { - if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_ident_backslash_eof; - } - switch (*p) { - case 92: { - p++; - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__ident_span; - } - default: { - goto s_n_llpkgc_file__internal__n_error; - } - } - UNREACHABLE; - } - case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_6: - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_6: { - switch (llpkgc_file__lookahead_backslash(state, p, endp)) { - case 0: - goto s_n_llpkgc_file__internal__n_pkgc_file_ident_backslash_literal; - case 1: - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__ident_span_4; - case 2: - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__ident_span_5; - case 3: - goto s_n_llpkgc_file__internal__n_pkgc_file_ident_double_backslash; - case 4: - goto s_n_llpkgc_file__internal__n_pkgc_file_ident_backslash_eof; - case 5: - goto s_n_llpkgc_file__internal__n_pause_9; + case s_n_llpkgc_file__internal__n_invoke_update_finish_9: + s_n_llpkgc_file__internal__n_invoke_update_finish_9: { + switch (llpkgc_file__internal__c_update_finish_4(state, p, endp)) { default: - goto s_n_llpkgc_file__internal__n_error; + goto s_n_llpkgc_file__internal__n_separator; } UNREACHABLE; } - case s_n_llpkgc_file__internal__n_pkgc_file_ident: - s_n_llpkgc_file__internal__n_pkgc_file_ident: { + case s_n_llpkgc_file__internal__n_identifier_lf: + s_n_llpkgc_file__internal__n_identifier_lf: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_identifier_lf; + } + switch (*p) { + case 13: { + p++; + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident_2; + } + default: { + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident_2; + } + } + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_identifier_cr: + s_n_llpkgc_file__internal__n_identifier_cr: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_identifier_cr; + } + switch (*p) { + case 10: { + p++; + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident_2; + } + default: { + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident_2; + } + } + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_identifier_escape: + s_n_llpkgc_file__internal__n_identifier_escape: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_identifier_escape; + } + switch (*p) { + case 10: { + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_32; + } + case 13: { + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_33; + } + case '#': { + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident; + } + case 92: { + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_ident_mark_6; + } + default: { + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_ident_mark_7; + } + } + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_identifier_backslash: + s_n_llpkgc_file__internal__n_identifier_backslash: { + if (p == endp) { + return s_n_llpkgc_file__internal__n_identifier_backslash; + } + p++; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_31; + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_7: + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_7: { + switch (llpkgc_file__mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_identifier_backslash; + case 5: + goto s_n_llpkgc_file__internal__n_error_88; + default: + goto s_n_llpkgc_file__internal__n_error_83; + } + UNREACHABLE; + } + case s_n_llpkgc_file__internal__n_identifier: + s_n_llpkgc_file__internal__n_identifier: { static uint8_t lookup_table[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0, 0, 1, 0, 0, @@ -1653,69 +1198,77 @@ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_ident; + return s_n_llpkgc_file__internal__n_identifier; } switch (lookup_table[(uint8_t) *p]) { case 1: { - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__ident_span_3; + goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_ident_2; } case 2: { - goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__ident_span; + goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_ident; } case 3: { p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_ident; + goto s_n_llpkgc_file__internal__n_identifier; } case 4: { - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_6; + goto s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_ident_3; } default: { - goto s_n_llpkgc_file__internal__n_pkgc_file_barewords; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_4; } } UNREACHABLE; } - case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_5: - s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_5: { + case s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident_2: + s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident_2: { if (p == endp) { - return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_5; + return s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident_2; } state->_span_pos0 = (void*) p; - state->_span_cb0 = llpkgc_file__ident_span; - goto s_n_llpkgc_file__internal__n_pkgc_file_ident; + state->_span_cb0 = llpkgc_file__on_ident; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_8; UNREACHABLE; } - case s_n_llpkgc_file__internal__n_pkgc_file_expect_ident: - s_n_llpkgc_file__internal__n_pkgc_file_expect_ident: { + case s_n_llpkgc_file__internal__n_start: + s_n_llpkgc_file__internal__n_start: { if (p == endp) { - return s_n_llpkgc_file__internal__n_pkgc_file_expect_ident; + return s_n_llpkgc_file__internal__n_start; } switch (*p) { case 9: { p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_expect_ident; + goto s_n_llpkgc_file__internal__n_start; } case 10: { p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_expect_ident; + goto s_n_llpkgc_file__internal__n_start; + } + case 11: { + p++; + goto s_n_llpkgc_file__internal__n_start; + } + case 12: { + p++; + goto s_n_llpkgc_file__internal__n_start; } case 13: { p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_expect_ident; + goto s_n_llpkgc_file__internal__n_start; } case ' ': { p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_expect_ident; + goto s_n_llpkgc_file__internal__n_start; } case '#': { p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_comment; + goto s_n_llpkgc_file__internal__n_comment; } case 92: { - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash; + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark; } default: { - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_4; + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident_2; } } UNREACHABLE; @@ -1723,719 +1276,1497 @@ default: UNREACHABLE; } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_1: { - switch (llpkgc_file__internal__c_update_llpkgc_file__unfinished_1(state, p, endp)) { + s_n_llpkgc_file__internal__n_invoke_update_finish: { + switch (llpkgc_file__internal__c_update_finish(state, p, endp)) { default: - goto s_n_llpkgc_file__internal__n_pkgc_file_expect_ident; + goto s_n_llpkgc_file__internal__n_start; } UNREACHABLE; } - s_n_llpkgc_file__internal__n_error_2: { - state->error = 0xa; - state->reason = "Value complete error"; + s_n_llpkgc_file__internal__n_invoke_update_finish_2: { + switch (llpkgc_file__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_start_lf; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_3: { + switch (llpkgc_file__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_start_cr; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_3: { + state->error = 0x5; + state->reason = "Internal parser error"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; UNREACHABLE; } - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__val_complete: { - switch (llpkgc_file__val_complete(state, p, endp)) { + s_n_llpkgc_file__internal__n_error_2: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_complete: { + switch (llpkgc_file__on_value_complete(state, p, endp)) { case 0: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_1; + goto s_n_llpkgc_file__internal__n_invoke_update_finish; + case 5: + goto s_n_llpkgc_file__internal__n_error_3; default: goto s_n_llpkgc_file__internal__n_error_2; } UNREACHABLE; } - s_n_llpkgc_file__internal__n_error_1: { - state->error = 0x9; - state->reason = "Barewords complete error"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_error; - return s_error; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_span_end_llpkgc_file__ident_span: { - const unsigned char* start; - int err; - - start = state->_span_pos0; - state->_span_pos0 = NULL; - err = llpkgc_file__ident_span(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__barewords_decl_complete; - return s_error; - } - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__barewords_decl_complete; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_error: { - state->error = 0xe; - state->reason = "Lookahead error"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_error; - return s_error; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_span_end_llpkgc_file__ident_span_1: { - const unsigned char* start; - int err; - - start = state->_span_pos0; - state->_span_pos0 = NULL; - err = llpkgc_file__ident_span(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) (p + 1); - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_pkgc_file_barewords_continue_line; - return s_error; - } - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_barewords_continue_line; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_span_end_llpkgc_file__ident_span_2: { - const unsigned char* start; - int err; - - start = state->_span_pos0; - state->_span_pos0 = NULL; - err = llpkgc_file__ident_span(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) (p + 1); - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_pkgc_file_barewords_escaped_comment; - return s_error; - } - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_barewords_escaped_comment; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_pause: { - state->error = 0x4; - state->reason = "Lookahead required"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_1; - return s_error; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished: { - switch (llpkgc_file__internal__c_update_llpkgc_file__unfinished(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_2: { - switch (llpkgc_file__internal__c_update_llpkgc_file__unfinished(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_3; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_3: { - switch (llpkgc_file__internal__c_update_llpkgc_file__unfinished(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_4; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_pause_1: { - state->error = 0x4; - state->reason = "Lookahead required"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash; - return s_error; - UNREACHABLE; - } s_n_llpkgc_file__internal__n_error_4: { - state->error = 0xb; - state->reason = "Value literal complete error"; + state->error = 0x5; + state->reason = "Internal parser error"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; UNREACHABLE; } - s_n_llpkgc_file__internal__n_span_end_llpkgc_file__lit_span: { + s_n_llpkgc_file__internal__n_error_1: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_ident: { const unsigned char* start; int err; - start = state->_span_pos1; - state->_span_pos1 = NULL; - err = llpkgc_file__lit_span(state, start, p); + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llpkgc_file__on_ident(state, start, p); if (err != 0) { state->error = err; state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete; + state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_barewords_complete; return s_error; } - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete; + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_barewords_complete; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_6: { + switch (llpkgc_file__internal__c_update_finish_4(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_bareword_lf; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_7: { + switch (llpkgc_file__internal__c_update_finish_4(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_bareword_cr; + } UNREACHABLE; } s_n_llpkgc_file__internal__n_error_7: { - state->error = 0xb; - state->reason = "Value literal complete error"; + state->error = 0x5; + state->reason = "Internal parser error"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; UNREACHABLE; } - s_n_llpkgc_file__internal__n_span_end_llpkgc_file__lit_span_2: { - const unsigned char* start; - int err; - - start = state->_span_pos1; - state->_span_pos1 = NULL; - err = llpkgc_file__lit_span(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_2; - return s_error; - } - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_2; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_9: { - switch (llpkgc_file__internal__c_update_llpkgc_file__unfinished_6(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_2; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_pause_2: { - state->error = 0x4; - state->reason = "Lookahead required"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_2; - return s_error; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_load_llpkgc_file__value_resume: { - switch (llpkgc_file__internal__c_load_llpkgc_file__value_resume(state, p, endp)) { - case 0: - goto s_n_llpkgc_file__internal__n_pkgc_file_expect_value; - case 1: - goto s_n_llpkgc_file__internal__n_pkgc_file_value; - default: - goto s_n_llpkgc_file__internal__n_error; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_load_llpkgc_file__line_resume: { - switch (llpkgc_file__internal__c_load_llpkgc_file__line_resume(state, p, endp)) { - case 0: - goto s_n_llpkgc_file__internal__n_pkgc_file_maybe_separator; - case 1: - goto s_n_llpkgc_file__internal__n_invoke_load_llpkgc_file__value_resume; - default: - goto s_n_llpkgc_file__internal__n_error; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__line_resume: { - switch (llpkgc_file__internal__c_update_llpkgc_file__line_resume(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_pkgc_file_continue_line; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__value_resume: { - switch (llpkgc_file__internal__c_update_llpkgc_file__value_resume(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__line_resume; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_10: { - switch (llpkgc_file__internal__c_update_llpkgc_file__unfinished_6(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_3; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_load_llpkgc_file__text_resume: { - switch (llpkgc_file__internal__c_load_llpkgc_file__text_resume(state, p, endp)) { - case 0: - goto s_n_llpkgc_file__internal__n_pkgc_file_value_literal; - default: - goto s_n_llpkgc_file__internal__n_error; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__text_resume: { - switch (llpkgc_file__internal__c_update_llpkgc_file__text_resume(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_pkgc_file_double_backslash; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_error_8: { - state->error = 0xb; - state->reason = "Value literal complete error"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_error; - return s_error; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_span_end_llpkgc_file__lit_span_3: { - const unsigned char* start; - int err; - - start = state->_span_pos1; - state->_span_pos1 = NULL; - err = llpkgc_file__lit_span(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_3; - return s_error; - } - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_3; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_11: { - switch (llpkgc_file__internal__c_update_llpkgc_file__unfinished_6(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_5; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_pause_3: { - state->error = 0x4; - state->reason = "Lookahead required"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_2; - return s_error; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_8: { - switch (llpkgc_file__internal__c_update_llpkgc_file__unfinished_8(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_pkgc_file_value; - } - UNREACHABLE; - } s_n_llpkgc_file__internal__n_error_6: { - state->error = 0xc; - state->reason = "Value substitution complete error"; + state->error = 0x2; + state->reason = "Callback error"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; UNREACHABLE; } - s_n_llpkgc_file__internal__n_span_end_llpkgc_file__sub_span: { + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_ident_mark: { + switch (llpkgc_file__emit_ident_mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident; + case 5: + goto s_n_llpkgc_file__internal__n_error_7; + default: + goto s_n_llpkgc_file__internal__n_error_6; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_9: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_8: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_ident_mark_1: { + switch (llpkgc_file__emit_ident_mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident_1; + case 5: + goto s_n_llpkgc_file__internal__n_error_9; + default: + goto s_n_llpkgc_file__internal__n_error_8; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_5: { + switch (llpkgc_file__internal__c_update_finish_1(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_bareword_escape; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_10: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_5: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_ident_1: { const unsigned char* start; int err; start = state->_span_pos0; state->_span_pos0 = NULL; - err = llpkgc_file__sub_span(state, start, p); + err = llpkgc_file__on_ident(state, start, p); if (err != 0) { state->error = err; - state->error_pos = (const char*) (p + 1); - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__sub_complete; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_1; return s_error; } - p++; - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__sub_complete; + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_1; UNREACHABLE; } - s_n_llpkgc_file__internal__n_error_9: { - state->error = 0xd; + s_n_llpkgc_file__internal__n_invoke_update_finish_4: { + switch (llpkgc_file__internal__c_update_finish_4(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_bareword; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_12: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_11: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_ident_mark_2: { + switch (llpkgc_file__emit_ident_mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident; + case 5: + goto s_n_llpkgc_file__internal__n_error_12; + default: + goto s_n_llpkgc_file__internal__n_error_11; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_14: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_13: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_ident_mark_3: { + switch (llpkgc_file__emit_ident_mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident_1; + case 5: + goto s_n_llpkgc_file__internal__n_error_14; + default: + goto s_n_llpkgc_file__internal__n_error_13; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_1: { + switch (llpkgc_file__internal__c_update_finish_1(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_start_escape; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_15: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark: { + switch (llpkgc_file__mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_start_backslash; + case 5: + goto s_n_llpkgc_file__internal__n_error_15; + default: + goto s_n_llpkgc_file__internal__n_error; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_13: { + switch (llpkgc_file__internal__c_update_finish_10(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_leading_whitespace; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_12: { + switch (llpkgc_file__internal__c_update_finish_10(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_leading_lf; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_14: { + switch (llpkgc_file__internal__c_update_finish_10(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_leading_cr; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_18: { + switch (llpkgc_file__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_start; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_21: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_20: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_complete_1: { + switch (llpkgc_file__on_value_complete(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_invoke_update_finish_18; + case 5: + goto s_n_llpkgc_file__internal__n_error_21; + default: + goto s_n_llpkgc_file__internal__n_error_20; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_22: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_19: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_span_end_llpkgc_file__whitespace: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llpkgc_file__whitespace(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__clear_whitespace; + return s_error; + } + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__clear_whitespace; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_20: { + switch (llpkgc_file__internal__c_update_finish_10(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_whitespace_lf; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_21: { + switch (llpkgc_file__internal__c_update_finish_10(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_whitespace_cr; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_25: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_24: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__flush_whitespace_all: { + switch (llpkgc_file__flush_whitespace_all(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_value_literal; + case 5: + goto s_n_llpkgc_file__internal__n_error_25; + default: + goto s_n_llpkgc_file__internal__n_error_24; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_29: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_28: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_literal_complete_1: { + switch (llpkgc_file__on_value_literal_complete(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_value_literal; + case 5: + goto s_n_llpkgc_file__internal__n_error_29; + default: + goto s_n_llpkgc_file__internal__n_error_28; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_30: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_27: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_literal_mark: { + switch (llpkgc_file__emit_literal_mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_literal_complete_1; + case 5: + goto s_n_llpkgc_file__internal__n_error_30; + default: + goto s_n_llpkgc_file__internal__n_error_27; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_31: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_26: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__flush_whitespace_all_1: { + switch (llpkgc_file__flush_whitespace_all(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_literal_mark; + case 5: + goto s_n_llpkgc_file__internal__n_error_31; + default: + goto s_n_llpkgc_file__internal__n_error_26; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_35: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_34: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_literal_complete_2: { + switch (llpkgc_file__on_value_literal_complete(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_invoke_update_finish_16; + case 5: + goto s_n_llpkgc_file__internal__n_error_35; + default: + goto s_n_llpkgc_file__internal__n_error_34; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_36: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_33: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_literal_mark_1: { + switch (llpkgc_file__emit_literal_mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_literal_complete_2; + case 5: + goto s_n_llpkgc_file__internal__n_error_36; + default: + goto s_n_llpkgc_file__internal__n_error_33; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_37: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_32: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__flush_whitespace_all_2: { + switch (llpkgc_file__flush_whitespace_all(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_literal_mark_1; + case 5: + goto s_n_llpkgc_file__internal__n_error_37; + default: + goto s_n_llpkgc_file__internal__n_error_32; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_19: { + switch (llpkgc_file__internal__c_update_finish_11(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_whitespace_escape; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_38: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_23: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_span_end_llpkgc_file__whitespace_1: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llpkgc_file__whitespace(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_3; + return s_error; + } + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_3; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_40: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_39: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_span_end_llpkgc_file__whitespace_2: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llpkgc_file__whitespace(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__flush_whitespace_all_3; + return s_error; + } + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__flush_whitespace_all_3; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_17: { + switch (llpkgc_file__internal__c_update_finish_10(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_whitespace; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_44: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_43: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_literal_complete_3: { + switch (llpkgc_file__on_value_literal_complete(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_invoke_update_finish_16; + case 5: + goto s_n_llpkgc_file__internal__n_error_44; + default: + goto s_n_llpkgc_file__internal__n_error_43; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_45: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_42: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_literal_mark_2: { + switch (llpkgc_file__emit_literal_mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_literal_complete_3; + case 5: + goto s_n_llpkgc_file__internal__n_error_45; + default: + goto s_n_llpkgc_file__internal__n_error_42; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_47: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_46: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_substitution_complete: { + switch (llpkgc_file__on_value_substitution_complete(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_invoke_update_finish_16; + case 5: + goto s_n_llpkgc_file__internal__n_error_47; + default: + goto s_n_llpkgc_file__internal__n_error_46; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_value_substitution: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llpkgc_file__on_value_substitution(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_substitution_end; + return s_error; + } + goto s_n_llpkgc_file__internal__n_substitution_end; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_48: { + state->error = 0x4; state->reason = "Invalid variable substitution character"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; UNREACHABLE; } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_7: { - switch (llpkgc_file__internal__c_update_llpkgc_file__unfinished_7(state, p, endp)) { + s_n_llpkgc_file__internal__n_invoke_update_finish_23: { + switch (llpkgc_file__internal__c_update_finish_23(state, p, endp)) { default: - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__sub_span; + goto s_n_llpkgc_file__internal__n_substitution; } UNREACHABLE; } - s_n_llpkgc_file__internal__n_error_5: { - state->error = 0xb; - state->reason = "Value literal complete error"; + s_n_llpkgc_file__internal__n_error_51: { + state->error = 0x5; + state->reason = "Internal parser error"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; UNREACHABLE; } - s_n_llpkgc_file__internal__n_span_end_llpkgc_file__lit_span_1: { - const unsigned char* start; - int err; - - start = state->_span_pos1; - state->_span_pos1 = NULL; - err = llpkgc_file__lit_span(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_1; - return s_error; - } - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_1; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_error_10: { - state->error = 0xb; - state->reason = "Value literal complete error"; + s_n_llpkgc_file__internal__n_error_50: { + state->error = 0x2; + state->reason = "Callback error"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; UNREACHABLE; } - s_n_llpkgc_file__internal__n_span_end_llpkgc_file__lit_span_4: { - const unsigned char* start; - int err; - - start = state->_span_pos1; - state->_span_pos1 = NULL; - err = llpkgc_file__lit_span(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_4; - return s_error; - } - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_4; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_error_11: { - state->error = 0xb; - state->reason = "Value literal complete error"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_error; - return s_error; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_span_end_llpkgc_file__lit_span_5: { - const unsigned char* start; - int err; - - start = state->_span_pos1; - state->_span_pos1 = NULL; - err = llpkgc_file__lit_span(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_5; - return s_error; - } - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_5; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_pause_4: { - state->error = 0x4; - state->reason = "Lookahead required"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_1; - return s_error; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__text_resume_1: { - switch (llpkgc_file__internal__c_update_llpkgc_file__text_resume(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_pkgc_file_backslash_literal; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__line_resume_1: { - switch (llpkgc_file__internal__c_update_llpkgc_file__line_resume(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_pkgc_file_continue_line; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__value_resume_1: { - switch (llpkgc_file__internal__c_update_llpkgc_file__value_resume(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__line_resume_1; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_error_12: { - state->error = 0xb; - state->reason = "Value literal complete error"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_error; - return s_error; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_span_end_llpkgc_file__lit_span_6: { - const unsigned char* start; - int err; - - start = state->_span_pos1; - state->_span_pos1 = NULL; - err = llpkgc_file__lit_span(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_6; - return s_error; - } - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_6; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_error_13: { - state->error = 0xb; - state->reason = "Value literal complete error"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_error; - return s_error; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_span_end_llpkgc_file__lit_span_7: { - const unsigned char* start; - int err; - - start = state->_span_pos1; - state->_span_pos1 = NULL; - err = llpkgc_file__lit_span(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_7; - return s_error; - } - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_7; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__text_resume_2: { - switch (llpkgc_file__internal__c_update_llpkgc_file__text_resume(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_pkgc_file_double_backslash; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_error_14: { - state->error = 0xb; - state->reason = "Value literal complete error"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_error; - return s_error; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_span_end_llpkgc_file__lit_span_8: { - const unsigned char* start; - int err; - - start = state->_span_pos1; - state->_span_pos1 = NULL; - err = llpkgc_file__lit_span(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_8; - return s_error; - } - goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lit_complete_8; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_pause_5: { - state->error = 0x4; - state->reason = "Lookahead required"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_3; - return s_error; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_6: { - switch (llpkgc_file__internal__c_update_llpkgc_file__unfinished_6(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_12: { - switch (llpkgc_file__internal__c_update_llpkgc_file__unfinished_6(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_6; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_pause_6: { - state->error = 0x4; - state->reason = "Lookahead required"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead; - return s_error; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__line_resume_2: { - switch (llpkgc_file__internal__c_update_llpkgc_file__line_resume(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_pkgc_file_continue_line; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__value_resume_2: { - switch (llpkgc_file__internal__c_update_llpkgc_file__value_resume_2(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__line_resume_2; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__text_resume_3: { - switch (llpkgc_file__internal__c_update_llpkgc_file__text_resume(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_pkgc_file_double_backslash; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_13: { - switch (llpkgc_file__internal__c_update_llpkgc_file__unfinished_6(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__lit_span_8; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_pause_7: { - state->error = 0x4; - state->reason = "Lookahead required"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_4; - return s_error; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_5: { - switch (llpkgc_file__internal__c_update_llpkgc_file__unfinished_5(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_pkgc_file_expect_value; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_error_3: { - state->error = 0x7; - state->reason = "Property complete error"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_error; - return s_error; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__prop_decl_complete: { - switch (llpkgc_file__prop_decl_complete(state, p, endp)) { + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_literal_complete_4: { + switch (llpkgc_file__on_value_literal_complete(state, p, endp)) { case 0: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_5; + goto s_n_llpkgc_file__internal__n_invoke_update_finish_16; + case 5: + goto s_n_llpkgc_file__internal__n_error_51; default: - goto s_n_llpkgc_file__internal__n_error_3; + goto s_n_llpkgc_file__internal__n_error_50; } UNREACHABLE; } - s_n_llpkgc_file__internal__n_error_15: { - state->error = 0x8; - state->reason = "Variable complete error"; + s_n_llpkgc_file__internal__n_error_52: { + state->error = 0x5; + state->reason = "Internal parser error"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; UNREACHABLE; } - s_n_llpkgc_file__internal__n_invoke_llpkgc_file__var_decl_complete: { - switch (llpkgc_file__var_decl_complete(state, p, endp)) { - case 0: - goto s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_5; - default: - goto s_n_llpkgc_file__internal__n_error_15; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__line_resume_3: { - switch (llpkgc_file__internal__c_update_llpkgc_file__line_resume_3(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_pkgc_file_continue_line; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_14: { - switch (llpkgc_file__internal__c_update_llpkgc_file__unfinished(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_6; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_15: { - switch (llpkgc_file__internal__c_update_llpkgc_file__unfinished(state, p, endp)) { - default: - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_7; - } - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_pause_8: { - state->error = 0x4; - state->reason = "Lookahead required"; + s_n_llpkgc_file__internal__n_error_49: { + state->error = 0x2; + state->reason = "Callback error"; state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_5; + state->_current = (void*) (intptr_t) s_error; return s_error; UNREACHABLE; } - s_n_llpkgc_file__internal__n_span_end_llpkgc_file__ident_span_3: { + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_literal_mark_3: { + switch (llpkgc_file__emit_literal_mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_literal_complete_4; + case 5: + goto s_n_llpkgc_file__internal__n_error_52; + default: + goto s_n_llpkgc_file__internal__n_error_49; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_22: { + switch (llpkgc_file__internal__c_update_finish_22(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_dollar; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_53: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_41: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_4: { + switch (llpkgc_file__mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_dollar_start; + case 5: + goto s_n_llpkgc_file__internal__n_error_53; + default: + goto s_n_llpkgc_file__internal__n_error_41; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_25: { + switch (llpkgc_file__internal__c_update_finish_10(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_value_lf; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_26: { + switch (llpkgc_file__internal__c_update_finish_10(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_value_cr; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_57: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_56: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_literal_complete_5: { + switch (llpkgc_file__on_value_literal_complete(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_value_literal; + case 5: + goto s_n_llpkgc_file__internal__n_error_57; + default: + goto s_n_llpkgc_file__internal__n_error_56; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_58: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_55: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_literal_mark_4: { + switch (llpkgc_file__emit_literal_mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_literal_complete_5; + case 5: + goto s_n_llpkgc_file__internal__n_error_58; + default: + goto s_n_llpkgc_file__internal__n_error_55; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_61: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_60: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_literal_complete_6: { + switch (llpkgc_file__on_value_literal_complete(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_invoke_update_finish_16; + case 5: + goto s_n_llpkgc_file__internal__n_error_61; + default: + goto s_n_llpkgc_file__internal__n_error_60; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_62: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_59: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_literal_mark_5: { + switch (llpkgc_file__emit_literal_mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_literal_complete_6; + case 5: + goto s_n_llpkgc_file__internal__n_error_62; + default: + goto s_n_llpkgc_file__internal__n_error_59; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_24: { + switch (llpkgc_file__internal__c_update_finish_11(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_value_escape; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_63: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_54: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_5: { + switch (llpkgc_file__mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_value_backslash; + case 5: + goto s_n_llpkgc_file__internal__n_error_63; + default: + goto s_n_llpkgc_file__internal__n_error_54; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_16: { + switch (llpkgc_file__internal__c_update_finish_10(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_value; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_64: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_18: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_value_literal: { const unsigned char* start; int err; start = state->_span_pos0; state->_span_pos0 = NULL; - err = llpkgc_file__ident_span(state, start, p); + err = llpkgc_file__on_value_literal(state, start, p); if (err != 0) { state->error = err; state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_pkgc_file_maybe_separator; + state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_literal_complete; return s_error; } - goto s_n_llpkgc_file__internal__n_pkgc_file_maybe_separator; + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_literal_complete; UNREACHABLE; } - s_n_llpkgc_file__internal__n_span_end_llpkgc_file__ident_span_4: { - const unsigned char* start; - int err; - - start = state->_span_pos0; - state->_span_pos0 = NULL; - err = llpkgc_file__ident_span(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) (p + 1); - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_pkgc_file_ident_continue_line; - return s_error; + s_n_llpkgc_file__internal__n_invoke_update_finish_15: { + switch (llpkgc_file__internal__c_update_finish_15(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_text; } - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_ident_continue_line; UNREACHABLE; } - s_n_llpkgc_file__internal__n_span_end_llpkgc_file__ident_span_5: { - const unsigned char* start; - int err; - - start = state->_span_pos0; - state->_span_pos0 = NULL; - err = llpkgc_file__ident_span(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) (p + 1); - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_pkgc_file_ident_escaped_comment; - return s_error; - } - p++; - goto s_n_llpkgc_file__internal__n_pkgc_file_ident_escaped_comment; - UNREACHABLE; - } - s_n_llpkgc_file__internal__n_pause_9: { - state->error = 0x4; - state->reason = "Lookahead required"; + s_n_llpkgc_file__internal__n_error_67: { + state->error = 0x5; + state->reason = "Internal parser error"; state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__lookahead_backslash_6; + state->_current = (void*) (intptr_t) s_error; return s_error; UNREACHABLE; } - s_n_llpkgc_file__internal__n_invoke_update_llpkgc_file__unfinished_4: { - switch (llpkgc_file__internal__c_update_llpkgc_file__unfinished_4(state, p, endp)) { + s_n_llpkgc_file__internal__n_error_66: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_literal_complete_7: { + switch (llpkgc_file__on_value_literal_complete(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_value_literal; + case 5: + goto s_n_llpkgc_file__internal__n_error_67; default: - goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__ident_span_5; + goto s_n_llpkgc_file__internal__n_error_66; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_68: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_65: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_literal_mark_6: { + switch (llpkgc_file__emit_literal_mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_literal_complete_7; + case 5: + goto s_n_llpkgc_file__internal__n_error_68; + default: + goto s_n_llpkgc_file__internal__n_error_65; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_71: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_70: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_literal_complete_8: { + switch (llpkgc_file__on_value_literal_complete(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_invoke_update_finish_16; + case 5: + goto s_n_llpkgc_file__internal__n_error_71; + default: + goto s_n_llpkgc_file__internal__n_error_70; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_72: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_69: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_literal_mark_7: { + switch (llpkgc_file__emit_literal_mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_value_literal_complete_8; + case 5: + goto s_n_llpkgc_file__internal__n_error_72; + default: + goto s_n_llpkgc_file__internal__n_error_69; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_11: { + switch (llpkgc_file__internal__c_update_finish_11(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_leading_escape; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_73: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_17: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_2: { + switch (llpkgc_file__mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_leading_backslash; + case 5: + goto s_n_llpkgc_file__internal__n_error_73; + default: + goto s_n_llpkgc_file__internal__n_error_17; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_10: { + switch (llpkgc_file__internal__c_update_finish_10(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_leading_whitespace; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_74: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_16: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_property_complete: { + switch (llpkgc_file__on_property_complete(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_invoke_update_finish_10; + case 5: + goto s_n_llpkgc_file__internal__n_error_74; + default: + goto s_n_llpkgc_file__internal__n_error_16; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_27: { + switch (llpkgc_file__internal__c_update_finish_10(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_leading_whitespace; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_76: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_75: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__on_variable_complete: { + switch (llpkgc_file__on_variable_complete(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_invoke_update_finish_27; + case 5: + goto s_n_llpkgc_file__internal__n_error_76; + default: + goto s_n_llpkgc_file__internal__n_error_75; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_29: { + switch (llpkgc_file__internal__c_update_finish_4(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_separator_lf; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_30: { + switch (llpkgc_file__internal__c_update_finish_4(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_separator_cr; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_79: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_78: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_ident_mark_4: { + switch (llpkgc_file__emit_ident_mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident; + case 5: + goto s_n_llpkgc_file__internal__n_error_79; + default: + goto s_n_llpkgc_file__internal__n_error_78; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_81: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_80: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_ident_mark_5: { + switch (llpkgc_file__emit_ident_mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident_1; + case 5: + goto s_n_llpkgc_file__internal__n_error_81; + default: + goto s_n_llpkgc_file__internal__n_error_80; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_28: { + switch (llpkgc_file__internal__c_update_finish_1(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_separator_escape; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_82: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_77: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_6: { + switch (llpkgc_file__mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_separator_backslash; + case 5: + goto s_n_llpkgc_file__internal__n_error_82; + default: + goto s_n_llpkgc_file__internal__n_error_77; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_ident_2: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llpkgc_file__on_ident(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_update_finish_9; + return s_error; + } + goto s_n_llpkgc_file__internal__n_invoke_update_finish_9; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_32: { + switch (llpkgc_file__internal__c_update_finish_4(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_identifier_lf; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_33: { + switch (llpkgc_file__internal__c_update_finish_4(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_identifier_cr; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_85: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_84: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_ident_mark_6: { + switch (llpkgc_file__emit_ident_mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident; + case 5: + goto s_n_llpkgc_file__internal__n_error_85; + default: + goto s_n_llpkgc_file__internal__n_error_84; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_87: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_86: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_llpkgc_file__emit_ident_mark_7: { + switch (llpkgc_file__emit_ident_mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_file__internal__n_span_start_llpkgc_file__on_ident_1; + case 5: + goto s_n_llpkgc_file__internal__n_error_87; + default: + goto s_n_llpkgc_file__internal__n_error_86; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_31: { + switch (llpkgc_file__internal__c_update_finish_1(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_identifier_escape; + } + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_88: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_error_83: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_span_end_llpkgc_file__on_ident_3: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llpkgc_file__on_ident(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_7; + return s_error; + } + goto s_n_llpkgc_file__internal__n_invoke_llpkgc_file__mark_7; + UNREACHABLE; + } + s_n_llpkgc_file__internal__n_invoke_update_finish_8: { + switch (llpkgc_file__internal__c_update_finish_4(state, p, endp)) { + default: + goto s_n_llpkgc_file__internal__n_identifier; } UNREACHABLE; } @@ -2453,9 +2784,6 @@ if (state->_span_pos0 != NULL) { state->_span_pos0 = (void*) p; } - if (state->_span_pos1 != NULL) { - state->_span_pos1 = (void*) p; - } next = llpkgc_file__internal__run(state, (const unsigned char*) p, (const unsigned char*) endp); if (next == s_error) { @@ -2474,16 +2802,411 @@ return error; } } - if (state->_span_pos1 != NULL) { - int error; - - error = llpkgc_file__lit_span(state, state->_span_pos1, (const char*) endp); - if (error != 0) { - state->error = error; - state->error_pos = endp; - return error; - } - } return 0; } +#include <string.h> +#include "llpkgc_file.h" +int llpkgc_file__on_barewords_complete(llpkgc_file_t*, const unsigned char*, const unsigned char*); +int llpkgc_file__clear_whitespace(llpkgc_file_t*, const unsigned char*, const unsigned char*); +int llpkgc_file__on_value_complete(llpkgc_file_t*, const unsigned char*, const unsigned char*); +int llpkgc_file__emit_ident_mark(llpkgc_file_t*, const unsigned char*, const unsigned char*); +int llpkgc_file__on_value_literal_complete(llpkgc_file_t*, const unsigned char*, const unsigned char*); +int llpkgc_file__flush_whitespace_all(llpkgc_file_t*, const unsigned char*, const unsigned char*); +int llpkgc_file__emit_literal_mark(llpkgc_file_t*, const unsigned char*, const unsigned char*); + +int llpkgc_file__on_pkgc_complete(llpkgc_file_t* s, const unsigned char* p, const unsigned char* endp) { + const llpkgc_file_settings_t* settings = s->settings; + int err; + if (settings == NULL || settings->on_pkgc_complete == NULL) return 0; + err = settings->on_pkgc_complete(s); + if (err != 0) { + if (s->reason == NULL) s->reason = "User callback error in on_pkgc_complete"; + s->callback_reason = (void*) s->reason; + return PFCE_USER; + } + return 0; +} + +int llpkgc_file__on_ident(llpkgc_file_t* s, const unsigned char* p, const unsigned char* endp) { + const llpkgc_file_settings_t* settings = s->settings; + int err; + if (settings == NULL || settings->on_ident == NULL) return 0; + err = settings->on_ident(s, (const char*) p, (size_t) (endp - p)); + if (err != 0) { + if (s->reason == NULL) s->reason = "User callback error in on_ident"; + s->callback_reason = (void*) s->reason; + return PFCE_USER; + } + return 0; +} + +int llpkgc_file__on_value_literal(llpkgc_file_t* s, const unsigned char* p, const unsigned char* endp) { + const llpkgc_file_settings_t* settings = s->settings; + int err; + if (settings == NULL || settings->on_value_literal == NULL) return 0; + err = settings->on_value_literal(s, (const char*) p, (size_t) (endp - p)); + if (err != 0) { + if (s->reason == NULL) s->reason = "User callback error in on_value_literal"; + s->callback_reason = (void*) s->reason; + return PFCE_USER; + } + return 0; +} + +int llpkgc_file__on_value_substitution(llpkgc_file_t* s, const unsigned char* p, const unsigned char* endp) { + const llpkgc_file_settings_t* settings = s->settings; + int err; + if (settings == NULL || settings->on_value_substitution == NULL) return 0; + err = settings->on_value_substitution(s, (const char*) p, (size_t) (endp - p)); + if (err != 0) { + if (s->reason == NULL) s->reason = "User callback error in on_value_substitution"; + s->callback_reason = (void*) s->reason; + return PFCE_USER; + } + return 0; +} + +int llpkgc_file__on_value_literal_complete(llpkgc_file_t* s, const unsigned char* p, const unsigned char* endp) { + const llpkgc_file_settings_t* settings = s->settings; + int err; + if (settings == NULL || settings->on_value_literal_complete == NULL) return 0; + err = settings->on_value_literal_complete(s); + if (err != 0) { + if (s->reason == NULL) s->reason = "User callback error in on_value_literal_complete"; + s->callback_reason = (void*) s->reason; + return PFCE_USER; + } + return 0; +} + +int llpkgc_file__on_value_complete(llpkgc_file_t* s, const unsigned char* p, const unsigned char* endp) { + const llpkgc_file_settings_t* settings = s->settings; + int err; + if (settings == NULL || settings->on_value_complete == NULL) return 0; + err = settings->on_value_complete(s); + if (err != 0) { + if (s->reason == NULL) s->reason = "User callback error in on_value_complete"; + s->callback_reason = (void*) s->reason; + return PFCE_USER; + } + return 0; +} + +int llpkgc_file__on_barewords_complete(llpkgc_file_t* s, const unsigned char* p, const unsigned char* endp) { + const llpkgc_file_settings_t* settings = s->settings; + int err; + if (settings == NULL || settings->on_barewords_complete == NULL) return 0; + err = settings->on_barewords_complete(s); + if (err != 0) { + if (s->reason == NULL) s->reason = "User callback error in on_barewords_complete"; + s->callback_reason = (void*) s->reason; + return PFCE_USER; + } + return 0; +} + +int llpkgc_file__on_property_complete(llpkgc_file_t* s, const unsigned char* p, const unsigned char* endp) { + const llpkgc_file_settings_t* settings = s->settings; + int err; + if (settings == NULL || settings->on_property_complete == NULL) return 0; + err = settings->on_property_complete(s); + if (err != 0) { + if (s->reason == NULL) s->reason = "User callback error in on_property_complete"; + s->callback_reason = (void*) s->reason; + return PFCE_USER; + } + return 0; +} + +int llpkgc_file__on_variable_complete(llpkgc_file_t* s, const unsigned char* p, const unsigned char* endp) { + const llpkgc_file_settings_t* settings = s->settings; + int err; + if (settings == NULL || settings->on_variable_complete == NULL) return 0; + err = settings->on_variable_complete(s); + if (err != 0) { + if (s->reason == NULL) s->reason = "User callback error in on_variable_complete"; + s->callback_reason = (void*) s->reason; + return PFCE_USER; + } + return 0; +} + +int llpkgc_file__on_value_substitution_complete(llpkgc_file_t* s, const unsigned char* p, const unsigned char* endp) { + const llpkgc_file_settings_t* settings = s->settings; + int err; + if (settings == NULL || settings->on_value_substitution_complete == NULL) return 0; + err = settings->on_value_substitution_complete(s); + if (err != 0) { + if (s->reason == NULL) s->reason = "User callback error in on_value_substitution_complete"; + s->callback_reason = (void*) s->reason; + return PFCE_USER; + } + return 0; +} + +void llpkgc_file_init(llpkgc_file_t* s, const llpkgc_file_settings_t* settings) { + llpkgc_file__internal_init(s); + s->settings = (void*) settings; +} +void llpkgc_file_reset(llpkgc_file_t* s) { + const llpkgc_file_settings_t* settings = s->settings; + void* data = s->data; + llpkgc_file_init(s, settings); + s->data = data; +} +void llpkgc_file_settings_init(llpkgc_file_settings_t* settings) { + memset(settings, 0, sizeof(*settings)); +} +llpkgc_file_errno_t llpkgc_file_execute(llpkgc_file_t* s, const char* data, size_t len) { + if (s->error != 0) return s->error; + if (s->done) { + s->reason = "Input after finish"; + s->error_pos = data; + return s->error = PFCE_INVALID; + } + if (s->whitespace_start != NULL && data != s->end && len != 0) { + s->reason = "Retained input requires a contiguous extension"; + s->error_pos = data; + return s->error = PFCE_INVALID; + } + if (len == 0) return s->whitespace_start != NULL ? PFCE_NEED_MORE : PFCE_OK; + s->end = (void*) (data + len); + { + int err = llpkgc_file__internal_execute(s, data, data + len); + if (err == PFCE_USER && s->callback_reason != NULL) + s->reason = s->callback_reason; + if (err == 0 && s->whitespace_start != NULL) return PFCE_NEED_MORE; + return err; + } +} +llpkgc_file_errno_t llpkgc_file_finish(llpkgc_file_t* s) { + int err; + if (s->error != 0) return s->error; + if (s->done) return PFCE_OK; + switch (s->finish) { + case 0: + err = llpkgc_file__on_pkgc_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + break; +case 1: + err = llpkgc_file__on_barewords_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_file__clear_whitespace(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_file__on_value_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_file__on_pkgc_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + break; +case 2: + err = llpkgc_file__emit_ident_mark(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_file__on_barewords_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_file__clear_whitespace(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_file__on_value_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_file__on_pkgc_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + break; +case 3: + err = llpkgc_file__clear_whitespace(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_file__on_value_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_file__on_pkgc_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + break; +case 4: + err = llpkgc_file__on_value_literal_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_file__clear_whitespace(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_file__on_value_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_file__on_pkgc_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + break; +case 5: + err = llpkgc_file__flush_whitespace_all(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_file__emit_literal_mark(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_file__on_value_literal_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_file__clear_whitespace(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_file__on_value_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_file__on_pkgc_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + break; +case 6: + err = llpkgc_file__emit_literal_mark(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_file__on_value_literal_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_file__clear_whitespace(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_file__on_value_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_file__on_pkgc_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + break; +case 7: s->reason = "Invalid EOF state"; + s->error = PFCE_UNFINISHED; s->error_pos = s->end; return s->error; + default: s->reason = "Invalid finish action"; return s->error = PFCE_INTERNAL; + } + s->done = 1; + return PFCE_OK; +} +llpkgc_file_errno_t llpkgc_file_get_errno(const llpkgc_file_t* s) { return s->error; } +const char* llpkgc_file_get_error_reason(const llpkgc_file_t* s) { return s->reason; } +void llpkgc_file_set_error_reason(llpkgc_file_t* s, const char* reason) { s->reason = reason; } +const char* llpkgc_file_get_error_pos(const llpkgc_file_t* s) { return s->error_pos; } +const char* llpkgc_file_errno_name(llpkgc_file_errno_t err) { + switch (err) { + case PFCE_OK: return "PFCE_OK"; + case PFCE_USER: return "PFCE_USER"; + case PFCE_UNFINISHED: return "PFCE_UNFINISHED"; + case PFCE_INVALID: return "PFCE_INVALID"; + case PFCE_NEED_MORE: return "PFCE_NEED_MORE"; + default: return "PFCE_INTERNAL"; + } +} +
diff --git a/Utilities/cmllpkgc/llpkgc_file__internal.h b/Utilities/cmllpkgc/llpkgc_file__internal.h index 8b63477..f32eabd 100644 --- a/Utilities/cmllpkgc/llpkgc_file__internal.h +++ b/Utilities/cmllpkgc/llpkgc_file__internal.h
@@ -17,19 +17,19 @@ int32_t _index; void* _span_pos0; void* _span_cb0; - void* _span_pos1; int32_t error; const char* reason; const char* error_pos; void* data; void* _current; - void* llpkgc_file__settings; - uint8_t llpkgc_file__unfinished; - uint8_t llpkgc_file__lookahead; - uint8_t llpkgc_file__eof; - uint8_t llpkgc_file__value_resume; - uint8_t llpkgc_file__line_resume; - uint8_t llpkgc_file__text_resume; + void* settings; + void* end; + void* callback_reason; + uint32_t finish; + uint8_t done; + uint8_t mark; + void* whitespace_start; + void* whitespace_end; }; int llpkgc_file__internal_init(llpkgc_file__internal_t* s);
diff --git a/Utilities/cmllpkgc/llpkgc_frag.c b/Utilities/cmllpkgc/llpkgc_frag.c index cab2b1a..017a68b 100644 --- a/Utilities/cmllpkgc/llpkgc_frag.c +++ b/Utilities/cmllpkgc/llpkgc_frag.c
@@ -1,215 +1,13 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file LICENSE.rst for details. */ -#include <stdint.h> -#include <stdlib.h> -#include <string.h> - #include "llpkgc_frag.h" -#define CALLBACK_MAYBE(PARSER, NAME) \ - do { \ - const llpkgc_frag_settings_t* settings; \ - settings = \ - (const llpkgc_frag_settings_t*) (PARSER)->llpkgc_frag__settings; \ - if(settings == NULL || settings->NAME == NULL) { \ - err = 0; \ - break; \ - } \ - err = settings->NAME((PARSER)); \ - } while(0) +int llpkgc_frag__on_fragment_text(llpkgc_frag_t*, const unsigned char*, + const unsigned char*); -#define SPAN_CALLBACK_MAYBE(PARSER, NAME, START, LEN) \ - do { \ - const llpkgc_frag_settings_t* settings; \ - settings = \ - (const llpkgc_frag_settings_t*) (PARSER)->llpkgc_frag__settings; \ - if(settings == NULL || settings->NAME == NULL) { \ - err = 0; \ - break; \ - } \ - err = settings->NAME((PARSER), (START), (LEN)); \ - if(err == -1) { \ - err = PFFE_USER; \ - llpkgc_frag_set_error_reason((PARSER), "Span callback error in " #NAME); \ - } \ - } while(0) - -enum llpkgc_frag_state { - PFFS_START = 0, - PFFS_UNQUOTED = 1, - PFFS_DOUBLE_QUOTED = 2, - PFFS_SINGLE_QUOTED = 3, -}; - -void llpkgc_frag_init(llpkgc_frag_t* parser, - const llpkgc_frag_settings_t* settings) { - llpkgc_frag__internal_init(parser); - parser->llpkgc_frag__settings = (void*) settings; -} - -void llpkgc_frag_reset(llpkgc_frag_t* parser) { - llpkgc_frag_settings_t* settings = parser->llpkgc_frag__settings; - void* data = parser->data; - llpkgc_frag__internal_init(parser); - parser->llpkgc_frag__settings = settings; - parser->data = data; -} - -void llpkgc_frag_settings_init(llpkgc_frag_settings_t* settings) { - memset(settings, 0, sizeof(*settings)); -} - -llpkgc_frag_errno_t llpkgc_frag_execute(llpkgc_frag_t* parser, const char* data, - size_t len) { - return llpkgc_frag__internal_execute(parser, data, data + len); -} - -llpkgc_frag_errno_t llpkgc_frag_finish(llpkgc_frag_t* parser) { - int err = PFFE_OK; - - if(parser->error == PFFE_LOOKAHEAD) { - if(parser->error_pos == NULL) { - parser->error = PFFE_INTERNAL; - parser->reason = "Missing lookahead error position"; - return parser->error; - } - - parser->llpkgc_frag__eof = 1; - llpkgc_frag_resume(parser); - err = llpkgc_frag_execute(parser, parser->error_pos, 1); - parser->llpkgc_frag__eof = 0; - - if(err != PFFE_OK) { - return err; - } - - parser->llpkgc_frag__lookahead = 0; - } else if(parser->error != 0) { - return parser->error; - } - - switch(parser->llpkgc_frag__state) { - case PFFS_UNQUOTED: - CALLBACK_MAYBE(parser, on_frag_complete); - if(err != PFFE_OK) { - parser->error = err; - return err; - } - break; - - case PFFS_DOUBLE_QUOTED: - case PFFS_SINGLE_QUOTED: - parser->reason = "Unterminated quote at end of input"; - parser->error = PFFE_UNFINISHED; - return PFFE_UNFINISHED; - - case PFFS_START: - break; - } - - CALLBACK_MAYBE(parser, on_fraglist_complete); - if(err != PFFE_OK) { - parser->error = err; - return err; - } - - return PFFE_OK; -} - -void llpkgc_frag_pause(llpkgc_frag_t* parser) { - if(parser->error != PFFE_OK) { - return; - } - parser->error = PFFE_PAUSED; - parser->reason = "Paused"; -} - -void llpkgc_frag_resume(llpkgc_frag_t* parser) { - if(parser->error != PFFE_PAUSED && parser->error != PFFE_LOOKAHEAD) { - return; - } - parser->error = 0; -} - -llpkgc_frag_errno_t llpkgc_frag_get_errno(const llpkgc_frag_t* parser) { - return parser->error; -} - -const char* llpkgc_frag_get_error_reason(const llpkgc_frag_t* parser) { - return parser->reason; -} - -void llpkgc_frag_set_error_reason(llpkgc_frag_t* parser, const char* reason) { - parser->reason = reason; -} - -const char* llpkgc_frag_get_error_pos(const llpkgc_frag_t* parser) { - return parser->error_pos; -} - -const char* llpkgc_frag_errno_name(llpkgc_frag_errno_t err) { - switch(err) { - case PFFE_OK: - return "PFFE_OK"; - case PFFE_INTERNAL: - return "PFFE_INTERNAL"; - case PFFE_PAUSED: - return "PFFE_PAUSED"; - case PFFE_USER: - return "PFFE_USER"; - case PFFE_UNFINISHED: - return "PFFE_UNFINISHED"; - case PFFE_LOOKAHEAD: - return "PFFE_LOOKAHEAD"; - } - return "INVALID_ERRNO"; -} - -int llpkgc_frag__lookahead_dq_backslash(llpkgc_frag_t* s, const char* p, - const char* endp) { - if(p == endp) { - llpkgc_frag_set_error_reason(s, "Invalid lookahead state"); - return PFFE_INTERNAL; - } - - if(p + 1 == endp) { - if(s->llpkgc_frag__eof != 0) { - s->llpkgc_frag__lookahead = 0; - return 1; - } - s->llpkgc_frag__lookahead = (uint8_t) *p; - return PFFE_LOOKAHEAD; - } - - s->llpkgc_frag__lookahead = 0; - - if(*p != '\\') { - llpkgc_frag_set_error_reason(s, "Invalid lookahead state"); - return PFFE_INTERNAL; - } - - switch(p[1]) { - case '$': - case '`': - case '"': - case '\\': - return 0; - default: - return 1; - } -} - -int llpkgc_frag__fragment_text(llpkgc_frag_t* s, const char* p, - const char* endp) { - int err; - SPAN_CALLBACK_MAYBE(s, on_fragment_text, p, endp - p); - return err; -} - -int llpkgc_frag__frag_complete(llpkgc_frag_t* s, const char* p, - const char* endp) { - int err; - CALLBACK_MAYBE(s, on_frag_complete); - return err; +int llpkgc_frag__emit_mark(llpkgc_frag_t* s, const unsigned char* p, + const unsigned char* endp) { + static const unsigned char backslash[] = "\\"; + return llpkgc_frag__on_fragment_text(s, backslash, backslash + 1); }
diff --git a/Utilities/cmllpkgc/llpkgc_frag.h b/Utilities/cmllpkgc/llpkgc_frag.h index 7210a5b..34c6dfa 100644 --- a/Utilities/cmllpkgc/llpkgc_frag.h +++ b/Utilities/cmllpkgc/llpkgc_frag.h
@@ -30,12 +30,11 @@ }; enum llpkgc_frag_errno { - PFFE_INTERNAL = -1, PFFE_OK = 0, - PFFE_PAUSED = 1, PFFE_USER = 2, PFFE_UNFINISHED = 3, - PFFE_LOOKAHEAD = 4, + PFFE_INVALID = 4, + PFFE_INTERNAL = 5, }; typedef enum llpkgc_frag_errno llpkgc_frag_errno_t; @@ -49,6 +48,8 @@ LLPKGC_FRAG_EXPORT void llpkgc_frag_settings_init(llpkgc_frag_settings_t* settings); +/* Successful chunks are fully consumed and may be released immediately. + * Subsequent chunks need not be contiguous. Callback spans are borrowed. */ LLPKGC_FRAG_EXPORT llpkgc_frag_errno_t llpkgc_frag_execute(llpkgc_frag_t* parser, const char* data, size_t len); @@ -57,12 +58,6 @@ llpkgc_frag_errno_t llpkgc_frag_finish(llpkgc_frag_t* parser); LLPKGC_FRAG_EXPORT -void llpkgc_frag_pause(llpkgc_frag_t* parser); - -LLPKGC_FRAG_EXPORT -void llpkgc_frag_resume(llpkgc_frag_t* parser); - -LLPKGC_FRAG_EXPORT llpkgc_frag_errno_t llpkgc_frag_get_errno(const llpkgc_frag_t* parser); LLPKGC_FRAG_EXPORT
diff --git a/Utilities/cmllpkgc/llpkgc_frag__internal.c b/Utilities/cmllpkgc/llpkgc_frag__internal.c index b74d611..26ac80b 100644 --- a/Utilities/cmllpkgc/llpkgc_frag__internal.c +++ b/Utilities/cmllpkgc/llpkgc_frag__internal.c
@@ -39,77 +39,74 @@ enum llparse_state_e { s_error, - s_n_llpkgc_frag__internal__n_invoke_llpkgc_frag__frag_complete, - s_n_llpkgc_frag__internal__n_pkgc_frag_consume_dq, - s_n_llpkgc_frag__internal__n_pkgc_frag_consume_closing_sq, - s_n_llpkgc_frag__internal__n_pkgc_frag_sq, - s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text_1, - s_n_llpkgc_frag__internal__n_pkgc_frag_consume_sq, - s_n_llpkgc_frag__internal__n_pkgc_frag_unquoted_escaped_char, - s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text_3, - s_n_llpkgc_frag__internal__n_pkgc_frag_unquoted_skip_backslash, - s_n_llpkgc_frag__internal__n_pkgc_frag_unquoted, - s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text_2, - s_n_llpkgc_frag__internal__n_pkgc_frag_after_quote, - s_n_llpkgc_frag__internal__n_pkgc_frag_consume_closing_dq, - s_n_llpkgc_frag__internal__n_pkgc_frag_dq_special_skip, - s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text_4, - s_n_llpkgc_frag__internal__n_pkgc_frag_dq_special, - s_n_llpkgc_frag__internal__n_pkgc_frag_dq_keep_backslash, - s_n_llpkgc_frag__internal__n_invoke_llpkgc_frag__lookahead_dq_backslash, - s_n_llpkgc_frag__internal__n_pkgc_frag_dq, - s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text, - s_n_llpkgc_frag__internal__n_pkgc_frag_start, + s_n_llpkgc_frag__internal__n_double_quote_end, + s_n_llpkgc_frag__internal__n_double_escaped_character, + s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_1, + s_n_llpkgc_frag__internal__n_double_escape, + s_n_llpkgc_frag__internal__n_double_escape_start, + s_n_llpkgc_frag__internal__n_double_quote, + s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text, + s_n_llpkgc_frag__internal__n_single_quote_end, + s_n_llpkgc_frag__internal__n_single_quote, + s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_2, + s_n_llpkgc_frag__internal__n_text, + s_n_llpkgc_frag__internal__n_escaped_character, + s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_3, + s_n_llpkgc_frag__internal__n_escape_start, + s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_4, + s_n_llpkgc_frag__internal__n_token, + s_n_llpkgc_frag__internal__n_invoke_update_finish, + s_n_llpkgc_frag__internal__n_start, }; typedef enum llparse_state_e llparse_state_t; -int llpkgc_frag__fragment_text( +int llpkgc_frag__on_fragment_text( llpkgc_frag__internal_t* s, const unsigned char* p, const unsigned char* endp); -int llpkgc_frag__internal__c_update_llpkgc_frag__state( +int llpkgc_frag__internal__c_update_finish( llpkgc_frag__internal_t* state, const unsigned char* p, const unsigned char* endp) { - state->llpkgc_frag__state = 2; + state->finish = 1; return 0; } -int llpkgc_frag__internal__c_update_llpkgc_frag__state_1( - llpkgc_frag__internal_t* state, - const unsigned char* p, - const unsigned char* endp) { - state->llpkgc_frag__state = 1; - return 0; -} - -int llpkgc_frag__frag_complete( +int llpkgc_frag__on_frag_complete( llpkgc_frag__internal_t* s, const unsigned char* p, const unsigned char* endp); -int llpkgc_frag__internal__c_update_llpkgc_frag__state_2( +int llpkgc_frag__internal__c_update_finish_1( llpkgc_frag__internal_t* state, const unsigned char* p, const unsigned char* endp) { - state->llpkgc_frag__state = 0; + state->finish = 0; return 0; } -int llpkgc_frag__internal__c_update_llpkgc_frag__state_3( +int llpkgc_frag__internal__c_update_finish_2( llpkgc_frag__internal_t* state, const unsigned char* p, const unsigned char* endp) { - state->llpkgc_frag__state = 3; + state->finish = 2; return 0; } -int llpkgc_frag__lookahead_dq_backslash( +int llpkgc_frag__emit_mark( llpkgc_frag__internal_t* s, const unsigned char* p, const unsigned char* endp); +int llpkgc_frag__internal__c_update_finish_5( + llpkgc_frag__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->finish = 3; + return 0; +} + int llpkgc_frag__internal_init(llpkgc_frag__internal_t* state) { memset(state, 0, sizeof(*state)); - state->_current = (void*) (intptr_t) s_n_llpkgc_frag__internal__n_pkgc_frag_start; + state->_current = (void*) (intptr_t) s_n_llpkgc_frag__internal__n_start; return 0; } @@ -119,338 +116,292 @@ const unsigned char* endp) { int match; switch ((llparse_state_t) (intptr_t) state->_current) { - case s_n_llpkgc_frag__internal__n_invoke_llpkgc_frag__frag_complete: - s_n_llpkgc_frag__internal__n_invoke_llpkgc_frag__frag_complete: { - switch (llpkgc_frag__frag_complete(state, p, endp)) { - case 0: - goto s_n_llpkgc_frag__internal__n_invoke_update_llpkgc_frag__state_2; - default: - goto s_n_llpkgc_frag__internal__n_error; - } - UNREACHABLE; - } - case s_n_llpkgc_frag__internal__n_pkgc_frag_consume_dq: - s_n_llpkgc_frag__internal__n_pkgc_frag_consume_dq: { + case s_n_llpkgc_frag__internal__n_double_quote_end: + s_n_llpkgc_frag__internal__n_double_quote_end: { if (p == endp) { - return s_n_llpkgc_frag__internal__n_pkgc_frag_consume_dq; - } - switch (*p) { - case '"': { - p++; - goto s_n_llpkgc_frag__internal__n_invoke_update_llpkgc_frag__state; - } - default: { - goto s_n_llpkgc_frag__internal__n_error_1; - } - } - UNREACHABLE; - } - case s_n_llpkgc_frag__internal__n_pkgc_frag_consume_closing_sq: - s_n_llpkgc_frag__internal__n_pkgc_frag_consume_closing_sq: { - if (p == endp) { - return s_n_llpkgc_frag__internal__n_pkgc_frag_consume_closing_sq; - } - switch (*p) { - case 39: { - p++; - goto s_n_llpkgc_frag__internal__n_invoke_update_llpkgc_frag__state_1; - } - default: { - goto s_n_llpkgc_frag__internal__n_error_1; - } - } - UNREACHABLE; - } - case s_n_llpkgc_frag__internal__n_pkgc_frag_sq: - s_n_llpkgc_frag__internal__n_pkgc_frag_sq: { - if (p == endp) { - return s_n_llpkgc_frag__internal__n_pkgc_frag_sq; - } - switch (*p) { - case 39: { - goto s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__fragment_text_1; - } - default: { - p++; - goto s_n_llpkgc_frag__internal__n_pkgc_frag_sq; - } - } - UNREACHABLE; - } - case s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text_1: - s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text_1: { - if (p == endp) { - return s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text_1; - } - state->_span_pos0 = (void*) p; - goto s_n_llpkgc_frag__internal__n_pkgc_frag_sq; - UNREACHABLE; - } - case s_n_llpkgc_frag__internal__n_pkgc_frag_consume_sq: - s_n_llpkgc_frag__internal__n_pkgc_frag_consume_sq: { - if (p == endp) { - return s_n_llpkgc_frag__internal__n_pkgc_frag_consume_sq; - } - switch (*p) { - case 39: { - p++; - goto s_n_llpkgc_frag__internal__n_invoke_update_llpkgc_frag__state_3; - } - default: { - goto s_n_llpkgc_frag__internal__n_error_1; - } - } - UNREACHABLE; - } - case s_n_llpkgc_frag__internal__n_pkgc_frag_unquoted_escaped_char: - s_n_llpkgc_frag__internal__n_pkgc_frag_unquoted_escaped_char: { - if (p == endp) { - return s_n_llpkgc_frag__internal__n_pkgc_frag_unquoted_escaped_char; + return s_n_llpkgc_frag__internal__n_double_quote_end; } p++; - goto s_n_llpkgc_frag__internal__n_pkgc_frag_unquoted; + goto s_n_llpkgc_frag__internal__n_invoke_update_finish; UNREACHABLE; } - case s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text_3: - s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text_3: { + case s_n_llpkgc_frag__internal__n_double_escaped_character: + s_n_llpkgc_frag__internal__n_double_escaped_character: { if (p == endp) { - return s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text_3; + return s_n_llpkgc_frag__internal__n_double_escaped_character; + } + p++; + goto s_n_llpkgc_frag__internal__n_invoke_update_finish_3; + UNREACHABLE; + } + case s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_1: + s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_1: { + if (p == endp) { + return s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_1; } state->_span_pos0 = (void*) p; - goto s_n_llpkgc_frag__internal__n_pkgc_frag_unquoted_escaped_char; + goto s_n_llpkgc_frag__internal__n_double_escaped_character; UNREACHABLE; } - case s_n_llpkgc_frag__internal__n_pkgc_frag_unquoted_skip_backslash: - s_n_llpkgc_frag__internal__n_pkgc_frag_unquoted_skip_backslash: { + case s_n_llpkgc_frag__internal__n_double_escape: + s_n_llpkgc_frag__internal__n_double_escape: { if (p == endp) { - return s_n_llpkgc_frag__internal__n_pkgc_frag_unquoted_skip_backslash; - } - switch (*p) { - case 92: { - p++; - goto s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text_3; - } - default: { - goto s_n_llpkgc_frag__internal__n_error_2; - } - } - UNREACHABLE; - } - case s_n_llpkgc_frag__internal__n_pkgc_frag_unquoted: - s_n_llpkgc_frag__internal__n_pkgc_frag_unquoted: { - if (p == endp) { - return s_n_llpkgc_frag__internal__n_pkgc_frag_unquoted; - } - switch (*p) { - case 9: { - goto s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__fragment_text_2; - } - case ' ': { - goto s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__fragment_text_2; - } - case '"': { - goto s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__fragment_text_3; - } - case 39: { - goto s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__fragment_text_4; - } - case 92: { - goto s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__fragment_text_5; - } - default: { - p++; - goto s_n_llpkgc_frag__internal__n_pkgc_frag_unquoted; - } - } - UNREACHABLE; - } - case s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text_2: - s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text_2: { - if (p == endp) { - return s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text_2; - } - state->_span_pos0 = (void*) p; - goto s_n_llpkgc_frag__internal__n_pkgc_frag_unquoted; - UNREACHABLE; - } - case s_n_llpkgc_frag__internal__n_pkgc_frag_after_quote: - s_n_llpkgc_frag__internal__n_pkgc_frag_after_quote: { - if (p == endp) { - return s_n_llpkgc_frag__internal__n_pkgc_frag_after_quote; - } - switch (*p) { - case 9: { - goto s_n_llpkgc_frag__internal__n_invoke_llpkgc_frag__frag_complete; - } - case ' ': { - goto s_n_llpkgc_frag__internal__n_invoke_llpkgc_frag__frag_complete; - } - case '"': { - goto s_n_llpkgc_frag__internal__n_pkgc_frag_consume_dq; - } - case 39: { - goto s_n_llpkgc_frag__internal__n_pkgc_frag_consume_sq; - } - case 92: { - goto s_n_llpkgc_frag__internal__n_invoke_update_llpkgc_frag__state_4; - } - default: { - goto s_n_llpkgc_frag__internal__n_invoke_update_llpkgc_frag__state_4; - } - } - UNREACHABLE; - } - case s_n_llpkgc_frag__internal__n_pkgc_frag_consume_closing_dq: - s_n_llpkgc_frag__internal__n_pkgc_frag_consume_closing_dq: { - if (p == endp) { - return s_n_llpkgc_frag__internal__n_pkgc_frag_consume_closing_dq; + return s_n_llpkgc_frag__internal__n_double_escape; } switch (*p) { case '"': { - p++; - goto s_n_llpkgc_frag__internal__n_invoke_update_llpkgc_frag__state_1; - } - default: { - goto s_n_llpkgc_frag__internal__n_error_1; - } - } - UNREACHABLE; - } - case s_n_llpkgc_frag__internal__n_pkgc_frag_dq_special_skip: - s_n_llpkgc_frag__internal__n_pkgc_frag_dq_special_skip: { - if (p == endp) { - return s_n_llpkgc_frag__internal__n_pkgc_frag_dq_special_skip; - } - switch (*p) { - case '"': { - p++; - goto s_n_llpkgc_frag__internal__n_pkgc_frag_dq; + goto s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_1; } case '$': { - p++; - goto s_n_llpkgc_frag__internal__n_pkgc_frag_dq; + goto s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_1; } case 92: { - p++; - goto s_n_llpkgc_frag__internal__n_pkgc_frag_dq; + goto s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_1; } case '`': { - p++; - goto s_n_llpkgc_frag__internal__n_pkgc_frag_dq; + goto s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_1; } default: { - goto s_n_llpkgc_frag__internal__n_error_2; + goto s_n_llpkgc_frag__internal__n_invoke_llpkgc_frag__emit_mark; } } UNREACHABLE; } - case s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text_4: - s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text_4: { + case s_n_llpkgc_frag__internal__n_double_escape_start: + s_n_llpkgc_frag__internal__n_double_escape_start: { if (p == endp) { - return s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text_4; + return s_n_llpkgc_frag__internal__n_double_escape_start; } - state->_span_pos0 = (void*) p; - goto s_n_llpkgc_frag__internal__n_pkgc_frag_dq_special_skip; + p++; + goto s_n_llpkgc_frag__internal__n_double_escape; UNREACHABLE; } - case s_n_llpkgc_frag__internal__n_pkgc_frag_dq_special: - s_n_llpkgc_frag__internal__n_pkgc_frag_dq_special: { + case s_n_llpkgc_frag__internal__n_double_quote: + s_n_llpkgc_frag__internal__n_double_quote: { if (p == endp) { - return s_n_llpkgc_frag__internal__n_pkgc_frag_dq_special; - } - switch (*p) { - case 92: { - p++; - goto s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text_4; - } - default: { - goto s_n_llpkgc_frag__internal__n_error_2; - } - } - UNREACHABLE; - } - case s_n_llpkgc_frag__internal__n_pkgc_frag_dq_keep_backslash: - s_n_llpkgc_frag__internal__n_pkgc_frag_dq_keep_backslash: { - if (p == endp) { - return s_n_llpkgc_frag__internal__n_pkgc_frag_dq_keep_backslash; - } - switch (*p) { - case 92: { - p++; - goto s_n_llpkgc_frag__internal__n_pkgc_frag_dq; - } - default: { - goto s_n_llpkgc_frag__internal__n_error_2; - } - } - UNREACHABLE; - } - case s_n_llpkgc_frag__internal__n_invoke_llpkgc_frag__lookahead_dq_backslash: - s_n_llpkgc_frag__internal__n_invoke_llpkgc_frag__lookahead_dq_backslash: { - switch (llpkgc_frag__lookahead_dq_backslash(state, p, endp)) { - case 0: - goto s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__fragment_text_6; - case 1: - goto s_n_llpkgc_frag__internal__n_pkgc_frag_dq_keep_backslash; - case 4: - goto s_n_llpkgc_frag__internal__n_pause; - default: - goto s_n_llpkgc_frag__internal__n_error_2; - } - UNREACHABLE; - } - case s_n_llpkgc_frag__internal__n_pkgc_frag_dq: - s_n_llpkgc_frag__internal__n_pkgc_frag_dq: { - if (p == endp) { - return s_n_llpkgc_frag__internal__n_pkgc_frag_dq; + return s_n_llpkgc_frag__internal__n_double_quote; } switch (*p) { case '"': { - goto s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__fragment_text; + goto s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__on_fragment_text; } case 92: { - goto s_n_llpkgc_frag__internal__n_invoke_llpkgc_frag__lookahead_dq_backslash; + goto s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__on_fragment_text_1; } default: { p++; - goto s_n_llpkgc_frag__internal__n_pkgc_frag_dq; + goto s_n_llpkgc_frag__internal__n_double_quote; } } UNREACHABLE; } - case s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text: - s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text: { + case s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text: + s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text: { if (p == endp) { - return s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text; + return s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text; } state->_span_pos0 = (void*) p; - goto s_n_llpkgc_frag__internal__n_pkgc_frag_dq; + goto s_n_llpkgc_frag__internal__n_invoke_update_finish_2; UNREACHABLE; } - case s_n_llpkgc_frag__internal__n_pkgc_frag_start: - s_n_llpkgc_frag__internal__n_pkgc_frag_start: { + case s_n_llpkgc_frag__internal__n_single_quote_end: + s_n_llpkgc_frag__internal__n_single_quote_end: { if (p == endp) { - return s_n_llpkgc_frag__internal__n_pkgc_frag_start; + return s_n_llpkgc_frag__internal__n_single_quote_end; + } + p++; + goto s_n_llpkgc_frag__internal__n_invoke_update_finish; + UNREACHABLE; + } + case s_n_llpkgc_frag__internal__n_single_quote: + s_n_llpkgc_frag__internal__n_single_quote: { + if (p == endp) { + return s_n_llpkgc_frag__internal__n_single_quote; + } + switch (*p) { + case 39: { + goto s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__on_fragment_text_2; + } + default: { + p++; + goto s_n_llpkgc_frag__internal__n_single_quote; + } + } + UNREACHABLE; + } + case s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_2: + s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_2: { + if (p == endp) { + return s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_2; + } + state->_span_pos0 = (void*) p; + goto s_n_llpkgc_frag__internal__n_invoke_update_finish_4; + UNREACHABLE; + } + case s_n_llpkgc_frag__internal__n_text: + s_n_llpkgc_frag__internal__n_text: { + if (p == endp) { + return s_n_llpkgc_frag__internal__n_text; + } + switch (*p) { + case 9: { + goto s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__on_fragment_text_3; + } + case 10: { + goto s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__on_fragment_text_3; + } + case 11: { + goto s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__on_fragment_text_3; + } + case 12: { + goto s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__on_fragment_text_3; + } + case 13: { + goto s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__on_fragment_text_3; + } + case ' ': { + goto s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__on_fragment_text_3; + } + case '"': { + goto s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__on_fragment_text_3; + } + case 39: { + goto s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__on_fragment_text_3; + } + case 92: { + goto s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__on_fragment_text_3; + } + default: { + p++; + goto s_n_llpkgc_frag__internal__n_text; + } + } + UNREACHABLE; + } + case s_n_llpkgc_frag__internal__n_escaped_character: + s_n_llpkgc_frag__internal__n_escaped_character: { + if (p == endp) { + return s_n_llpkgc_frag__internal__n_escaped_character; + } + p++; + goto s_n_llpkgc_frag__internal__n_invoke_update_finish_6; + UNREACHABLE; + } + case s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_3: + s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_3: { + if (p == endp) { + return s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_3; + } + state->_span_pos0 = (void*) p; + goto s_n_llpkgc_frag__internal__n_escaped_character; + UNREACHABLE; + } + case s_n_llpkgc_frag__internal__n_escape_start: + s_n_llpkgc_frag__internal__n_escape_start: { + if (p == endp) { + return s_n_llpkgc_frag__internal__n_escape_start; + } + p++; + goto s_n_llpkgc_frag__internal__n_invoke_update_finish_5; + UNREACHABLE; + } + case s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_4: + s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_4: { + if (p == endp) { + return s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_4; + } + state->_span_pos0 = (void*) p; + p++; + goto s_n_llpkgc_frag__internal__n_text; + UNREACHABLE; + } + case s_n_llpkgc_frag__internal__n_token: + s_n_llpkgc_frag__internal__n_token: { + if (p == endp) { + return s_n_llpkgc_frag__internal__n_token; } switch (*p) { case 9: { p++; - goto s_n_llpkgc_frag__internal__n_pkgc_frag_start; + goto s_n_llpkgc_frag__internal__n_invoke_llpkgc_frag__on_frag_complete; + } + case 10: { + p++; + goto s_n_llpkgc_frag__internal__n_invoke_llpkgc_frag__on_frag_complete; + } + case 11: { + p++; + goto s_n_llpkgc_frag__internal__n_invoke_llpkgc_frag__on_frag_complete; + } + case 12: { + p++; + goto s_n_llpkgc_frag__internal__n_invoke_llpkgc_frag__on_frag_complete; + } + case 13: { + p++; + goto s_n_llpkgc_frag__internal__n_invoke_llpkgc_frag__on_frag_complete; } case ' ': { p++; - goto s_n_llpkgc_frag__internal__n_pkgc_frag_start; + goto s_n_llpkgc_frag__internal__n_invoke_llpkgc_frag__on_frag_complete; } case '"': { p++; - goto s_n_llpkgc_frag__internal__n_invoke_update_llpkgc_frag__state; + goto s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text; } case 39: { p++; - goto s_n_llpkgc_frag__internal__n_invoke_update_llpkgc_frag__state_3; + goto s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_2; + } + case 92: { + goto s_n_llpkgc_frag__internal__n_escape_start; } default: { - goto s_n_llpkgc_frag__internal__n_invoke_update_llpkgc_frag__state_4; + goto s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_4; + } + } + UNREACHABLE; + } + case s_n_llpkgc_frag__internal__n_invoke_update_finish: + s_n_llpkgc_frag__internal__n_invoke_update_finish: { + switch (llpkgc_frag__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llpkgc_frag__internal__n_token; + } + UNREACHABLE; + } + case s_n_llpkgc_frag__internal__n_start: + s_n_llpkgc_frag__internal__n_start: { + if (p == endp) { + return s_n_llpkgc_frag__internal__n_start; + } + switch (*p) { + case 9: { + p++; + goto s_n_llpkgc_frag__internal__n_start; + } + case 10: { + p++; + goto s_n_llpkgc_frag__internal__n_start; + } + case 11: { + p++; + goto s_n_llpkgc_frag__internal__n_start; + } + case 12: { + p++; + goto s_n_llpkgc_frag__internal__n_start; + } + case 13: { + p++; + goto s_n_llpkgc_frag__internal__n_start; + } + case ' ': { + p++; + goto s_n_llpkgc_frag__internal__n_start; + } + default: { + goto s_n_llpkgc_frag__internal__n_invoke_update_finish; } } UNREACHABLE; @@ -458,182 +409,163 @@ default: UNREACHABLE; } - s_n_llpkgc_frag__internal__n_invoke_update_llpkgc_frag__state_2: { - switch (llpkgc_frag__internal__c_update_llpkgc_frag__state_2(state, p, endp)) { + s_n_llpkgc_frag__internal__n_invoke_update_finish_1: { + switch (llpkgc_frag__internal__c_update_finish_1(state, p, endp)) { default: - goto s_n_llpkgc_frag__internal__n_pkgc_frag_start; + goto s_n_llpkgc_frag__internal__n_start; } UNREACHABLE; } - s_n_llpkgc_frag__internal__n_error: { - state->error = 0x1; - state->reason = "Fragment complete error"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_error; - return s_error; - UNREACHABLE; - } s_n_llpkgc_frag__internal__n_error_1: { - state->error = 0x1; - state->reason = "Fragment parse error"; + state->error = 0x5; + state->reason = "Internal parser error"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; UNREACHABLE; } - s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__fragment_text_1: { - const unsigned char* start; - int err; - - start = state->_span_pos0; - state->_span_pos0 = NULL; - err = llpkgc_frag__fragment_text(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_frag__internal__n_pkgc_frag_consume_closing_sq; - return s_error; - } - goto s_n_llpkgc_frag__internal__n_pkgc_frag_consume_closing_sq; + s_n_llpkgc_frag__internal__n_error: { + state->error = 0x2; + state->reason = "Callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; UNREACHABLE; } - s_n_llpkgc_frag__internal__n_invoke_update_llpkgc_frag__state_3: { - switch (llpkgc_frag__internal__c_update_llpkgc_frag__state_3(state, p, endp)) { + s_n_llpkgc_frag__internal__n_invoke_llpkgc_frag__on_frag_complete: { + switch (llpkgc_frag__on_frag_complete(state, p, endp)) { + case 0: + goto s_n_llpkgc_frag__internal__n_invoke_update_finish_1; + case 5: + goto s_n_llpkgc_frag__internal__n_error_1; default: - goto s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text_1; + goto s_n_llpkgc_frag__internal__n_error; } UNREACHABLE; } - s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__fragment_text_2: { + s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__on_fragment_text: { const unsigned char* start; int err; start = state->_span_pos0; state->_span_pos0 = NULL; - err = llpkgc_frag__fragment_text(state, start, p); + err = llpkgc_frag__on_fragment_text(state, start, p); if (err != 0) { state->error = err; state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_frag__internal__n_invoke_llpkgc_frag__frag_complete; + state->_current = (void*) (intptr_t) s_n_llpkgc_frag__internal__n_double_quote_end; return s_error; } - goto s_n_llpkgc_frag__internal__n_invoke_llpkgc_frag__frag_complete; + goto s_n_llpkgc_frag__internal__n_double_quote_end; UNREACHABLE; } - s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__fragment_text_3: { - const unsigned char* start; - int err; - - start = state->_span_pos0; - state->_span_pos0 = NULL; - err = llpkgc_frag__fragment_text(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_frag__internal__n_pkgc_frag_consume_dq; - return s_error; + s_n_llpkgc_frag__internal__n_invoke_update_finish_3: { + switch (llpkgc_frag__internal__c_update_finish_2(state, p, endp)) { + default: + goto s_n_llpkgc_frag__internal__n_double_quote; } - goto s_n_llpkgc_frag__internal__n_pkgc_frag_consume_dq; UNREACHABLE; } - s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__fragment_text_4: { - const unsigned char* start; - int err; - - start = state->_span_pos0; - state->_span_pos0 = NULL; - err = llpkgc_frag__fragment_text(state, start, p); - if (err != 0) { - state->error = err; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_frag__internal__n_pkgc_frag_consume_sq; - return s_error; - } - goto s_n_llpkgc_frag__internal__n_pkgc_frag_consume_sq; + s_n_llpkgc_frag__internal__n_error_3: { + state->error = 0x5; + state->reason = "Internal parser error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; UNREACHABLE; } s_n_llpkgc_frag__internal__n_error_2: { - state->error = 0x3; - state->reason = "Lookahead error"; + state->error = 0x2; + state->reason = "Callback error"; state->error_pos = (const char*) p; state->_current = (void*) (intptr_t) s_error; return s_error; UNREACHABLE; } - s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__fragment_text_5: { + s_n_llpkgc_frag__internal__n_invoke_llpkgc_frag__emit_mark: { + switch (llpkgc_frag__emit_mark(state, p, endp)) { + case 0: + goto s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_1; + case 5: + goto s_n_llpkgc_frag__internal__n_error_3; + default: + goto s_n_llpkgc_frag__internal__n_error_2; + } + UNREACHABLE; + } + s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__on_fragment_text_1: { const unsigned char* start; int err; start = state->_span_pos0; state->_span_pos0 = NULL; - err = llpkgc_frag__fragment_text(state, start, p); + err = llpkgc_frag__on_fragment_text(state, start, p); if (err != 0) { state->error = err; state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_frag__internal__n_pkgc_frag_unquoted_skip_backslash; + state->_current = (void*) (intptr_t) s_n_llpkgc_frag__internal__n_double_escape_start; return s_error; } - goto s_n_llpkgc_frag__internal__n_pkgc_frag_unquoted_skip_backslash; + goto s_n_llpkgc_frag__internal__n_double_escape_start; UNREACHABLE; } - s_n_llpkgc_frag__internal__n_invoke_update_llpkgc_frag__state_4: { - switch (llpkgc_frag__internal__c_update_llpkgc_frag__state_1(state, p, endp)) { + s_n_llpkgc_frag__internal__n_invoke_update_finish_2: { + switch (llpkgc_frag__internal__c_update_finish_2(state, p, endp)) { default: - goto s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text_2; + goto s_n_llpkgc_frag__internal__n_double_quote; } UNREACHABLE; } - s_n_llpkgc_frag__internal__n_invoke_update_llpkgc_frag__state_1: { - switch (llpkgc_frag__internal__c_update_llpkgc_frag__state_1(state, p, endp)) { - default: - goto s_n_llpkgc_frag__internal__n_pkgc_frag_after_quote; - } - UNREACHABLE; - } - s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__fragment_text: { + s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__on_fragment_text_2: { const unsigned char* start; int err; start = state->_span_pos0; state->_span_pos0 = NULL; - err = llpkgc_frag__fragment_text(state, start, p); + err = llpkgc_frag__on_fragment_text(state, start, p); if (err != 0) { state->error = err; state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_frag__internal__n_pkgc_frag_consume_closing_dq; + state->_current = (void*) (intptr_t) s_n_llpkgc_frag__internal__n_single_quote_end; return s_error; } - goto s_n_llpkgc_frag__internal__n_pkgc_frag_consume_closing_dq; + goto s_n_llpkgc_frag__internal__n_single_quote_end; UNREACHABLE; } - s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__fragment_text_6: { + s_n_llpkgc_frag__internal__n_invoke_update_finish_4: { + switch (llpkgc_frag__internal__c_update_finish_2(state, p, endp)) { + default: + goto s_n_llpkgc_frag__internal__n_single_quote; + } + UNREACHABLE; + } + s_n_llpkgc_frag__internal__n_span_end_llpkgc_frag__on_fragment_text_3: { const unsigned char* start; int err; start = state->_span_pos0; state->_span_pos0 = NULL; - err = llpkgc_frag__fragment_text(state, start, p); + err = llpkgc_frag__on_fragment_text(state, start, p); if (err != 0) { state->error = err; state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_frag__internal__n_pkgc_frag_dq_special; + state->_current = (void*) (intptr_t) s_n_llpkgc_frag__internal__n_invoke_update_finish; return s_error; } - goto s_n_llpkgc_frag__internal__n_pkgc_frag_dq_special; + goto s_n_llpkgc_frag__internal__n_invoke_update_finish; UNREACHABLE; } - s_n_llpkgc_frag__internal__n_pause: { - state->error = 0x4; - state->reason = "Lookahead required"; - state->error_pos = (const char*) p; - state->_current = (void*) (intptr_t) s_n_llpkgc_frag__internal__n_invoke_llpkgc_frag__lookahead_dq_backslash; - return s_error; - UNREACHABLE; - } - s_n_llpkgc_frag__internal__n_invoke_update_llpkgc_frag__state: { - switch (llpkgc_frag__internal__c_update_llpkgc_frag__state(state, p, endp)) { + s_n_llpkgc_frag__internal__n_invoke_update_finish_6: { + switch (llpkgc_frag__internal__c_update_finish(state, p, endp)) { default: - goto s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__fragment_text; + goto s_n_llpkgc_frag__internal__n_text; + } + UNREACHABLE; + } + s_n_llpkgc_frag__internal__n_invoke_update_finish_5: { + switch (llpkgc_frag__internal__c_update_finish_5(state, p, endp)) { + default: + goto s_n_llpkgc_frag__internal__n_span_start_llpkgc_frag__on_fragment_text_3; } UNREACHABLE; } @@ -662,7 +594,7 @@ if (state->_span_pos0 != NULL) { int error; - error = llpkgc_frag__fragment_text(state, state->_span_pos0, (const char*) endp); + error = llpkgc_frag__on_fragment_text(state, state->_span_pos0, (const char*) endp); if (error != 0) { state->error = error; state->error_pos = endp; @@ -672,3 +604,129 @@ return 0; } +#include <string.h> +#include "llpkgc_frag.h" +int llpkgc_frag__on_frag_complete(llpkgc_frag_t*, const unsigned char*, const unsigned char*); + +int llpkgc_frag__on_fraglist_complete(llpkgc_frag_t* s, const unsigned char* p, const unsigned char* endp) { + const llpkgc_frag_settings_t* settings = s->settings; + int err; + if (settings == NULL || settings->on_fraglist_complete == NULL) return 0; + err = settings->on_fraglist_complete(s); + if (err != 0) { + if (s->reason == NULL) s->reason = "User callback error in on_fraglist_complete"; + s->callback_reason = (void*) s->reason; + return PFFE_USER; + } + return 0; +} + +int llpkgc_frag__on_fragment_text(llpkgc_frag_t* s, const unsigned char* p, const unsigned char* endp) { + const llpkgc_frag_settings_t* settings = s->settings; + int err; + if (settings == NULL || settings->on_fragment_text == NULL) return 0; + err = settings->on_fragment_text(s, (const char*) p, (size_t) (endp - p)); + if (err != 0) { + if (s->reason == NULL) s->reason = "User callback error in on_fragment_text"; + s->callback_reason = (void*) s->reason; + return PFFE_USER; + } + return 0; +} + +int llpkgc_frag__on_frag_complete(llpkgc_frag_t* s, const unsigned char* p, const unsigned char* endp) { + const llpkgc_frag_settings_t* settings = s->settings; + int err; + if (settings == NULL || settings->on_frag_complete == NULL) return 0; + err = settings->on_frag_complete(s); + if (err != 0) { + if (s->reason == NULL) s->reason = "User callback error in on_frag_complete"; + s->callback_reason = (void*) s->reason; + return PFFE_USER; + } + return 0; +} + +void llpkgc_frag_init(llpkgc_frag_t* s, const llpkgc_frag_settings_t* settings) { + llpkgc_frag__internal_init(s); + s->settings = (void*) settings; +} +void llpkgc_frag_reset(llpkgc_frag_t* s) { + const llpkgc_frag_settings_t* settings = s->settings; + void* data = s->data; + llpkgc_frag_init(s, settings); + s->data = data; +} +void llpkgc_frag_settings_init(llpkgc_frag_settings_t* settings) { + memset(settings, 0, sizeof(*settings)); +} +llpkgc_frag_errno_t llpkgc_frag_execute(llpkgc_frag_t* s, const char* data, size_t len) { + if (s->error != 0) return s->error; + if (s->done) { + s->reason = "Input after finish"; + s->error_pos = data; + return s->error = PFFE_INVALID; + } + + if (len == 0) return PFFE_OK; + s->end = (void*) (data + len); + { + int err = llpkgc_frag__internal_execute(s, data, data + len); + if (err == PFFE_USER && s->callback_reason != NULL) + s->reason = s->callback_reason; + + return err; + } +} +llpkgc_frag_errno_t llpkgc_frag_finish(llpkgc_frag_t* s) { + int err; + if (s->error != 0) return s->error; + if (s->done) return PFFE_OK; + switch (s->finish) { + case 0: + err = llpkgc_frag__on_fraglist_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + break; +case 1: + err = llpkgc_frag__on_frag_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + + err = llpkgc_frag__on_fraglist_complete(s, s->end, s->end); + if (err != 0) { + s->error = err; + s->error_pos = s->end; + return s->error; + } + break; +case 2: s->reason = "Unterminated quote at end of input"; + s->error = PFFE_UNFINISHED; s->error_pos = s->end; return s->error; +case 3: s->reason = "Unfinished escape at end of input"; + s->error = PFFE_UNFINISHED; s->error_pos = s->end; return s->error; + default: s->reason = "Invalid finish action"; return s->error = PFFE_INTERNAL; + } + s->done = 1; + return PFFE_OK; +} +llpkgc_frag_errno_t llpkgc_frag_get_errno(const llpkgc_frag_t* s) { return s->error; } +const char* llpkgc_frag_get_error_reason(const llpkgc_frag_t* s) { return s->reason; } +void llpkgc_frag_set_error_reason(llpkgc_frag_t* s, const char* reason) { s->reason = reason; } +const char* llpkgc_frag_get_error_pos(const llpkgc_frag_t* s) { return s->error_pos; } +const char* llpkgc_frag_errno_name(llpkgc_frag_errno_t err) { + switch (err) { + case PFFE_OK: return "PFFE_OK"; + case PFFE_USER: return "PFFE_USER"; + case PFFE_UNFINISHED: return "PFFE_UNFINISHED"; + case PFFE_INVALID: return "PFFE_INVALID"; + + default: return "PFFE_INTERNAL"; + } +} +
diff --git a/Utilities/cmllpkgc/llpkgc_frag__internal.h b/Utilities/cmllpkgc/llpkgc_frag__internal.h index cd21219..399f795 100644 --- a/Utilities/cmllpkgc/llpkgc_frag__internal.h +++ b/Utilities/cmllpkgc/llpkgc_frag__internal.h
@@ -21,10 +21,11 @@ const char* error_pos; void* data; void* _current; - void* llpkgc_frag__settings; - uint8_t llpkgc_frag__state; - uint8_t llpkgc_frag__eof; - uint8_t llpkgc_frag__lookahead; + void* settings; + void* end; + void* callback_reason; + uint32_t finish; + uint8_t done; }; int llpkgc_frag__internal_init(llpkgc_frag__internal_t* s);
diff --git a/Utilities/cmllpkgc/llpkgc_types.h b/Utilities/cmllpkgc/llpkgc_types.h new file mode 100644 index 0000000..c3d48cb --- /dev/null +++ b/Utilities/cmllpkgc/llpkgc_types.h
@@ -0,0 +1,27 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. + See accompanying file LICENSE.rst for details. */ +/* This code was generated by llpkgc, do not edit it by hand + See: https://gitlab.kitware.com/utils/llpkgc */ + +#ifndef INCLUDE_LLPKGC_TYPES_H_ +#define INCLUDE_LLPKGC_TYPES_H_ + +enum llpkgc_dep_comparator { + LLPKGC_DEP_ANY = 0, + LLPKGC_DEP_LESS_THAN = 1, + LLPKGC_DEP_LESS_THAN_EQUAL = 2, + LLPKGC_DEP_EQUAL = 3, + LLPKGC_DEP_NOT_EQUAL = 4, + LLPKGC_DEP_GREATER_THAN = 5, + LLPKGC_DEP_GREATER_THAN_EQUAL = 6, +}; +typedef enum llpkgc_dep_comparator llpkgc_dep_comparator_t; + +enum llpkgc_value_kind { + LLPKGC_VALUE_LITERAL, + LLPKGC_VALUE_FRAGMENTS, + LLPKGC_VALUE_DEPENDENCIES, +}; +typedef enum llpkgc_value_kind llpkgc_value_kind_t; + +#endif /* INCLUDE_LLPKGC_TYPES_H_ */
diff --git a/Utilities/cmllpkgc/llpkgc_whitespace__internal.c b/Utilities/cmllpkgc/llpkgc_whitespace__internal.c new file mode 100644 index 0000000..262c589 --- /dev/null +++ b/Utilities/cmllpkgc/llpkgc_whitespace__internal.c
@@ -0,0 +1,246 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. + See accompanying file LICENSE.rst for details. */ +/* This code was generated by llpkgc, do not edit it by hand + See: https://gitlab.kitware.com/utils/llpkgc */ + + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> + +#ifdef __SSE4_2__ + #ifdef _MSC_VER + #include <nmmintrin.h> + #else /* !_MSC_VER */ + #include <x86intrin.h> + #endif /* _MSC_VER */ +#endif /* __SSE4_2__ */ + +#if defined(__ARM_NEON__) || defined(__ARM_NEON) + #include <arm_neon.h> +#endif /* __ARM_NEON__ */ + +#ifdef __wasm__ + #include <wasm_simd128.h> +#endif /* __wasm__ */ + +#ifdef _MSC_VER + #define ALIGN(n) _declspec(align(n)) + #define UNREACHABLE __assume(0) +#else /* !_MSC_VER */ + #define ALIGN(n) __attribute__((aligned(n))) + #define UNREACHABLE __builtin_unreachable() +#endif /* _MSC_VER */ + +#include "llpkgc_whitespace__internal.h" + +typedef int (*llpkgc_whitespace__internal__span_cb)( + llpkgc_whitespace__internal_t*, const char*, const char*); + +enum llparse_state_e { + s_error, + s_n_llpkgc_whitespace__internal__n_whitespace, + s_n_llpkgc_whitespace__internal__n_span_start_llpkgc_file__deferred_span, + s_n_llpkgc_whitespace__internal__n_lf, + s_n_llpkgc_whitespace__internal__n_cr, + s_n_llpkgc_whitespace__internal__n_escaped, + s_n_llpkgc_whitespace__internal__n_start, +}; +typedef enum llparse_state_e llparse_state_t; + +int llpkgc_file__deferred_span( + llpkgc_whitespace__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llpkgc_whitespace__internal_init(llpkgc_whitespace__internal_t* state) { + memset(state, 0, sizeof(*state)); + state->_current = (void*) (intptr_t) s_n_llpkgc_whitespace__internal__n_start; + return 0; +} + +static llparse_state_t llpkgc_whitespace__internal__run( + llpkgc_whitespace__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + int match; + switch ((llparse_state_t) (intptr_t) state->_current) { + case s_n_llpkgc_whitespace__internal__n_whitespace: + s_n_llpkgc_whitespace__internal__n_whitespace: { + if (p == endp) { + return s_n_llpkgc_whitespace__internal__n_whitespace; + } + switch (*p) { + case 9: { + p++; + goto s_n_llpkgc_whitespace__internal__n_whitespace; + } + case 11: { + p++; + goto s_n_llpkgc_whitespace__internal__n_whitespace; + } + case 12: { + p++; + goto s_n_llpkgc_whitespace__internal__n_whitespace; + } + case ' ': { + p++; + goto s_n_llpkgc_whitespace__internal__n_whitespace; + } + default: { + goto s_n_llpkgc_whitespace__internal__n_span_end_llpkgc_file__deferred_span; + } + } + UNREACHABLE; + } + case s_n_llpkgc_whitespace__internal__n_span_start_llpkgc_file__deferred_span: + s_n_llpkgc_whitespace__internal__n_span_start_llpkgc_file__deferred_span: { + if (p == endp) { + return s_n_llpkgc_whitespace__internal__n_span_start_llpkgc_file__deferred_span; + } + state->_span_pos0 = (void*) p; + p++; + goto s_n_llpkgc_whitespace__internal__n_whitespace; + UNREACHABLE; + } + case s_n_llpkgc_whitespace__internal__n_lf: + s_n_llpkgc_whitespace__internal__n_lf: { + if (p == endp) { + return s_n_llpkgc_whitespace__internal__n_lf; + } + switch (*p) { + case 13: { + p++; + goto s_n_llpkgc_whitespace__internal__n_start; + } + default: { + goto s_n_llpkgc_whitespace__internal__n_start; + } + } + UNREACHABLE; + } + case s_n_llpkgc_whitespace__internal__n_cr: + s_n_llpkgc_whitespace__internal__n_cr: { + if (p == endp) { + return s_n_llpkgc_whitespace__internal__n_cr; + } + switch (*p) { + case 10: { + p++; + goto s_n_llpkgc_whitespace__internal__n_start; + } + default: { + goto s_n_llpkgc_whitespace__internal__n_start; + } + } + UNREACHABLE; + } + case s_n_llpkgc_whitespace__internal__n_escaped: + s_n_llpkgc_whitespace__internal__n_escaped: { + if (p == endp) { + return s_n_llpkgc_whitespace__internal__n_escaped; + } + switch (*p) { + case 10: { + p++; + goto s_n_llpkgc_whitespace__internal__n_lf; + } + case 13: { + p++; + goto s_n_llpkgc_whitespace__internal__n_cr; + } + default: { + goto s_n_llpkgc_whitespace__internal__n_error; + } + } + UNREACHABLE; + } + case s_n_llpkgc_whitespace__internal__n_start: + s_n_llpkgc_whitespace__internal__n_start: { + if (p == endp) { + return s_n_llpkgc_whitespace__internal__n_start; + } + switch (*p) { + case 9: { + goto s_n_llpkgc_whitespace__internal__n_span_start_llpkgc_file__deferred_span; + } + case 11: { + goto s_n_llpkgc_whitespace__internal__n_span_start_llpkgc_file__deferred_span; + } + case 12: { + goto s_n_llpkgc_whitespace__internal__n_span_start_llpkgc_file__deferred_span; + } + case ' ': { + goto s_n_llpkgc_whitespace__internal__n_span_start_llpkgc_file__deferred_span; + } + case 92: { + p++; + goto s_n_llpkgc_whitespace__internal__n_escaped; + } + default: { + goto s_n_llpkgc_whitespace__internal__n_error; + } + } + UNREACHABLE; + } + default: + UNREACHABLE; + } + s_n_llpkgc_whitespace__internal__n_span_end_llpkgc_file__deferred_span: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llpkgc_file__deferred_span(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llpkgc_whitespace__internal__n_start; + return s_error; + } + goto s_n_llpkgc_whitespace__internal__n_start; + UNREACHABLE; + } + s_n_llpkgc_whitespace__internal__n_error: { + state->error = 0x5; + state->reason = "Invalid deferred whitespace range"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + UNREACHABLE; + } +} + +int llpkgc_whitespace__internal_execute(llpkgc_whitespace__internal_t* state, const char* p, const char* endp) { + llparse_state_t next; + + /* check lingering errors */ + if (state->error != 0) { + return state->error; + } + + /* restart spans */ + if (state->_span_pos0 != NULL) { + state->_span_pos0 = (void*) p; + } + + next = llpkgc_whitespace__internal__run(state, (const unsigned char*) p, (const unsigned char*) endp); + if (next == s_error) { + return state->error; + } + state->_current = (void*) (intptr_t) next; + + /* execute spans */ + if (state->_span_pos0 != NULL) { + int error; + + error = llpkgc_file__deferred_span(state, state->_span_pos0, (const char*) endp); + if (error != 0) { + state->error = error; + state->error_pos = endp; + return error; + } + } + + return 0; +}
diff --git a/Utilities/cmllpkgc/llpkgc_whitespace__internal.h b/Utilities/cmllpkgc/llpkgc_whitespace__internal.h new file mode 100644 index 0000000..6ebad8b --- /dev/null +++ b/Utilities/cmllpkgc/llpkgc_whitespace__internal.h
@@ -0,0 +1,33 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. + See accompanying file LICENSE.rst for details. */ +/* This code was generated by llpkgc, do not edit it by hand + See: https://gitlab.kitware.com/utils/llpkgc */ + + +#ifndef INCLUDE_LLPKGC_WHITESPACE__INTERNAL_H_ +#define INCLUDE_LLPKGC_WHITESPACE__INTERNAL_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> + +typedef struct llpkgc_whitespace__internal_s llpkgc_whitespace__internal_t; +struct llpkgc_whitespace__internal_s { + int32_t _index; + void* _span_pos0; + int32_t error; + const char* reason; + const char* error_pos; + void* data; + void* _current; + void* parent; +}; + +int llpkgc_whitespace__internal_init(llpkgc_whitespace__internal_t* s); +int llpkgc_whitespace__internal_execute(llpkgc_whitespace__internal_t* s, const char* p, const char* endp); + +#ifdef __cplusplus +} /* extern "C" */ +#endif +#endif /* INCLUDE_LLPKGC_WHITESPACE__INTERNAL_H_ */
diff --git a/Utilities/std/cm/bits/constexpr.hxx b/Utilities/std/cm/bits/constexpr.hxx new file mode 100644 index 0000000..0d18834 --- /dev/null +++ b/Utilities/std/cm/bits/constexpr.hxx
@@ -0,0 +1,52 @@ +// -*-c++-*- +// vim: set ft=cpp: + +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file LICENSE.rst or https://cmake.org/licensing for details. */ + +#pragma once + +#define CMAKE_CXX_STD_98 199711L +#define CMAKE_CXX_STD_11 201103L +#define CMAKE_CXX_STD_14 201402L +#define CMAKE_CXX_STD_17 201703L +#define CMAKE_CXX_STD_20 202002L +#define CMAKE_CXX_STD_23 202302L + +#if defined(_MSVC_LANG) && (_MSVC_LANG > __cplusplus) +# define CMAKE_CXX_STD _MSVC_LANG +#else +# define CMAKE_CXX_STD __cplusplus +#endif + +#ifndef CONSTEXPR_CXX14 +# if CMAKE_CXX_STD >= CMAKE_CXX_STD_14 +# define CONSTEXPR_CXX14 constexpr +# else +# define CONSTEXPR_CXX14 +# endif +#endif + +#ifndef CONSTEXPR_CXX17 +# if CMAKE_CXX_STD >= CMAKE_CXX_STD_17 +# define CONSTEXPR_CXX17 constexpr +# else +# define CONSTEXPR_CXX17 +# endif +#endif + +#ifndef CONSTEXPR_CXX20 +# if CMAKE_CXX_STD >= CMAKE_CXX_STD_20 +# define CONSTEXPR_CXX20 constexpr +# else +# define CONSTEXPR_CXX20 +# endif +#endif + +#ifndef CONSTEXPR_CXX23 +# if CMAKE_CXX_STD >= CMAKE_CXX_STD_23 +# define CONSTEXPR_CXX23 constexpr +# else +# define CONSTEXPR_CXX23 +# endif +#endif
diff --git a/Utilities/std/cm/bits/string_view.cxx b/Utilities/std/cm/bits/string_view.cxx index d89e964..dade087 100644 --- a/Utilities/std/cm/bits/string_view.cxx +++ b/Utilities/std/cm/bits/string_view.cxx
@@ -13,14 +13,6 @@ namespace cm { -string_view::const_reference string_view::at(size_type pos) const -{ - if (pos >= size_) { - throw std::out_of_range("Index out of range in string_view::at"); - } - return data_[pos]; -} - string_view::size_type string_view::copy(char* dest, size_type count, size_type pos) const { @@ -32,15 +24,6 @@ return rcount; } -string_view string_view::substr(size_type pos, size_type count) const -{ - if (pos > size_) { - throw std::out_of_range("Index out of range in string_view::substr"); - } - size_type const rcount = std::min(count, size_ - pos); - return string_view(data_ + pos, rcount); -} - int string_view::compare(string_view v) const noexcept { size_type const rlen = std::min(size_, v.size_);
diff --git a/Utilities/std/cm/optional b/Utilities/std/cm/optional index 6a03a6c..3ceb29e 100644 --- a/Utilities/std/cm/optional +++ b/Utilities/std/cm/optional
@@ -17,6 +17,7 @@ # endif # include <memory> +# include <cm/bits/constexpr.hxx> # include <cm/utility> #endif @@ -50,8 +51,8 @@ public: using value_type = T; - optional() noexcept = default; - optional(nullopt_t) noexcept; + constexpr optional() noexcept = default; + constexpr optional(nullopt_t) noexcept; optional(optional const& other); optional(optional&& other) noexcept; @@ -88,18 +89,18 @@ optional&>::type operator=(U&& v); - T const* operator->() const; - T* operator->(); - T const& operator*() const&; - T& operator*() &; + constexpr T const* operator->() const; + CONSTEXPR_CXX14 T* operator->(); + constexpr T const& operator*() const&; + CONSTEXPR_CXX14 T& operator*() &; T const&& operator*() const&&; T&& operator*() &&; - explicit operator bool() const noexcept; - bool has_value() const noexcept; + constexpr explicit operator bool() const noexcept; + constexpr bool has_value() const noexcept; - T& value() &; - T const& value() const&; + CONSTEXPR_CXX14 T& value() &; + constexpr T const& value() const&; T&& value() &&; T const&& value() const&&; @@ -148,7 +149,7 @@ } template <typename T> -optional<T>::optional(nullopt_t) noexcept +constexpr optional<T>::optional(nullopt_t) noexcept : optional() { } @@ -454,25 +455,25 @@ } template <typename T> -T const* optional<T>::operator->() const +constexpr T const* optional<T>::operator->() const { return &**this; } template <typename T> -T* optional<T>::operator->() +CONSTEXPR_CXX14 T* optional<T>::operator->() { return &**this; } template <typename T> -T const& optional<T>::operator*() const& +constexpr T const& optional<T>::operator*() const& { return this->_mem.value; } template <typename T> -T& optional<T>::operator*() & +CONSTEXPR_CXX14 T& optional<T>::operator*() & { return this->_mem.value; } @@ -490,19 +491,19 @@ } template <typename T> -bool optional<T>::has_value() const noexcept +constexpr bool optional<T>::has_value() const noexcept { return this->_has_value; } template <typename T> -optional<T>::operator bool() const noexcept +constexpr optional<T>::operator bool() const noexcept { return this->has_value(); } template <typename T> -T& optional<T>::value() & +CONSTEXPR_CXX14 T& optional<T>::value() & { if (!this->has_value()) { throw cm::bad_optional_access{}; @@ -511,12 +512,9 @@ } template <typename T> -T const& optional<T>::value() const& +constexpr T const& optional<T>::value() const& { - if (!this->has_value()) { - throw cm::bad_optional_access{}; - } - return **this; + return **(this->has_value() ? this : throw cm::bad_optional_access{}); } template <typename T>
diff --git a/Utilities/std/cm/string_view b/Utilities/std/cm/string_view index 05618bf..b03f0f4 100644 --- a/Utilities/std/cm/string_view +++ b/Utilities/std/cm/string_view
@@ -21,8 +21,11 @@ # include <functional> # include <iosfwd> # include <iterator> +# include <stdexcept> # include <string> +# include <cm/bits/constexpr.hxx> + namespace cm { class string_view @@ -41,17 +44,25 @@ using size_type = std::string::size_type; using difference_type = std::string::difference_type; - static size_type const npos = static_cast<size_type>(-1); + static constexpr size_type const npos = static_cast<size_type>(-1); - string_view() noexcept = default; - string_view(string_view const&) noexcept = default; +private: + static inline constexpr size_type cxx11_min(size_type a, size_type b) + { + return a > b ? b : a; + } - string_view(char const* s, size_t count) noexcept +public: + constexpr string_view() noexcept = default; + constexpr string_view(string_view const&) noexcept = default; + + constexpr string_view(char const* s, size_t count) noexcept : data_(s) , size_(count) { } + // std::char_traits<char>::length() is constexpr only from C++17 string_view(char const* s) noexcept : data_(s) , size_(traits_type::length(s)) @@ -62,6 +73,7 @@ // a conversion operator on std::string to create a string_view. // Since this implementation is used in C++11, std::string does // not have that conversion. + // std::string is constexpr only from C++20. string_view(std::string const& s) noexcept : data_(s.data()) , size_(s.size()) @@ -72,15 +84,17 @@ // a constructor on std::string that can take a string_view. // Since this implementation is used in C++11, std::string does // not have that constructor. + // std::string is constexpr only from C++20. explicit operator std::string() const { return std::string(data_, size_); } - string_view& operator=(string_view const&) = default; + CONSTEXPR_CXX14 string_view& operator=(string_view const&) = default; - const_iterator begin() const noexcept { return data_; } - const_iterator end() const noexcept { return data_ + size_; } - const_iterator cbegin() const noexcept { return begin(); } - const_iterator cend() const noexcept { return end(); } + constexpr const_iterator begin() const noexcept { return data_; } + constexpr const_iterator end() const noexcept { return data_ + size_; } + constexpr const_iterator cbegin() const noexcept { return begin(); } + constexpr const_iterator cend() const noexcept { return end(); } + // `std::reverse_iterator` is constexpr only from C++17 const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); @@ -92,36 +106,52 @@ const_reverse_iterator crbegin() const noexcept { return rbegin(); } const_reverse_iterator crend() const noexcept { return rend(); } - const_reference operator[](size_type pos) const noexcept + constexpr const_reference operator[](size_type pos) const noexcept { return data_[pos]; } - const_reference at(size_type pos) const; - const_reference front() const noexcept { return data_[0]; } - const_reference back() const noexcept { return data_[size_ - 1]; } - const_pointer data() const noexcept { return data_; } - size_type size() const noexcept { return size_; } - size_type length() const noexcept { return size_; } - size_type max_size() const noexcept { return npos - 1; } - bool empty() const noexcept { return size_ == 0; } + constexpr const_reference at(size_type pos) const + { + return data_[pos < size_ ? pos + : throw std::out_of_range( + "Index out of range in string_view::at")]; + } - void remove_prefix(size_type n) noexcept + constexpr const_reference front() const noexcept { return data_[0]; } + constexpr const_reference back() const noexcept { return data_[size_ - 1]; } + constexpr const_pointer data() const noexcept { return data_; } + + constexpr size_type size() const noexcept { return size_; } + constexpr size_type length() const noexcept { return size_; } + constexpr size_type max_size() const noexcept { return npos - 1; } + constexpr bool empty() const noexcept { return size_ == 0; } + + CONSTEXPR_CXX14 void remove_prefix(size_type n) noexcept { data_ += n; size_ -= n; } - void remove_suffix(size_type n) noexcept { size_ -= n; } - void swap(string_view& v) noexcept + CONSTEXPR_CXX14 void remove_suffix(size_type n) noexcept { size_ -= n; } + CONSTEXPR_CXX14 void swap(string_view& v) noexcept { string_view tmp = v; v = *this; *this = tmp; } + // std::char_traits<char>::copy() is constexpr only from C++20 size_type copy(char* dest, size_type count, size_type pos = 0) const; - string_view substr(size_type pos = 0, size_type count = npos) const; + constexpr string_view substr(size_type pos = 0, size_type count = npos) const + { + return pos <= size_ + ? string_view(data_ + pos, cxx11_min(count, size_ - pos)) + : throw std::out_of_range("Index out of range in string_view::substr"); + ; + } + + // std::char_traits<char>::compare() is constexpr only from C++17 int compare(string_view v) const noexcept; int compare(size_type pos1, size_type count1, string_view v) const; int compare(size_type pos1, size_type count1, string_view v, size_type pos2, @@ -131,6 +161,8 @@ int compare(size_type pos1, size_type count1, char const* s, size_type count2) const; + // std::char_traits<char>::compare() is constexpr only from C++17 + // std::char_traits<char>::find() is constexpr only from C++17 size_type find(string_view v, size_type pos = 0) const noexcept; size_type find(char c, size_type pos = 0) const noexcept; size_type find(char const* s, size_type pos, size_type count) const;
diff --git a/Utilities/std/cmext/string_view b/Utilities/std/cmext/string_view index 29a1cf9..dc98e95 100644 --- a/Utilities/std/cmext/string_view +++ b/Utilities/std/cmext/string_view
@@ -20,16 +20,18 @@ */ class static_string_view : public string_view { - static_string_view(string_view v) + constexpr static_string_view(string_view v) : string_view(v) { } - friend static_string_view operator"" _s(char const* data, size_t size); + friend constexpr static_string_view operator"" _s(char const* data, + size_t size); }; /** Create a static_string_view using `""_s` literal syntax. */ -inline static_string_view operator"" _s(char const* data, size_t size) +inline constexpr static_string_view operator"" _s(char const* data, + size_t size) { return string_view(data, size); }