From bcc396581387582acec736dcfac577f477f60821 Mon Sep 17 00:00:00 2001
From: Kyle Edwards <kyle.edwards@kitware.com>
Date: Wed, 24 Aug 2022 15:16:50 -0400
Subject: Tests: Fix VS10Project SourceGroupTreeCMakeLists check

Fix an `IN LISTS` loop, fix a variable check, and escape backslashes
in the regex used to search for source group names.
---
 Tests/RunCMake/VS10Project/SourceGroupHelpers.cmake              | 5 +++--
 Tests/RunCMake/VS10Project/SourceGroupTreeCMakeLists-check.cmake | 4 ++--
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/Tests/RunCMake/VS10Project/SourceGroupHelpers.cmake b/Tests/RunCMake/VS10Project/SourceGroupHelpers.cmake
index c82a66e..3a5d2e7 100644
--- a/Tests/RunCMake/VS10Project/SourceGroupHelpers.cmake
+++ b/Tests/RunCMake/VS10Project/SourceGroupHelpers.cmake
@@ -1,8 +1,9 @@
 function(find_source_group LINES NAME)
   set(foundFileFilter 0)
   set(foundFilter 0)
+  string(REPLACE "\\" "\\\\" regexName "${NAME}")
   foreach(line IN LISTS LINES)
-    if(line MATCHES "<Filter>${NAME}</Filter>")
+    if(line MATCHES "<Filter>${regexName}</Filter>")
       if(foundFileFilter)
         set(RunCMake_TEST_FAILED "Multiple files listed with filter for ${NAME}." PARENT_SCOPE)
         set(FILTER_FOUND 0 PARENT_SCOPE)
@@ -10,7 +11,7 @@ function(find_source_group LINES NAME)
       endif()
       set(foundFileFilter 1)
     endif()
-    if(line MATCHES "<Filter.*Include=\"${NAME}\"")
+    if(line MATCHES "<Filter.*Include=\"${regexName}\"")
       if(foundFilter)
         set(RunCMake_TEST_FAILED "Multiple copies of ${NAME} filter listed." PARENT_SCOPE)
         set(FILTER_FOUND 0 PARENT_SCOPE)
diff --git a/Tests/RunCMake/VS10Project/SourceGroupTreeCMakeLists-check.cmake b/Tests/RunCMake/VS10Project/SourceGroupTreeCMakeLists-check.cmake
index ee0c412..28d0d29 100644
--- a/Tests/RunCMake/VS10Project/SourceGroupTreeCMakeLists-check.cmake
+++ b/Tests/RunCMake/VS10Project/SourceGroupTreeCMakeLists-check.cmake
@@ -18,9 +18,9 @@ set(SOURCE_GROUPS_TO_FIND
   "SourcesPrefix\\PrefixedNested"
 )
 
-foreach(GROUP_NAME IN LISTS ${SOURCE_GROUPS_TO_FIND})
+foreach(GROUP_NAME IN LISTS SOURCE_GROUPS_TO_FIND)
   find_source_group("${lines}" ${GROUP_NAME})
-  if(NOT ${FILTER_FOUND})
+  if(NOT FILTER_FOUND)
     return()
   endif()
 endforeach()
-- 
cgit v0.12


From 970052feddcb49f52b49e04a9edd7cb5e9085859 Mon Sep 17 00:00:00 2001
From: Kyle Edwards <kyle.edwards@kitware.com>
Date: Wed, 24 Aug 2022 14:14:09 -0400
Subject: FILE_SET: Fix source group detection

Call MatchChildrenFiles() instead of MatchesFiles() in order to
account for files being in subgroups of source groups.

Fixes: #23880
---
 Source/cmGeneratorTarget.cxx                              |  2 +-
 Source/cmSourceGroup.cxx                                  | 15 +++++++++++++++
 Source/cmSourceGroup.h                                    |  6 ++++++
 Tests/RunCMake/VS10Project/RunCMakeTest.cmake             |  1 +
 Tests/RunCMake/VS10Project/SourceGroupFileSet-check.cmake | 13 +++++++++++++
 Tests/RunCMake/VS10Project/SourceGroupFileSet.cmake       |  3 +++
 6 files changed, 39 insertions(+), 1 deletion(-)
 create mode 100644 Tests/RunCMake/VS10Project/SourceGroupFileSet-check.cmake
 create mode 100644 Tests/RunCMake/VS10Project/SourceGroupFileSet.cmake

diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 0c351ad..99afee9 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -1702,7 +1702,7 @@ void addFileSetEntry(cmGeneratorTarget const* headTarget,
       }
       bool found = false;
       for (auto const& sg : headTarget->Makefile->GetSourceGroups()) {
-        if (sg.MatchesFiles(path)) {
+        if (sg.MatchChildrenFiles(path)) {
           found = true;
           break;
         }
diff --git a/Source/cmSourceGroup.cxx b/Source/cmSourceGroup.cxx
index 155068cb..6019de1 100644
--- a/Source/cmSourceGroup.cxx
+++ b/Source/cmSourceGroup.cxx
@@ -124,6 +124,21 @@ cmSourceGroup* cmSourceGroup::MatchChildrenFiles(const std::string& name)
   return nullptr;
 }
 
+const cmSourceGroup* cmSourceGroup::MatchChildrenFiles(
+  const std::string& name) const
+{
+  if (this->MatchesFiles(name)) {
+    return this;
+  }
+  for (const cmSourceGroup& group : this->Internal->GroupChildren) {
+    const cmSourceGroup* result = group.MatchChildrenFiles(name);
+    if (result) {
+      return result;
+    }
+  }
+  return nullptr;
+}
+
 cmSourceGroup* cmSourceGroup::MatchChildrenRegex(const std::string& name)
 {
   for (cmSourceGroup& group : this->Internal->GroupChildren) {
diff --git a/Source/cmSourceGroup.h b/Source/cmSourceGroup.h
index 295240d..9ce71c7 100644
--- a/Source/cmSourceGroup.h
+++ b/Source/cmSourceGroup.h
@@ -80,6 +80,12 @@ public:
   cmSourceGroup* MatchChildrenFiles(const std::string& name);
 
   /**
+   * Check if the given name matches this group's explicit file list
+   * in children.
+   */
+  const cmSourceGroup* MatchChildrenFiles(const std::string& name) const;
+
+  /**
    * Check if the given name matches this group's regex in children.
    */
   cmSourceGroup* MatchChildrenRegex(const std::string& name);
diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
index ee8821a..e540b9f 100644
--- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
@@ -16,6 +16,7 @@ run_cmake(NoImpLib)
 run_cmake(RuntimeLibrary)
 run_cmake(SourceGroupCMakeLists)
 run_cmake(SourceGroupTreeCMakeLists)
+run_cmake(SourceGroupFileSet)
 run_cmake(VsConfigurationType)
 run_cmake(VsTargetsFileReferences)
 run_cmake(VsCustomProps)
diff --git a/Tests/RunCMake/VS10Project/SourceGroupFileSet-check.cmake b/Tests/RunCMake/VS10Project/SourceGroupFileSet-check.cmake
new file mode 100644
index 0000000..fb2eecc
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/SourceGroupFileSet-check.cmake
@@ -0,0 +1,13 @@
+cmake_policy(SET CMP0011 NEW)
+
+set(vcFiltersFile "${RunCMake_TEST_BINARY_DIR}/SourceGroupFileSet.vcxproj.filters")
+if(NOT EXISTS "${vcFiltersFile}")
+  set(RunCMake_TEST_FAILED "Filters file ${vcFiltersFile} does not exist.")
+  return()
+endif()
+
+file(STRINGS "${vcFiltersFile}" lines)
+
+include(${RunCMake_TEST_SOURCE_DIR}/SourceGroupHelpers.cmake)
+
+find_source_group("${lines}" "Header Files\\SourceGroupFileSet")
diff --git a/Tests/RunCMake/VS10Project/SourceGroupFileSet.cmake b/Tests/RunCMake/VS10Project/SourceGroupFileSet.cmake
new file mode 100644
index 0000000..9541687
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/SourceGroupFileSet.cmake
@@ -0,0 +1,3 @@
+add_library(SourceGroupFileSet INTERFACE)
+target_sources(SourceGroupFileSet PUBLIC FILE_SET HEADERS FILES iface.h)
+source_group("Header Files/SourceGroupFileSet" FILES iface.h)
-- 
cgit v0.12