summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCristian Le <git@lecris.dev>2024-01-03 19:34:56 (GMT)
committerBrad King <brad.king@kitware.com>2024-01-09 21:36:55 (GMT)
commitfa00928bcded97d20c9aa2813f68f1df41591125 (patch)
treec84c88485c075b94d2f92d3e6467fb776a217f41
parentff0085cf74eb10a7e5f9c906258022c6b8b68413 (diff)
downloadCMake-fa00928bcded97d20c9aa2813f68f1df41591125.zip
CMake-fa00928bcded97d20c9aa2813f68f1df41591125.tar.gz
CMake-fa00928bcded97d20c9aa2813f68f1df41591125.tar.bz2
file: `STRINGS` + `REGEX` store match results
Signed-off-by: Cristian Le <cristian.le@mpsd.mpg.de>
-rw-r--r--Help/command/file.rst5
-rw-r--r--Help/manual/cmake-policies.7.rst1
-rw-r--r--Help/policy/CMP0159.rst24
-rw-r--r--Source/cmFileCommand.cxx37
-rw-r--r--Source/cmPolicies.h5
-rw-r--r--Tests/RunCMake/CMakeLists.txt1
-rw-r--r--Tests/RunCMake/CommandLine/trace-try_compile-redirect.cmake1
-rw-r--r--Tests/RunCMake/file-STRINGS/CMP0159-Common.cmake12
-rw-r--r--Tests/RunCMake/file-STRINGS/CMP0159-NEW-stdout.txt5
-rw-r--r--Tests/RunCMake/file-STRINGS/CMP0159-NEW.cmake4
-rw-r--r--Tests/RunCMake/file-STRINGS/CMP0159-OLD-stdout.txt5
-rw-r--r--Tests/RunCMake/file-STRINGS/CMP0159-OLD.cmake4
-rw-r--r--Tests/RunCMake/file-STRINGS/CMP0159-WARN-stderr.txt10
-rw-r--r--Tests/RunCMake/file-STRINGS/CMP0159-WARN-stdout.txt5
-rw-r--r--Tests/RunCMake/file-STRINGS/CMP0159-WARN.cmake4
-rw-r--r--Tests/RunCMake/file-STRINGS/CMP0159.txt3
-rw-r--r--Tests/RunCMake/file-STRINGS/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/file-STRINGS/RunCMakeTest.cmake5
18 files changed, 133 insertions, 1 deletions
diff --git a/Help/command/file.rst b/Help/command/file.rst
index 957b8b5..4acdc7e 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -113,6 +113,11 @@ Reading
Consider only strings that match the given regular expression,
as described under :ref:`string(REGEX) <Regex Specification>`.
+ .. versionchanged:: 3.29
+ Capture groups from the last match in the file are stored in
+ :variable:`CMAKE_MATCH_<n>`, similar to
+ :command:`string(REGEX MATCHALL)`. See policy :policy:`CMP0159`.
+
``ENCODING <encoding-type>``
.. versionadded:: 3.1
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 35b4497..2bb4f2f 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.29
.. toctree::
:maxdepth: 1
+ CMP0159: file(STRINGS) with REGEX updates CMAKE_MATCH_<n>. </policy/CMP0159>
CMP0158: add_test() honors CMAKE_CROSSCOMPILING_EMULATOR only when cross-compiling. </policy/CMP0158>
CMP0157: Swift compilation mode is selected by an abstraction. </policy/CMP0157>
CMP0156: De-duplicate libraries on link lines based on linker capabilities. </policy/CMP0156>
diff --git a/Help/policy/CMP0159.rst b/Help/policy/CMP0159.rst
new file mode 100644
index 0000000..2d05282
--- /dev/null
+++ b/Help/policy/CMP0159.rst
@@ -0,0 +1,24 @@
+CMP0159
+-------
+
+.. versionadded:: 3.29
+
+:command:`file(STRINGS)` with ``REGEX`` updates :variable:`CMAKE_MATCH_<n>`.
+
+In CMake 3.28 and below the :command:`file(STRINGS)` command's ``REGEX``
+option does not affect :variable:`CMAKE_MATCH_<n>` variables. CMake 3.29
+and above prefer to update the :variable:`CMAKE_MATCH_<n>` variables using
+captures from the last match in the file, similar to the
+:command:`string(REGEX MATCHALL)` command. This policy provides
+compatibility for projects that have not been updated to expect the behavior.
+
+The ``OLD`` behavior for this policy is for :command:`file(STRINGS)` with
+``REGEX`` to not store capture groups in :variable:`CMAKE_MATCH_<n>`
+variables. The ``NEW`` behavior is to store the capture groups.
+
+This policy was introduced in CMake version 3.29. Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike many policies, CMake version |release| does *not* warn
+when this policy is not set and simply uses ``OLD`` behavior.
+
+.. include:: DEPRECATED.txt
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index c1b7b48..e3f5b96 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -315,6 +315,7 @@ bool HandleStringsCommand(std::vector<std::string> const& args,
unsigned int limit_count = 0;
cmsys::RegularExpression regex;
bool have_regex = false;
+ bool store_regex = true;
bool newline_consume = false;
bool hex_conversion_enabled = true;
enum
@@ -399,6 +400,26 @@ bool HandleStringsCommand(std::vector<std::string> const& args,
return false;
}
have_regex = true;
+ switch (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0159)) {
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ // store_regex = true
+ break;
+ case cmPolicies::WARN:
+ if (status.GetMakefile().PolicyOptionalWarningEnabled(
+ "CMAKE_POLICY_WARNING_CMP0159")) {
+ status.GetMakefile().IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0159), '\n',
+ "For compatibility, CMake is leaving CMAKE_MATCH_<n> "
+ "unchanged."));
+ }
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ store_regex = false;
+ break;
+ }
arg_mode = arg_none;
} else if (arg_mode == arg_encoding) {
if (args[i] == "UTF-8") {
@@ -539,6 +560,10 @@ bool HandleStringsCommand(std::vector<std::string> const& args,
// string matches the requirements. The length may now be as
// low as zero since blank lines are allowed.
if (s.length() >= minlen && (!have_regex || regex.find(s))) {
+ if (store_regex) {
+ status.GetMakefile().ClearMatches();
+ status.GetMakefile().StoreMatches(regex);
+ }
output_size += static_cast<int>(s.size()) + 1;
if (limit_output >= 0 && output_size >= limit_output) {
s.clear();
@@ -555,6 +580,10 @@ bool HandleStringsCommand(std::vector<std::string> const& args,
// be at least one no matter what the user specified.
if (s.length() >= minlen && !s.empty() &&
(!have_regex || regex.find(s))) {
+ if (store_regex) {
+ status.GetMakefile().ClearMatches();
+ status.GetMakefile().StoreMatches(regex);
+ }
output_size += static_cast<int>(s.size()) + 1;
if (limit_output >= 0 && output_size >= limit_output) {
s.clear();
@@ -572,6 +601,10 @@ bool HandleStringsCommand(std::vector<std::string> const& args,
if (maxlen > 0 && s.size() == maxlen) {
// Terminate a string if the maximum length is reached.
if (s.length() >= minlen && (!have_regex || regex.find(s))) {
+ if (store_regex) {
+ status.GetMakefile().ClearMatches();
+ status.GetMakefile().StoreMatches(regex);
+ }
output_size += static_cast<int>(s.size()) + 1;
if (limit_output >= 0 && output_size >= limit_output) {
s.clear();
@@ -588,6 +621,10 @@ bool HandleStringsCommand(std::vector<std::string> const& args,
// matches the requirements.
if ((!limit_count || strings.size() < limit_count) && !s.empty() &&
s.length() >= minlen && (!have_regex || regex.find(s))) {
+ if (store_regex) {
+ status.GetMakefile().ClearMatches();
+ status.GetMakefile().StoreMatches(regex);
+ }
output_size += static_cast<int>(s.size()) + 1;
if (limit_output < 0 || output_size < limit_output) {
strings.push_back(s);
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 3f20dc0..65870dc 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -484,7 +484,10 @@ class cmMakefile;
SELECT(POLICY, CMP0158, \
"add_test() honors CMAKE_CROSSCOMPILING_EMULATOR only when " \
"cross-compiling.", \
- 3, 29, 0, cmPolicies::WARN)
+ 3, 29, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0159, \
+ "file(STRINGS) with REGEX updates CMAKE_MATCH_<n>.", 3, 29, 0, \
+ cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index a4e4800..7f58ceb 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -538,6 +538,7 @@ foreach(var
endforeach()
add_RunCMake_test(file-DOWNLOAD)
add_RunCMake_test(file-RPATH -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME})
+add_RunCMake_test(file-STRINGS)
add_RunCMake_test(find_file -DMINGW=${MINGW})
add_RunCMake_test(find_library -DMINGW=${MINGW} -DCYGWIN=${CYGWIN} -DMSYS=${MSYS} -DMSVC=${MSVC})
add_RunCMake_test(find_package -DMINGW=${MINGW} -DMSYS=${MSYS})
diff --git a/Tests/RunCMake/CommandLine/trace-try_compile-redirect.cmake b/Tests/RunCMake/CommandLine/trace-try_compile-redirect.cmake
index 4107aa4..ef08627 100644
--- a/Tests/RunCMake/CommandLine/trace-try_compile-redirect.cmake
+++ b/Tests/RunCMake/CommandLine/trace-try_compile-redirect.cmake
@@ -1,2 +1,3 @@
cmake_policy(VERSION 3.24)
+cmake_policy(SET CMP0159 NEW)
enable_language(C)
diff --git a/Tests/RunCMake/file-STRINGS/CMP0159-Common.cmake b/Tests/RunCMake/file-STRINGS/CMP0159-Common.cmake
new file mode 100644
index 0000000..3608882
--- /dev/null
+++ b/Tests/RunCMake/file-STRINGS/CMP0159-Common.cmake
@@ -0,0 +1,12 @@
+function (output_results msg)
+ message(STATUS "results from: ${msg}")
+ message(STATUS "CMAKE_MATCH_0: -->${CMAKE_MATCH_0}<--")
+ message(STATUS "CMAKE_MATCH_1: -->${CMAKE_MATCH_1}<--")
+ message(STATUS "CMAKE_MATCH_2: -->${CMAKE_MATCH_2}<--")
+ message(STATUS "CMAKE_MATCH_COUNT: -->${CMAKE_MATCH_COUNT}<--")
+endfunction ()
+
+# Populate `CMAKE_MATCH_<n>` with some initial value
+string(REGEX MATCH "(.*):" _ "Initial-value:")
+file(STRINGS CMP0159.txt _ REGEX "(.*): (.*)")
+output_results(CMP0159)
diff --git a/Tests/RunCMake/file-STRINGS/CMP0159-NEW-stdout.txt b/Tests/RunCMake/file-STRINGS/CMP0159-NEW-stdout.txt
new file mode 100644
index 0000000..f163622
--- /dev/null
+++ b/Tests/RunCMake/file-STRINGS/CMP0159-NEW-stdout.txt
@@ -0,0 +1,5 @@
+-- results from: CMP0159
+-- CMAKE_MATCH_0: -->real-value: 1<--
+-- CMAKE_MATCH_1: -->real-value<--
+-- CMAKE_MATCH_2: -->1<--
+-- CMAKE_MATCH_COUNT: -->2<--
diff --git a/Tests/RunCMake/file-STRINGS/CMP0159-NEW.cmake b/Tests/RunCMake/file-STRINGS/CMP0159-NEW.cmake
new file mode 100644
index 0000000..8617561
--- /dev/null
+++ b/Tests/RunCMake/file-STRINGS/CMP0159-NEW.cmake
@@ -0,0 +1,4 @@
+
+cmake_policy(SET CMP0159 NEW)
+
+include(CMP0159-Common.cmake)
diff --git a/Tests/RunCMake/file-STRINGS/CMP0159-OLD-stdout.txt b/Tests/RunCMake/file-STRINGS/CMP0159-OLD-stdout.txt
new file mode 100644
index 0000000..16ee678
--- /dev/null
+++ b/Tests/RunCMake/file-STRINGS/CMP0159-OLD-stdout.txt
@@ -0,0 +1,5 @@
+-- results from: CMP0159
+-- CMAKE_MATCH_0: -->Initial-value:<--
+-- CMAKE_MATCH_1: -->Initial-value<--
+-- CMAKE_MATCH_2: --><--
+-- CMAKE_MATCH_COUNT: -->1<--
diff --git a/Tests/RunCMake/file-STRINGS/CMP0159-OLD.cmake b/Tests/RunCMake/file-STRINGS/CMP0159-OLD.cmake
new file mode 100644
index 0000000..4137aea
--- /dev/null
+++ b/Tests/RunCMake/file-STRINGS/CMP0159-OLD.cmake
@@ -0,0 +1,4 @@
+
+cmake_policy(SET CMP0159 OLD)
+
+include(CMP0159-Common.cmake)
diff --git a/Tests/RunCMake/file-STRINGS/CMP0159-WARN-stderr.txt b/Tests/RunCMake/file-STRINGS/CMP0159-WARN-stderr.txt
new file mode 100644
index 0000000..e82486c
--- /dev/null
+++ b/Tests/RunCMake/file-STRINGS/CMP0159-WARN-stderr.txt
@@ -0,0 +1,10 @@
+CMake Warning \(dev\) at CMP0159-Common.cmake:[0-9]+ \(file\):
+ Policy CMP0159 is not set: file\(STRINGS\) with REGEX updates
+ CMAKE_MATCH_<n>\. Run "cmake --help-policy CMP0159" for policy details\.
+ Use the cmake_policy command to set the policy and suppress this warning\.
+
+ For compatibility, CMake is leaving CMAKE_MATCH_<n> unchanged\.
+Call Stack \(most recent call first\):
+ CMP0159-WARN.cmake:[0-9]+ \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/file-STRINGS/CMP0159-WARN-stdout.txt b/Tests/RunCMake/file-STRINGS/CMP0159-WARN-stdout.txt
new file mode 100644
index 0000000..16ee678
--- /dev/null
+++ b/Tests/RunCMake/file-STRINGS/CMP0159-WARN-stdout.txt
@@ -0,0 +1,5 @@
+-- results from: CMP0159
+-- CMAKE_MATCH_0: -->Initial-value:<--
+-- CMAKE_MATCH_1: -->Initial-value<--
+-- CMAKE_MATCH_2: --><--
+-- CMAKE_MATCH_COUNT: -->1<--
diff --git a/Tests/RunCMake/file-STRINGS/CMP0159-WARN.cmake b/Tests/RunCMake/file-STRINGS/CMP0159-WARN.cmake
new file mode 100644
index 0000000..1feab4b
--- /dev/null
+++ b/Tests/RunCMake/file-STRINGS/CMP0159-WARN.cmake
@@ -0,0 +1,4 @@
+
+set(CMAKE_POLICY_WARNING_CMP0159 TRUE)
+
+include(CMP0159-Common.cmake)
diff --git a/Tests/RunCMake/file-STRINGS/CMP0159.txt b/Tests/RunCMake/file-STRINGS/CMP0159.txt
new file mode 100644
index 0000000..4b31aed
--- /dev/null
+++ b/Tests/RunCMake/file-STRINGS/CMP0159.txt
@@ -0,0 +1,3 @@
+overwritten-value: -1
+real-value: 1
+ignored = -2
diff --git a/Tests/RunCMake/file-STRINGS/CMakeLists.txt b/Tests/RunCMake/file-STRINGS/CMakeLists.txt
new file mode 100644
index 0000000..9a66cde
--- /dev/null
+++ b/Tests/RunCMake/file-STRINGS/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.13)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/file-STRINGS/RunCMakeTest.cmake b/Tests/RunCMake/file-STRINGS/RunCMakeTest.cmake
new file mode 100644
index 0000000..a22b3d8
--- /dev/null
+++ b/Tests/RunCMake/file-STRINGS/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0159-WARN)
+run_cmake(CMP0159-OLD)
+run_cmake(CMP0159-NEW)