Browse Source

Merge topic 'astgrep-cmstrcat'

557c44b93e cmStrCat: use character literals where possible
23779057fd cmStrCat: combine neighboring arguments where possible
483d13daf4 ast-grep: add a rule to turn strings into characters
61743471d9 ast-grep: add a rule to find adjacent string literals in cmStrCat calls

Acked-by: Kitware Robot <[email protected]>
Acked-by: buildbot <[email protected]>
Merge-request: !10790
Brad King 7 tháng trước cách đây
mục cha
commit
6be0c6d26a
94 tập tin đã thay đổi với 1123 bổ sung271 xóa
  1. 1 1
      Source/CPack/cmCPackArchiveGenerator.cxx
  2. 1 1
      Source/CPack/cmCPackBundleGenerator.cxx
  3. 5 5
      Source/CPack/cmCPackGenerator.cxx
  4. 9 9
      Source/CPack/cmCPackNSISGenerator.cxx
  5. 2 2
      Source/CPack/cmCPackProductBuildGenerator.cxx
  6. 1 1
      Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
  7. 1 1
      Source/CTest/cmCTestSubmitHandler.cxx
  8. 1 1
      Source/CTest/cmCTestTestHandler.cxx
  9. 2 2
      Source/CTest/cmParseCoberturaCoverage.cxx
  10. 4 3
      Source/CursesDialog/cmCursesMainForm.cxx
  11. 1 1
      Source/cmAddLibraryCommand.cxx
  12. 3 2
      Source/cmAddSubDirectoryCommand.cxx
  13. 1 1
      Source/cmAddTestCommand.cxx
  14. 1 1
      Source/cmBuildCommand.cxx
  15. 4 4
      Source/cmCMakeLanguageCommand.cxx
  16. 3 3
      Source/cmCMakePathCommand.cxx
  17. 14 14
      Source/cmCMakePkgConfigCommand.cxx
  18. 2 2
      Source/cmCMakePolicyCommand.cxx
  19. 12 12
      Source/cmCMakePresetsErrors.cxx
  20. 4 3
      Source/cmComputeLinkDepends.cxx
  21. 1 1
      Source/cmComputeLinkInformation.cxx
  22. 3 3
      Source/cmCoreTryCompile.cxx
  23. 1 1
      Source/cmCxxModuleMapper.cxx
  24. 1 1
      Source/cmDefinePropertyCommand.cxx
  25. 2 1
      Source/cmExperimental.cxx
  26. 3 2
      Source/cmExportCommand.cxx
  27. 4 4
      Source/cmExtraCodeBlocksGenerator.cxx
  28. 2 2
      Source/cmExtraCodeLiteGenerator.cxx
  29. 1 1
      Source/cmExtraSublimeTextGenerator.cxx
  30. 2 2
      Source/cmFLTKWrapUICommand.cxx
  31. 3 3
      Source/cmFileAPI.cxx
  32. 1 1
      Source/cmFileAPICommand.cxx
  33. 1 1
      Source/cmFileAPIToolchains.cxx
  34. 12 8
      Source/cmFileCommand.cxx
  35. 2 2
      Source/cmFileCopier.cxx
  36. 2 2
      Source/cmFindBase.cxx
  37. 3 3
      Source/cmFindLibraryCommand.cxx
  38. 1 1
      Source/cmFindPackageCommand.cxx
  39. 1 1
      Source/cmForEachCommand.cxx
  40. 13 12
      Source/cmGeneratorTarget.cxx
  41. 2 3
      Source/cmGeneratorTarget_Link.cxx
  42. 1 1
      Source/cmGhsMultiTargetGenerator.cxx
  43. 9 6
      Source/cmGlobalGhsMultiGenerator.cxx
  44. 4 4
      Source/cmGlobalNinjaGenerator.cxx
  45. 4 2
      Source/cmGlobalVisualStudio10Generator.cxx
  46. 4 4
      Source/cmGlobalXCodeGenerator.cxx
  47. 1 1
      Source/cmIncludeCommand.cxx
  48. 3 2
      Source/cmInstallCommand.cxx
  49. 1 1
      Source/cmInstallDirectoryGenerator.cxx
  50. 1 1
      Source/cmInstallScriptHandler.cxx
  51. 1 1
      Source/cmInstallTargetGenerator.cxx
  52. 7 7
      Source/cmInstrumentation.cxx
  53. 3 3
      Source/cmInstrumentationCommand.cxx
  54. 1 1
      Source/cmInstrumentationQuery.cxx
  55. 2 2
      Source/cmJSONHelpers.cxx
  56. 2 2
      Source/cmJSONState.cxx
  57. 4 4
      Source/cmLinkLineComputer.cxx
  58. 5 5
      Source/cmList.cxx
  59. 11 11
      Source/cmLocalGenerator.cxx
  60. 1 1
      Source/cmLocalNinjaGenerator.cxx
  61. 2 2
      Source/cmLocalUnixMakefileGenerator3.cxx
  62. 2 2
      Source/cmMakefileTargetGenerator.cxx
  63. 6 6
      Source/cmNinjaNormalTargetGenerator.cxx
  64. 8 5
      Source/cmNinjaTargetGenerator.cxx
  65. 1 1
      Source/cmNinjaUtilityTargetGenerator.cxx
  66. 3 3
      Source/cmPkgConfigResolver.cxx
  67. 1 1
      Source/cmPolicies.cxx
  68. 2 2
      Source/cmQtAutoGenGlobalInitializer.cxx
  69. 12 10
      Source/cmQtAutoGenInitializer.cxx
  70. 3 3
      Source/cmQtAutoMocUic.cxx
  71. 4 3
      Source/cmQtAutoRcc.cxx
  72. 1 1
      Source/cmRST.cxx
  73. 2 1
      Source/cmReturnCommand.cxx
  74. 2 2
      Source/cmRulePlaceholderExpander.cxx
  75. 1 1
      Source/cmSetPropertyCommand.cxx
  76. 1 1
      Source/cmStringCommand.cxx
  77. 1 1
      Source/cmSystemTools.cxx
  78. 5 7
      Source/cmTarget.cxx
  79. 1 1
      Source/cmTargetLinkLibrariesCommand.cxx
  80. 3 3
      Source/cmTargetSourcesCommand.cxx
  81. 1 1
      Source/cmTryRunCommand.cxx
  82. 1 1
      Source/cmVisualStudio10TargetGenerator.cxx
  83. 42 29
      Source/cmake.cxx
  84. 1 1
      Tests/CMakeLib/testStringAlgorithms.cxx
  85. 312 0
      Utilities/ast-grep/rule-tests/__snapshots__/cmstrcat-adjacent-literals-snapshot.yml
  86. 342 0
      Utilities/ast-grep/rule-tests/__snapshots__/cmstrcat-to-char-literal-snapshot.yml
  87. 39 0
      Utilities/ast-grep/rule-tests/cmstrcat-adjacent-literals-test.yml
  88. 24 0
      Utilities/ast-grep/rule-tests/cmstrcat-to-char-literal-test.yml
  89. 19 0
      Utilities/ast-grep/rules/cmstrcat-adjacent-literals.yml
  90. 36 0
      Utilities/ast-grep/rules/cmstrcat-to-char-literal.yaml
  91. 23 0
      Utilities/ast-grep/utils/cmstrcat-arg.yml
  92. 5 0
      Utilities/ast-grep/utils/cmstrcat-call.yml
  93. 13 0
      Utilities/ast-grep/utils/string-literal.yml
  94. 6 0
      sgconfig.yml

+ 1 - 1
Source/CPack/cmCPackArchiveGenerator.cxx

@@ -55,7 +55,7 @@ private:
         : DeduplicateStatus::Skip;
     }
 
-    this->Files[path] = cmStrCat(localTopLevel, "/", path);
+    this->Files[path] = cmStrCat(localTopLevel, '/', path);
     return DeduplicateStatus::Add;
   }
 

+ 1 - 1
Source/CPack/cmCPackBundleGenerator.cxx

@@ -231,7 +231,7 @@ int cmCPackBundleGenerator::SignBundle(std::string const& src_dir)
     // sign app bundle
     auto temp_codesign_cmd =
       cmStrCat(this->GetOption("CPACK_COMMAND_CODESIGN"), ' ', sign_parameter,
-               " -s \"", cpack_apple_cert_app, "\"");
+               " -s \"", cpack_apple_cert_app, '"');
     if (this->GetOption("CPACK_BUNDLE_APPLE_ENTITLEMENTS")) {
       temp_codesign_cmd +=
         cmStrCat(" --entitlements ",

+ 5 - 5
Source/CPack/cmCPackGenerator.cxx

@@ -100,18 +100,18 @@ int cmCPackGenerator::PrepareNames()
   std::string pkgFileName =
     cmStrCat(pkgBaseFileName, this->GetOutputExtension());
   // Determine path to the package.
-  std::string pkgFilePath = cmStrCat(pkgDirectory, "/", pkgFileName);
+  std::string pkgFilePath = cmStrCat(pkgDirectory, '/', pkgFileName);
   // Determine top-level directory for packaging.
   std::string topDirectory = cmStrCat(pkgDirectory, "/_CPack_Packages/");
   {
     cmValue toplevelTag = this->GetOption("CPACK_TOPLEVEL_TAG");
     if (toplevelTag) {
-      topDirectory += cmStrCat(toplevelTag, "/");
+      topDirectory += cmStrCat(toplevelTag, '/');
     }
   }
   topDirectory += *this->GetOption("CPACK_GENERATOR");
   // Determine temporary packaging-directory.
-  std::string tmpDirectory = cmStrCat(topDirectory, "/", pkgBaseFileName);
+  std::string tmpDirectory = cmStrCat(topDirectory, '/', pkgBaseFileName);
   // Determine path to temporary package file.
   std::string tmpPkgFilePath = topDirectory + "/" + pkgFileName;
 
@@ -982,7 +982,7 @@ bool cmCPackGenerator::GenerateChecksumFile(cmCryptoHash& crypto,
                                             cm::string_view filename) const
 {
   std::string packageFileName =
-    cmStrCat(this->GetOption("CPACK_OUTPUT_FILE_PREFIX"), "/", filename);
+    cmStrCat(this->GetOption("CPACK_OUTPUT_FILE_PREFIX"), '/', filename);
   std::string hashFile = cmStrCat(
     packageFileName, "." + cmSystemTools::LowerCase(crypto.GetHashAlgoName()));
   cmsys::ofstream outF(hashFile.c_str());
@@ -1001,7 +1001,7 @@ bool cmCPackGenerator::CopyPackageFile(std::string const& srcFilePath,
                                        cm::string_view filename) const
 {
   std::string destFilePath =
-    cmStrCat(this->GetOption("CPACK_OUTPUT_FILE_PREFIX"), "/", filename);
+    cmStrCat(this->GetOption("CPACK_OUTPUT_FILE_PREFIX"), '/', filename);
   cmCPackLogger(cmCPackLog::LOG_DEBUG,
                 "Copy final package(s): "
                   << (!srcFilePath.empty() ? srcFilePath : "(NULL)") << " to "

+ 9 - 9
Source/CPack/cmCPackNSISGenerator.cxx

@@ -132,11 +132,11 @@ int cmCPackNSISGenerator::PackageFiles()
     std::string installerIconCode;
     if (cmValue v = this->GetOptionIfSet("CPACK_NSIS_MUI_ICON")) {
       std::string iconFile = cmSystemTools::ConvertToWindowsOutputPath(*v);
-      installerIconCode += cmStrCat("!define MUI_ICON ", iconFile, "\n");
+      installerIconCode += cmStrCat("!define MUI_ICON ", iconFile, '\n');
     }
     if (cmValue v = this->GetOptionIfSet("CPACK_NSIS_MUI_UNIICON")) {
       std::string iconFile = cmSystemTools::ConvertToWindowsOutputPath(*v);
-      installerIconCode += cmStrCat("!define MUI_UNICON ", iconFile, "\n");
+      installerIconCode += cmStrCat("!define MUI_UNICON ", iconFile, '\n');
     }
     this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_ICON_CODE",
                             installerIconCode.c_str());
@@ -151,7 +151,7 @@ int cmCPackNSISGenerator::PackageFiles()
     installerHeaderImage =
       cmSystemTools::ConvertToWindowsOutputPath(installerHeaderImage);
     std::string installerIconCode =
-      cmStrCat("!define MUI_HEADERIMAGE_BITMAP ", installerHeaderImage, "\n");
+      cmStrCat("!define MUI_HEADERIMAGE_BITMAP ", installerHeaderImage, '\n');
     this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_ICON_CODE",
                             installerIconCode);
   }
@@ -160,7 +160,7 @@ int cmCPackNSISGenerator::PackageFiles()
         this->GetOptionIfSet("CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP")) {
     std::string bitmapFile = cmSystemTools::ConvertToWindowsOutputPath(*v);
     std::string installerBitmapCode =
-      cmStrCat("!define MUI_WELCOMEFINISHPAGE_BITMAP ", bitmapFile, "\n");
+      cmStrCat("!define MUI_WELCOMEFINISHPAGE_BITMAP ", bitmapFile, '\n');
     this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_WELCOMEFINISH_CODE",
                             installerBitmapCode);
   }
@@ -169,7 +169,7 @@ int cmCPackNSISGenerator::PackageFiles()
         this->GetOptionIfSet("CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP")) {
     std::string bitmapFile = cmSystemTools::ConvertToWindowsOutputPath(*v);
     std::string installerBitmapCode =
-      cmStrCat("!define MUI_UNWELCOMEFINISHPAGE_BITMAP ", bitmapFile, "\n");
+      cmStrCat("!define MUI_UNWELCOMEFINISHPAGE_BITMAP ", bitmapFile, '\n');
     this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_UNWELCOMEFINISH_CODE",
                             installerBitmapCode);
   }
@@ -184,7 +184,7 @@ int cmCPackNSISGenerator::PackageFiles()
 
   if (cmValue v = this->GetOptionIfSet("CPACK_NSIS_WELCOME_TITLE")) {
     std::string welcomeTitleCode =
-      cmStrCat("!define MUI_WELCOMEPAGE_TITLE \"", *v, "\"");
+      cmStrCat("!define MUI_WELCOMEPAGE_TITLE \"", *v, '"');
     this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_WELCOME_TITLE_CODE",
                             welcomeTitleCode);
   }
@@ -196,7 +196,7 @@ int cmCPackNSISGenerator::PackageFiles()
 
   if (cmValue v = this->GetOptionIfSet("CPACK_NSIS_FINISH_TITLE")) {
     std::string finishTitleCode =
-      cmStrCat("!define MUI_FINISHPAGE_TITLE \"", *v, "\"");
+      cmStrCat("!define MUI_FINISHPAGE_TITLE \"", *v, '"');
     this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_FINISH_TITLE_CODE",
                             finishTitleCode);
   }
@@ -240,7 +240,7 @@ int cmCPackNSISGenerator::PackageFiles()
     cmValue v = this->GetOption("CPACK_RESOURCE_FILE_LICENSE");
     std::string licenseFile = cmSystemTools::ConvertToWindowsOutputPath(*v);
     std::string licenseCode =
-      cmStrCat("!insertmacro MUI_PAGE_LICENSE ", licenseFile, "\n");
+      cmStrCat("!insertmacro MUI_PAGE_LICENSE ", licenseFile, '\n');
     this->SetOptionIfNotSet("CPACK_NSIS_LICENSE_PAGE", licenseCode);
   }
 
@@ -388,7 +388,7 @@ int cmCPackNSISGenerator::PackageFiles()
     cmStrCat('"', this->GetOption("CPACK_INSTALLER_PROGRAM"), "\" ",
              nsisPreArguments, " \"", nsisFileName, '"');
   if (!nsisPostArguments.empty()) {
-    nsisCmd = cmStrCat(nsisCmd, " ", nsisPostArguments);
+    nsisCmd = cmStrCat(nsisCmd, ' ', nsisPostArguments);
   }
   cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << nsisCmd << std::endl);
   std::string output;

+ 2 - 2
Source/CPack/cmCPackProductBuildGenerator.cxx

@@ -250,10 +250,10 @@ bool cmCPackProductBuildGenerator::GenerateComponentPackage(
          << "\""
             " --install-location \"/\""
          << (identityName.empty() ? std::string{}
-                                  : cmStrCat(" --sign \"", identityName, "\""))
+                                  : cmStrCat(" --sign \"", identityName, '"'))
          << (keychainPath.empty()
                ? std::string{}
-               : cmStrCat(" --keychain \"", keychainPath, "\""))
+               : cmStrCat(" --keychain \"", keychainPath, '"'))
          << " \"" << packageFile << '"';
 
   if (component && !component->Plist.empty()) {

+ 1 - 1
Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx

@@ -27,7 +27,7 @@ cmsys::Status TryToRemoveBinaryDirectoryOnce(std::string const& directoryPath)
       continue;
     }
 
-    std::string fullPath = cmStrCat(directoryPath, "/", path);
+    std::string fullPath = cmStrCat(directoryPath, '/', path);
 
     bool isDirectory = cmSystemTools::FileIsDirectory(fullPath) &&
       !cmSystemTools::FileIsSymlink(fullPath);

+ 1 - 1
Source/CTest/cmCTestSubmitHandler.cxx

@@ -219,7 +219,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(
       std::string local_file = file;
       bool initialize_cdash_buildid = false;
       if (!cmSystemTools::FileExists(local_file)) {
-        local_file = cmStrCat(localprefix, "/", file);
+        local_file = cmStrCat(localprefix, '/', file);
         // If this file exists within the local Testing directory we assume
         // that it will be associated with the current build in CDash.
         initialize_cdash_buildid = true;

+ 1 - 1
Source/CTest/cmCTestTestHandler.cxx

@@ -617,7 +617,7 @@ void cmCTestTestHandler::LogFailedTests(std::vector<std::string> const& failed,
           testColor = cmCTest::Color::YELLOW;
         }
         std::string ft_name_and_status =
-          cmStrCat(ft.Name, " (", this->GetTestStatus(ft), ")");
+          cmStrCat(ft.Name, " (", this->GetTestStatus(ft), ')');
         std::string labels;
         cmCTestTestProperties const& p = *ft.Properties;
         if (!p.Labels.empty()) {

+ 2 - 2
Source/CTest/cmParseCoberturaCoverage.cxx

@@ -77,7 +77,7 @@ protected:
             // Check if this is a path that is relative to our source or
             // binary directories.
             for (std::string const& filePath : this->FilePaths) {
-              finalpath = cmStrCat(filePath, "/", filename);
+              finalpath = cmStrCat(filePath, '/', filename);
               if (cmSystemTools::FileExists(finalpath)) {
                 this->CurFileName = finalpath;
                 break;
@@ -88,7 +88,7 @@ protected:
           cmsys::ifstream fin(this->CurFileName.c_str());
           if (this->CurFileName.empty() || !fin) {
             this->CurFileName =
-              cmStrCat(this->Coverage.BinaryDir, "/", atts[tagCount + 1]);
+              cmStrCat(this->Coverage.BinaryDir, '/', atts[tagCount + 1]);
             fin.open(this->CurFileName.c_str());
             if (!fin) {
               cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,

+ 4 - 3
Source/CursesDialog/cmCursesMainForm.cxx

@@ -848,9 +848,10 @@ void cmCursesMainForm::HandleInput()
             curField, "HELPSTRING");
         }
         if (helpString) {
-          this->HelpMessage[1] =
-            cmStrCat("Current option is: ", curField, '\n',
-                     "Help string for this option is: ", *helpString, '\n');
+          this->HelpMessage[1] = cmStrCat("Current option is: ", curField,
+                                          "\n"
+                                          "Help string for this option is: ",
+                                          *helpString, '\n');
         } else {
           this->HelpMessage[1] = "";
         }

+ 1 - 1
Source/cmAddLibraryCommand.cxx

@@ -237,7 +237,7 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
             "ADD_LIBRARY called with ",
             (type == cmStateEnums::SHARED_LIBRARY ? "SHARED" : "MODULE"),
             " option but the target platform does not support dynamic "
-            "linking. ",
+            "linking. "
             "Building a STATIC library instead. This may lead to problems."));
         CM_FALLTHROUGH;
       case cmPolicies::OLD:

+ 3 - 2
Source/cmAddSubDirectoryCommand.cxx

@@ -77,8 +77,9 @@ bool cmAddSubDirectoryCommand(std::vector<std::string> const& args,
     if (!cmSystemTools::IsSubDirectory(srcPath,
                                        mf.GetCurrentSourceDirectory())) {
       status.SetError(
-        cmStrCat("not given a binary directory but the given source ",
-                 "directory \"", srcPath, "\" is not a subdirectory of \"",
+        cmStrCat("not given a binary directory but the given source "
+                 "directory \"",
+                 srcPath, "\" is not a subdirectory of \"",
                  mf.GetCurrentSourceDirectory(),
                  "\".  When specifying an "
                  "out-of-tree source a binary directory must be explicitly "

+ 1 - 1
Source/cmAddTestCommand.cxx

@@ -152,7 +152,7 @@ bool cmAddTestCommandHandleNameMode(std::vector<std::string> const& args,
       }
       doing = DoingNone;
     } else {
-      status.SetError(cmStrCat(" given unknown argument:\n  ", args[i], "\n"));
+      status.SetError(cmStrCat(" given unknown argument:\n  ", args[i], '\n'));
       return false;
     }
   }

+ 1 - 1
Source/cmBuildCommand.cxx

@@ -60,7 +60,7 @@ bool MainSignature(std::vector<std::string> const& args,
       doing = DoingNone;
       parallel = args[i];
     } else {
-      status.SetError(cmStrCat("unknown argument \"", args[i], "\""));
+      status.SetError(cmStrCat("unknown argument \"", args[i], '"'));
       return false;
     }
   }

+ 4 - 4
Source/cmCMakeLanguageCommand.cxx

@@ -220,7 +220,7 @@ bool cmCMakeLanguageCommandEVAL(std::vector<cmListFileArgument> const& args,
   std::string const code =
     cmJoin(cmMakeRange(expandedArgs.begin() + 2, expandedArgs.end()), " ");
   return makefile.ReadListFileAsString(
-    code, cmStrCat(context.FilePath, ":", context.Line, ":EVAL"));
+    code, cmStrCat(context.FilePath, ':', context.Line, ":EVAL"));
 }
 
 bool cmCMakeLanguageCommandSET_DEPENDENCY_PROVIDER(
@@ -252,7 +252,7 @@ bool cmCMakeLanguageCommandSET_DEPENDENCY_PROVIDER(
 
   if (!unparsed.empty()) {
     return FatalError(
-      status, cmStrCat("Unrecognized keyword: \"", unparsed.front(), "\""));
+      status, cmStrCat("Unrecognized keyword: \"", unparsed.front(), '"'));
   }
 
   // We store the command that FetchContent_MakeAvailable() can call in a
@@ -296,7 +296,7 @@ bool cmCMakeLanguageCommandSET_DEPENDENCY_PROVIDER(
     } else {
       return FatalError(
         status,
-        cmStrCat("Unknown dependency provider method \"", method, "\""));
+        cmStrCat("Unknown dependency provider method \"", method, '"'));
     }
   }
 
@@ -467,7 +467,7 @@ bool cmCMakeLanguageCommand(std::vector<cmListFileArgument> const& args,
         if (!defer.Directory) {
           return FatalError(status,
                             cmStrCat("DEFER DIRECTORY:\n  "_s, dir,
-                                     "\nis not known.  "_s,
+                                     "\nis not known.  "
                                      "It may not have been processed yet."_s));
         }
       } else if (expArgs[expArg] == "ID"_s) {

+ 3 - 3
Source/cmCMakePathCommand.cxx

@@ -174,7 +174,7 @@ bool HandleGetCommand(std::vector<std::string> const& args,
 
   if (actions.find(action) == actions.end()) {
     status.SetError(
-      cmStrCat("GET called with an unknown action: ", action, "."));
+      cmStrCat("GET called with an unknown action: ", action, '.'));
     return false;
   }
 
@@ -609,7 +609,7 @@ bool HandleConvertCommand(std::vector<std::string> const& args,
 
   if (action != cmakePath && action != nativePath) {
     status.SetError(
-      cmStrCat("CONVERT called with an unknown action: ", action, "."));
+      cmStrCat("CONVERT called with an unknown action: ", action, '.'));
     return false;
   }
 
@@ -679,7 +679,7 @@ bool HandleCompareCommand(std::vector<std::string> const& args,
   auto const op = operators.find(args[2]);
   if (op == operators.end()) {
     status.SetError(cmStrCat(
-      "COMPARE called with an unknown comparison operator: ", args[2], "."));
+      "COMPARE called with an unknown comparison operator: ", args[2], '.'));
     return false;
   }
 

+ 14 - 14
Source/cmCMakePkgConfigCommand.cxx

@@ -508,7 +508,7 @@ cm::optional<cmPkgConfigResult> ReadPackage(std::string const& package,
   cmsys::ifstream ifs(path.string().c_str(), std::ios::binary);
 
   if (!ifs) {
-    warn_or_error(cmStrCat("Could not open file '", path.string(), "'"),
+    warn_or_error(cmStrCat("Could not open file '", path.string(), '\''),
                   imEnv);
     return result;
   }
@@ -518,7 +518,7 @@ cm::optional<cmPkgConfigResult> ReadPackage(std::string const& package,
 
   // Shouldn't have hit eof on previous read, should hit eof now
   if (ifs.fail() || ifs.eof() || ifs.get() != EOF) {
-    warn_or_error(cmStrCat("Error while reading file '", path.string(), "'"),
+    warn_or_error(cmStrCat("Error while reading file '", path.string(), '\''),
                   imEnv);
     return result;
   }
@@ -530,7 +530,7 @@ cm::optional<cmPkgConfigResult> ReadPackage(std::string const& package,
 
   if (imEnv.strictness != StrictnessType::STRICTNESS_BEST_EFFORT &&
       err != PCE_OK) {
-    warn_or_error(cmStrCat("Parsing failed for file '", path.string(), "'"),
+    warn_or_error(cmStrCat("Parsing failed for file '", path.string(), '\''),
                   imEnv);
     return result;
   }
@@ -544,8 +544,8 @@ cm::optional<cmPkgConfigResult> ReadPackage(std::string const& package,
   }
 
   if (!result) {
-    warn_or_error(cmStrCat("Resolution failed for file '", path.string(), "'"),
-                  imEnv);
+    warn_or_error(
+      cmStrCat("Resolution failed for file '", path.string(), '\''), imEnv);
   }
 
   return result;
@@ -559,7 +559,7 @@ cm::optional<cmPkgConfigResult> ImportPackage(
 
   if (!result) {
     if (!imEnv.err) {
-      warn_or_error(cmStrCat("Could not find pkg-config: '", package, "'"),
+      warn_or_error(cmStrCat("Could not find pkg-config: '", package, '\''),
                     imEnv);
     }
     return result;
@@ -575,7 +575,7 @@ cm::optional<cmPkgConfigResult> ImportPackage(
     if (ver != result->Version()) {
       warn_or_error(
         cmStrCat("Package '", package, "' version '", result->Version(),
-                 "' does not meet exact version requirement '", ver, "'"),
+                 "' does not meet exact version requirement '", ver, '\''),
         imEnv);
       return {};
     }
@@ -585,7 +585,7 @@ cm::optional<cmPkgConfigResult> ImportPackage(
     if (!cmPkgConfigResolver::CheckVersion(rv, result->Version())) {
       warn_or_error(
         cmStrCat("Package '", package, "' version '", result->Version(),
-                 "' does not meet version requirement '", *version, "'"),
+                 "' does not meet version requirement '", *version, '\''),
         imEnv);
       return {};
     }
@@ -609,9 +609,9 @@ cm::optional<cmPkgConfigResult> ImportPackage(
 
   if (!result) {
     if (!imEnv.err) {
-      std::string req_str = cmStrCat("'", reqs.begin()->parent, "'");
+      std::string req_str = cmStrCat('\'', reqs.begin()->parent, '\'');
       for (auto it = reqs.begin() + 1; it != reqs.end(); ++it) {
-        req_str = cmStrCat(req_str, ", '", it->parent, "'");
+        req_str = cmStrCat(req_str, ", '", it->parent, '\'');
       }
       warn_or_error(cmStrCat("Could not find pkg-config: '", package,
                              "' required by: ", req_str),
@@ -626,7 +626,7 @@ cm::optional<cmPkgConfigResult> ImportPackage(
     if (!cmPkgConfigResolver::CheckVersion(req.ver, ver)) {
       warn_or_error(cmStrCat("Package '", package, "' version '", ver,
                              "' does not meet version requirement '",
-                             req.ver.string(), "' ", "of '", req.parent, "'"),
+                             req.ver.string(), "' of '", req.parent, '\''),
                     imEnv);
       return {};
     }
@@ -856,7 +856,7 @@ bool CheckPackageDependencies(
       if (!cmPkgConfigResolver::CheckVersion(dep.VerReq, *ver)) {
         warn_or_error(cmStrCat("Package '", dep.Name, "' version '", *ver,
                                "' does not meet version requirement '",
-                               dep.VerReq.string(), "' ", "of '", name, "'"),
+                               dep.VerReq.string(), "' of '", name, '\''),
                       imEnv);
         return false;
       }
@@ -869,7 +869,7 @@ bool CheckPackageDependencies(
       if (!cmPkgConfigResolver::CheckVersion(dep.VerReq, ver)) {
         warn_or_error(cmStrCat("Package '", dep.Name, "' version '", ver,
                                "' does not meet version requirement '",
-                               dep.VerReq.string(), "' ", "of '", name, "'"),
+                               dep.VerReq.string(), "' of '", name, '\''),
                       imEnv);
         return false;
       }
@@ -920,7 +920,7 @@ std::pair<bool, bool> PopulatePCTarget(PopulateArguments& args,
                           provider_str.substr(assignment + 1));
       } else {
         imEnv.status.SetError(cmStrCat(
-          "No '=' found in BIND_PC_REQUIRES argument '", provider_str, "'"));
+          "No '=' found in BIND_PC_REQUIRES argument '", provider_str, '\''));
         cmSystemTools::SetFatalErrorOccurred();
         return { false, false };
       }

+ 2 - 2
Source/cmCMakePolicyCommand.cxx

@@ -56,7 +56,7 @@ bool cmCMakePolicyCommand(std::vector<std::string> const& args,
     return HandleGetWarningMode(args, status);
   }
 
-  status.SetError(cmStrCat("given unknown first argument \"", args[0], "\""));
+  status.SetError(cmStrCat("given unknown first argument \"", args[0], '"'));
   return false;
 }
 
@@ -77,7 +77,7 @@ bool HandleSetMode(std::vector<std::string> const& args,
     policyStatus = cmPolicies::NEW;
   } else {
     status.SetError(
-      cmStrCat("SET given unrecognized policy status \"", args[2], "\""));
+      cmStrCat("SET given unrecognized policy status \"", args[2], '"'));
     return false;
   }
 

+ 12 - 12
Source/cmCMakePresetsErrors.cxx

@@ -40,8 +40,8 @@ std::string getPresetName(cmJSONState* state)
 std::string getVariableName(cmJSONState* state)
 {
   std::string var = state->key_after("cacheVariables");
-  std::string errMsg = cmStrCat("variable \"", var, "\"");
-  errMsg = cmStrCat(errMsg, " for preset \"", getPresetName(state), "\"");
+  std::string errMsg = cmStrCat("variable \"", var, '"');
+  errMsg = cmStrCat(errMsg, " for preset \"", getPresetName(state), '"');
   return errMsg;
 }
 
@@ -82,7 +82,7 @@ void INVALID_PRESET(Json::Value const* value, cmJSONState* state)
 
 void INVALID_PRESET_NAMED(std::string const& presetName, cmJSONState* state)
 {
-  state->AddError(cmStrCat("Invalid preset: \"", presetName, "\""));
+  state->AddError(cmStrCat("Invalid preset: \"", presetName, '"'));
 }
 
 void INVALID_VARIABLE(Json::Value const* value, cmJSONState* state)
@@ -93,7 +93,7 @@ void INVALID_VARIABLE(Json::Value const* value, cmJSONState* state)
 
 void DUPLICATE_PRESETS(std::string const& presetName, cmJSONState* state)
 {
-  state->AddError(cmStrCat("Duplicate preset: \"", presetName, "\""));
+  state->AddError(cmStrCat("Duplicate preset: \"", presetName, '"'));
 }
 
 void CYCLIC_PRESET_INHERITANCE(std::string const& presetName,
@@ -101,7 +101,7 @@ void CYCLIC_PRESET_INHERITANCE(std::string const& presetName,
 
 {
   state->AddError(
-    cmStrCat("Cyclic preset inheritance for preset \"", presetName, "\""));
+    cmStrCat("Cyclic preset inheritance for preset \"", presetName, '"'));
 }
 
 void INHERITED_PRESET_UNREACHABLE_FROM_FILE(std::string const& presetName,
@@ -120,7 +120,7 @@ void CONFIGURE_PRESET_UNREACHABLE_FROM_FILE(std::string const& presetName,
 
 void INVALID_MACRO_EXPANSION(std::string const& presetName, cmJSONState* state)
 {
-  state->AddError(cmStrCat("Invalid macro expansion in \"", presetName, "\""));
+  state->AddError(cmStrCat("Invalid macro expansion in \"", presetName, '"'));
 }
 
 void BUILD_TEST_PRESETS_UNSUPPORTED(Json::Value const*, cmJSONState* state)
@@ -155,7 +155,7 @@ void INVALID_CONFIGURE_PRESET(std::string const& presetName,
                               cmJSONState* state)
 {
   state->AddError(
-    cmStrCat(R"(Invalid "configurePreset": ")", presetName, "\""));
+    cmStrCat(R"(Invalid "configurePreset": ")", presetName, '"'));
 }
 
 void INSTALL_PREFIX_UNSUPPORTED(Json::Value const* value, cmJSONState* state)
@@ -197,13 +197,13 @@ void TEST_OUTPUT_TRUNCATION_UNSUPPORTED(cmJSONState* state)
 void INVALID_WORKFLOW_STEPS(std::string const& workflowStep,
                             cmJSONState* state)
 {
-  state->AddError(cmStrCat("Invalid workflow step \"", workflowStep, "\""));
+  state->AddError(cmStrCat("Invalid workflow step \"", workflowStep, '"'));
 }
 
 void NO_WORKFLOW_STEPS(std::string const& presetName, cmJSONState* state)
 {
   state->AddError(
-    cmStrCat("No workflow steps specified for \"", presetName, "\""));
+    cmStrCat("No workflow steps specified for \"", presetName, '"'));
 }
 
 void FIRST_WORKFLOW_STEP_NOT_CONFIGURE(std::string const& stepName,
@@ -273,7 +273,7 @@ void INVALID_PRESET_NAME(Json::Value const* value, cmJSONState* state)
 void INVALID_CONDITION(Json::Value const* value, cmJSONState* state)
 {
   state->AddErrorAtValue(
-    cmStrCat("Invalid condition for preset \"", getPresetName(state), "\""),
+    cmStrCat("Invalid condition for preset \"", getPresetName(state), '"'),
     value);
 }
 
@@ -282,7 +282,7 @@ JsonErrors::ErrorGenerator INVALID_CONDITION_OBJECT(
 {
   return JsonErrors::INVALID_NAMED_OBJECT(
     [](Json::Value const*, cmJSONState* state) -> std::string {
-      return cmStrCat(" condition for preset \"", getPresetName(state), "\"");
+      return cmStrCat(" condition for preset \"", getPresetName(state), '"');
     })(errorType, extraFields);
 }
 
@@ -316,7 +316,7 @@ void PRESET_MISSING_FIELD(std::string const& presetName,
                           std::string const& missingField, cmJSONState* state)
 {
   state->AddError(cmStrCat("Preset \"", presetName, "\" missing field \"",
-                           missingField, "\""));
+                           missingField, '"'));
 }
 
 void SCHEMA_UNSUPPORTED(cmJSONState* state)

+ 4 - 3
Source/cmComputeLinkDepends.cxx

@@ -1179,8 +1179,8 @@ void cmComputeLinkDepends::AddLinkEntries(
               cmStrCat("Impossible to link target '", this->Target->GetName(),
                        "' because the link item '", entry.Item.Value,
                        "', specified with the group feature '", currentFeature,
-                       '\'', ", has already occurred with the feature '",
-                       groupFeature, '\'', ", which is not allowed."),
+                       "', has already occurred with the feature '",
+                       groupFeature, "', which is not allowed."),
               this->Target->GetBacktrace());
             continue;
           }
@@ -1203,7 +1203,8 @@ void cmComputeLinkDepends::AddLinkEntries(
             cmStrCat("Impossible to link target '", this->Target->GetName(),
                      "' because the link item '", entry.Item.Value,
                      "' is specified with the features '", itemFeature,
-                     "' and '", entry.Feature, "'",
+                     "' and '", entry.Feature,
+                     "'"
                      ", and both have an 'OVERRIDE' attribute that overrides "
                      "the other. Such cycles are not allowed."),
             this->Target->GetBacktrace());

+ 1 - 1
Source/cmComputeLinkInformation.cxx

@@ -2258,7 +2258,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
               cmSystemTools::IsSubDirectory(d, topBinaryDir)) {
             d = cmSystemTools::RelativePath(targetOutputDir, d);
             if (!d.empty()) {
-              d = cmStrCat(originToken, "/", d);
+              d = cmStrCat(originToken, '/', d);
             } else {
               d = originToken;
             }

+ 3 - 3
Source/cmCoreTryCompile.cxx

@@ -1293,7 +1293,7 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
           "to destination specified by COPY_FILE:\n"
           "  '", copyFile, "'\n"
           "because:\n"
-          "  ", err, "\n",
+          "  ", err, '\n',
           this->FindErrorMessage);
         /* clang-format on */
         if (!arguments.CopyFileError) {
@@ -1412,7 +1412,7 @@ void cmCoreTryCompile::FindOutputFile(std::string const& targetName)
   if (!cmSystemTools::FileExists(command)) {
     std::ostringstream emsg;
     emsg << "Unable to find the recorded try_compile output location:\n";
-    emsg << cmStrCat("  ", command, "\n");
+    emsg << cmStrCat("  ", command, '\n');
     this->FindErrorMessage = emsg.str();
     return;
   }
@@ -1423,7 +1423,7 @@ void cmCoreTryCompile::FindOutputFile(std::string const& targetName)
   if (!cmSystemTools::FileExists(outputFileLocation)) {
     std::ostringstream emsg;
     emsg << "Recorded try_compile output location doesn't exist:\n";
-    emsg << cmStrCat("  ", outputFileLocation, "\n");
+    emsg << cmStrCat("  ", outputFileLocation, '\n');
     this->FindErrorMessage = emsg.str();
     return;
   }

+ 1 - 1
Source/cmCxxModuleMapper.cxx

@@ -275,7 +275,7 @@ bool CxxModuleUsage::AddReference(std::string const& logical,
                                   ref.Path, "' via ", method_name(ref.Method),
                                   "; "
                                   "Location B: '",
-                                  loc, "' via ", method_name(method), "."));
+                                  loc, "' via ", method_name(method), '.'));
     return false;
   }
 

+ 1 - 1
Source/cmDefinePropertyCommand.cxx

@@ -89,7 +89,7 @@ bool cmDefinePropertyCommand(std::vector<std::string> const& args,
     if (!cmHasSuffix(initializeFromVariable, PropertyName)) {
       status.SetError(cmStrCat("Variable name \"", initializeFromVariable,
                                "\" does not end with property name \"",
-                               PropertyName, "\""));
+                               PropertyName, '"'));
       return false;
     }
     if (PropertyName.find('_') == std::string::npos) {

+ 2 - 1
Source/cmExperimental.cxx

@@ -125,7 +125,8 @@ bool cmExperimental::HasSupportEnabled(cmMakefile const& mf, Feature f)
         mf.IssueMessage(
           MessageType::AUTHOR_WARNING,
           cmStrCat(
-            data.Variable, " is set to incorrect value\n  ", value, '\n',
+            data.Variable, " is set to incorrect value\n  ", value,
+            "\n"
             "See 'Help/dev/experimental.rst' in the source tree of this "
             "version of CMake for documentation of the experimental feature "
             "and the corresponding activation value.  This project's code "

+ 3 - 2
Source/cmExportCommand.cxx

@@ -184,7 +184,7 @@ bool cmExportCommand(std::vector<std::string> const& args,
         } else {
           status.SetError(
             cmStrCat("Invalid enable setting for package dependency: \"",
-                     packageDependencyArguments.Enabled, "\""));
+                     packageDependencyArguments.Enabled, '"'));
           return false;
         }
       }
@@ -407,7 +407,8 @@ bool cmExportCommand(std::vector<std::string> const& args,
       case cmPolicies::WARN:
         mf.IssueMessage(
           MessageType::AUTHOR_WARNING,
-          cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0103), '\n',
+          cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0103),
+                   "\n"
                    "export() command already specified for the file\n  ",
                    arguments.Filename, "\nDid you miss 'APPEND' keyword?"));
         CM_FALLTHROUGH;

+ 4 - 4
Source/cmExtraCodeBlocksGenerator.cxx

@@ -183,19 +183,19 @@ void Tree::BuildUnitImpl(cmXMLWriter& xml,
 {
   for (std::string const& f : this->files) {
     xml.StartElement("Unit");
-    xml.Attribute("filename", cmStrCat(fsPath, this->path, "/", f));
+    xml.Attribute("filename", cmStrCat(fsPath, this->path, '/', f));
 
     xml.StartElement("Option");
     xml.Attribute(
       "virtualFolder",
-      cmStrCat("CMake Files\\", virtualFolderPath, this->path, "\\"));
+      cmStrCat("CMake Files\\", virtualFolderPath, this->path, '\\'));
     xml.EndElement();
 
     xml.EndElement();
   }
   for (Tree const& folder : this->folders) {
-    folder.BuildUnitImpl(xml, cmStrCat(virtualFolderPath, this->path, "\\"),
-                         cmStrCat(fsPath, this->path, "/"));
+    folder.BuildUnitImpl(xml, cmStrCat(virtualFolderPath, this->path, '\\'),
+                         cmStrCat(fsPath, this->path, '/'));
   }
 }
 

+ 2 - 2
Source/cmExtraCodeLiteGenerator.cxx

@@ -123,7 +123,7 @@ std::vector<std::string> cmExtraCodeLiteGenerator::CreateProjectsByTarget(
       cmStateEnums::TargetType type = lt->GetType();
       std::string const& outputDir = lg->GetCurrentBinaryDirectory();
       std::string targetName = lt->GetName();
-      std::string filename = cmStrCat(outputDir, "/", targetName, ".project");
+      std::string filename = cmStrCat(outputDir, '/', targetName, ".project");
       retval.push_back(targetName);
       // Make the project file relative to the workspace
       std::string relafilename =
@@ -163,7 +163,7 @@ std::vector<std::string> cmExtraCodeLiteGenerator::CreateProjectsByProjectMaps(
     std::string const& outputDir = it.second[0]->GetCurrentBinaryDirectory();
     std::string projectName = it.second[0]->GetProjectName();
     retval.push_back(projectName);
-    std::string filename = cmStrCat(outputDir, "/", projectName, ".project");
+    std::string filename = cmStrCat(outputDir, '/', projectName, ".project");
 
     // Make the project file relative to the workspace
     filename = cmSystemTools::RelativePath(this->WorkspacePath, filename);

+ 1 - 1
Source/cmExtraSublimeTextGenerator.cxx

@@ -270,7 +270,7 @@ void cmExtraSublimeTextGenerator::AppendTarget(
         R"((^|[ ])-[DIOUWfgs][^= ]+(=\"[^"]+\"|=[^"][^ ]+)?)";
       flagRegex.compile(regexString);
       std::string workString =
-        cmStrCat(flagsString, " ", definesString, " ", includesString);
+        cmStrCat(flagsString, ' ', definesString, ' ', includesString);
       while (flagRegex.find(workString)) {
         std::string::size_type start = flagRegex.start();
         if (workString[start] == ' ') {

+ 2 - 2
Source/cmFLTKWrapUICommand.cxx

@@ -78,9 +78,9 @@ bool cmFLTKWrapUICommand(std::vector<std::string> const& args,
     // to generate .cxx and .h files
     if (!curr || !curr->GetPropertyAsBool("WRAP_EXCLUDE")) {
       std::string outName = cmStrCat(
-        outputDirectory, "/", cmSystemTools::GetFilenameWithoutExtension(arg));
+        outputDirectory, '/', cmSystemTools::GetFilenameWithoutExtension(arg));
       std::string hname = cmStrCat(outName, ".h");
-      std::string origname = cmStrCat(cdir, "/", arg);
+      std::string origname = cmStrCat(cdir, '/', arg);
       // add starting depends
       std::vector<std::string> depends;
       depends.push_back(origname);

+ 3 - 3
Source/cmFileAPI.cxx

@@ -142,7 +142,7 @@ void cmFileAPI::RemoveOldReplyFiles()
   std::vector<std::string> files = this->LoadDir(reply_dir);
   for (std::string const& f : files) {
     if (this->ReplyFiles.find(f) == this->ReplyFiles.end()) {
-      std::string file = cmStrCat(reply_dir, "/", f);
+      std::string file = cmStrCat(reply_dir, '/', f);
       cmSystemTools::RemoveFile(file);
     }
   }
@@ -207,7 +207,7 @@ std::string cmFileAPI::WriteJsonFile(
 
   // Compute the final name for the file.
   std::string suffix = computeSuffix(tmpFile);
-  std::string suffixWithExtension = cmStrCat("-", suffix, ".json");
+  std::string suffixWithExtension = cmStrCat('-', suffix, ".json");
   fileName = cmStrCat(prefix, suffixWithExtension);
 
   // Truncate the file name length
@@ -225,7 +225,7 @@ std::string cmFileAPI::WriteJsonFile(
     suffix = cmCryptoHash(cmCryptoHash::AlgoSHA256)
                .HashString(toBeRemoved)
                .substr(0, newHashLength);
-    suffixWithExtension = cmStrCat("-", suffix, ".json");
+    suffixWithExtension = cmStrCat('-', suffix, ".json");
     fileName.replace(startPos, overLength, suffixWithExtension);
   }
 

+ 1 - 1
Source/cmFileAPICommand.cxx

@@ -51,7 +51,7 @@ std::string processObjectKindVersions(cmFileAPI& fileApi,
     }
     if (majorVersion < 1 || minorVersion < 0) {
       return cmStrCat("Given a malformed version \"", ver, "\" for ", keyword,
-                      ".");
+                      '.');
     }
     if (fileApi.AddProjectQuery(objectKind,
                                 static_cast<unsigned>(majorVersion),

+ 1 - 1
Source/cmFileAPIToolchains.cxx

@@ -122,7 +122,7 @@ void Toolchains::DumpToolchainVariable(cmMakefile const* mf,
                                        ToolchainVariable const& variable)
 {
   std::string const variableName =
-    cmStrCat("CMAKE_", lang, "_", variable.VariableSuffix);
+    cmStrCat("CMAKE_", lang, '_', variable.VariableSuffix);
 
   if (variable.IsList) {
     cmValue data = mf->GetDefinition(variableName);

+ 12 - 8
Source/cmFileCommand.cxx

@@ -417,7 +417,8 @@ bool HandleStringsCommand(std::vector<std::string> const& args,
                 "CMAKE_POLICY_WARNING_CMP0159")) {
             status.GetMakefile().IssueMessage(
               MessageType::AUTHOR_WARNING,
-              cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0159), '\n',
+              cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0159),
+                       "\n"
                        "For compatibility, CMake is leaving CMAKE_MATCH_<n> "
                        "unchanged."));
           }
@@ -446,7 +447,7 @@ bool HandleStringsCommand(std::vector<std::string> const& args,
       arg_mode = arg_none;
     } else {
       status.SetError(
-        cmStrCat("STRINGS given unknown argument \"", args[i], "\""));
+        cmStrCat("STRINGS given unknown argument \"", args[i], '"'));
       return false;
     }
   }
@@ -2131,8 +2132,9 @@ bool HandleDownloadCommand(std::vector<std::string> const& args,
   if (!file.empty()) {
     fout.open(file.c_str(), std::ios::binary);
     if (!fout) {
-      status.SetError(cmStrCat("DOWNLOAD cannot open file for write\n",
-                               "  file: \"", file, '"'));
+      status.SetError(cmStrCat("DOWNLOAD cannot open file for write\n"
+                               "  file: \"",
+                               file, '"'));
       return false;
     }
   }
@@ -2330,8 +2332,9 @@ bool HandleDownloadCommand(std::vector<std::string> const& args,
 
     std::string actualHash = hash->HashFile(file);
     if (actualHash.empty()) {
-      status.SetError(cmStrCat("DOWNLOAD cannot compute hash on download\n",
-                               "  for file: \"", file, '"'));
+      status.SetError(cmStrCat("DOWNLOAD cannot compute hash on download\n"
+                               "  for file: \"",
+                               file, '"'));
       return false;
     }
 
@@ -2990,8 +2993,9 @@ bool HandleLockCommand(std::vector<std::string> const& args,
     } else {
       status.GetMakefile().IssueMessage(
         MessageType::FATAL_ERROR,
-        cmStrCat("expected DIRECTORY, RELEASE, GUARD, RESULT_VARIABLE or ",
-                 "TIMEOUT\nbut got: \"", args[i], "\"."));
+        cmStrCat("expected DIRECTORY, RELEASE, GUARD, RESULT_VARIABLE or "
+                 "TIMEOUT\nbut got: \"",
+                 args[i], "\"."));
       return false;
     }
   }

+ 2 - 2
Source/cmFileCopier.cxx

@@ -498,7 +498,7 @@ bool cmFileCopier::InstallSymlinkChain(std::string& fromFile,
   while (cmSystemTools::ReadSymlink(fromFile, newFromFile)) {
     if (!cmSystemTools::FileIsFullPath(newFromFile)) {
       std::string fromFilePath = cmSystemTools::GetFilenamePath(fromFile);
-      newFromFile = cmStrCat(fromFilePath, "/", newFromFile);
+      newFromFile = cmStrCat(fromFilePath, '/', newFromFile);
     }
 
     std::string symlinkTarget = cmSystemTools::GetFilenameName(newFromFile);
@@ -530,7 +530,7 @@ bool cmFileCopier::InstallSymlinkChain(std::string& fromFile,
     }
 
     fromFile = newFromFile;
-    toFile = cmStrCat(toFilePath, "/", symlinkTarget);
+    toFile = cmStrCat(toFilePath, '/', symlinkTarget);
   }
 
   return true;

+ 2 - 2
Source/cmFindBase.cxx

@@ -679,7 +679,7 @@ void cmFindBaseDebugState::WriteDebug() const
       "\n    Only Search AppBundle: ", this->FindBaseCommand->SearchAppBundleOnly,
       "\n    Search AppBundle Last: ", this->FindBaseCommand->SearchAppBundleLast,
       "\n    Search AppBundle First: ", this->FindBaseCommand->SearchAppBundleFirst,
-      "\n"
+      '\n'
     );
   // clang-format on
 
@@ -693,7 +693,7 @@ void cmFindBaseDebugState::WriteDebug() const
       "\n  CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: ", !this->FindCommand->NoSystemEnvironmentPath,
       "\n  CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: ", !this->FindCommand->NoCMakeSystemPath,
       "\n  CMAKE_FIND_USE_INSTALL_PREFIX: ", !this->FindCommand->NoCMakeInstallPath,
-      "\n"
+      '\n'
      );
     // clang-format on
   }

+ 3 - 3
Source/cmFindLibraryCommand.cxx

@@ -93,7 +93,7 @@ void cmFindLibraryCommand::AddArchitecturePaths(char const* suffix)
       std::string msg = cmStrCat(
         "find_library(", this->VariableName, ") removed original suffix ", o,
         " from PATH_SUFFIXES while adding architecture paths for suffix '",
-        suffix, "'");
+        suffix, '\'');
       this->DebugMessage(msg);
     }
   }
@@ -160,7 +160,7 @@ void cmFindLibraryCommand::AddArchitecturePath(
       if (this->DebugModeEnabled()) {
         std::string msg = cmStrCat(
           "find_library(", this->VariableName, ") added replacement path ",
-          dirX, " to PATH_SUFFIXES for architecture suffix '", suffix, "'");
+          dirX, " to PATH_SUFFIXES for architecture suffix '", suffix, '\'');
         this->DebugMessage(msg);
       }
       this->SearchPaths.push_back(std::move(dirX));
@@ -171,7 +171,7 @@ void cmFindLibraryCommand::AddArchitecturePath(
       if (this->DebugModeEnabled()) {
         std::string msg = cmStrCat(
           "find_library(", this->VariableName, ") added replacement path ",
-          dir, " to PATH_SUFFIXES for architecture suffix '", suffix, "'");
+          dir, " to PATH_SUFFIXES for architecture suffix '", suffix, '\'');
         this->DebugMessage(msg);
       }
     }

+ 1 - 1
Source/cmFindPackageCommand.cxx

@@ -880,7 +880,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
       this->VersionComplete = args[i];
     } else {
       this->SetError(
-        cmStrCat("called with invalid argument \"", args[i], "\""));
+        cmStrCat("called with invalid argument \"", args[i], '"'));
       return false;
     }
   }

+ 1 - 1
Source/cmForEachCommand.cxx

@@ -357,7 +357,7 @@ bool HandleInMode(std::vector<std::string> const& args,
 
     } else {
       makefile.IssueMessage(MessageType::FATAL_ERROR,
-                            cmStrCat("Unknown argument:\n", "  ", arg, '\n'));
+                            cmStrCat("Unknown argument:\n  ", arg, '\n'));
       return true;
     }
   }

+ 13 - 12
Source/cmGeneratorTarget.cxx

@@ -461,7 +461,7 @@ cmValue cmGeneratorTarget::GetFilePrefixInternal(
   if (!targetPrefix) {
     char const* prefixVar = this->Target->GetPrefixVariableInternal(artifact);
     if (!language.empty() && cmNonempty(prefixVar)) {
-      std::string langPrefix = cmStrCat(prefixVar, "_", language);
+      std::string langPrefix = cmStrCat(prefixVar, '_', language);
       targetPrefix = this->Makefile->GetDefinition(langPrefix);
     }
 
@@ -512,7 +512,7 @@ cmValue cmGeneratorTarget::GetFileSuffixInternal(
   if (!targetSuffix) {
     char const* suffixVar = this->Target->GetSuffixVariableInternal(artifact);
     if (!language.empty() && cmNonempty(suffixVar)) {
-      std::string langSuffix = cmStrCat(suffixVar, "_", language);
+      std::string langSuffix = cmStrCat(suffixVar, '_', language);
       targetSuffix = this->Makefile->GetDefinition(langSuffix);
     }
 
@@ -605,7 +605,7 @@ void cmGeneratorTarget::AddSystemIncludeDirectory(std::string const& inc,
       cmSystemTools::ReplaceString(inc_with_config, "$<CONFIG>", config);
       config_upper = cmSystemTools::UpperCase(config);
     }
-    auto const& key = cmStrCat(config_upper, "/", lang);
+    auto const& key = cmStrCat(config_upper, '/', lang);
     this->Target->AddSystemIncludeDirectories({ inc_with_config });
     if (this->SystemIncludesCache.find(key) ==
         this->SystemIncludesCache.end()) {
@@ -2854,11 +2854,11 @@ std::string cmGeneratorTarget::GetPchHeader(std::string const& config,
     filename = generatorTarget->GetSupportDirectory();
 
     if (this->GetGlobalGenerator()->IsMultiConfig()) {
-      filename = cmStrCat(filename, "/", config);
+      filename = cmStrCat(filename, '/', config);
     }
 
     filename =
-      cmStrCat(filename, "/cmake_pch", arch.empty() ? "" : cmStrCat("_", arch),
+      cmStrCat(filename, "/cmake_pch", arch.empty() ? "" : cmStrCat('_', arch),
                languageToExtension.at(language));
 
     std::string const filename_tmp = cmStrCat(filename, ".tmp");
@@ -2955,14 +2955,14 @@ std::string cmGeneratorTarget::GetPchSource(std::string const& config,
         { "OBJCXX", ".objcxx.hxx.mm" }
       };
 
-      filename = cmStrCat(filename, arch.empty() ? "" : cmStrCat("_", arch),
+      filename = cmStrCat(filename, arch.empty() ? "" : cmStrCat('_', arch),
                           languageToExtension.at(language));
     } else {
       std::map<std::string, std::string> const languageToExtension = {
         { "C", ".c" }, { "CXX", ".cxx" }, { "OBJC", ".m" }, { "OBJCXX", ".mm" }
       };
 
-      filename = cmStrCat(filename, arch.empty() ? "" : cmStrCat("_", arch),
+      filename = cmStrCat(filename, arch.empty() ? "" : cmStrCat('_', arch),
                           languageToExtension.at(language));
     }
 
@@ -3073,7 +3073,7 @@ std::string cmGeneratorTarget::GetPchCreateCompileOptions(
       std::string instantiateOption =
         this->Makefile->GetSafeDefinition(varName);
       if (!instantiateOption.empty()) {
-        createOptionList = cmStrCat(createOptionList, ";", instantiateOption);
+        createOptionList = cmStrCat(createOptionList, ';', instantiateOption);
       }
     }
 
@@ -3081,7 +3081,7 @@ std::string cmGeneratorTarget::GetPchCreateCompileOptions(
       cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_CREATE_PCH");
 
     createOptionList = cmStrCat(
-      createOptionList, ";", this->Makefile->GetSafeDefinition(createOptVar));
+      createOptionList, ';', this->Makefile->GetSafeDefinition(createOptVar));
 
     std::string const pchHeader = this->GetPchHeader(config, language, arch);
     std::string const pchFile = this->GetPchFile(config, language, arch);
@@ -3113,7 +3113,7 @@ std::string cmGeneratorTarget::GetPchUseCompileOptions(
       this->GetSafeProperty(useOptVar);
 
     useOptionList = cmStrCat(
-      useOptionList, ";",
+      useOptionList, ';',
       useOptionListProperty.empty()
         ? this->Makefile->GetSafeDefinition(cmStrCat("CMAKE_", useOptVar))
         : useOptionListProperty);
@@ -5489,7 +5489,7 @@ bool cmGeneratorTarget::AddHeaderSetVerification()
           }
 
           if (fileCgesContextSensitive) {
-            filename = cmStrCat("$<$<CONFIG:", config, ">:", filename, ">");
+            filename = cmStrCat("$<$<CONFIG:", config, ">:", filename, '>');
           }
           verifyTarget->AddSource(filename);
         }
@@ -5770,7 +5770,8 @@ void cmGeneratorTarget::CheckCxxModuleStatus(std::string const& config) const
       cmStrCat("The target named \"", this->GetName(),
                "\" has C++ sources that may use modules, but modules are not "
                "supported by this generator:\n  ",
-               this->GetGlobalGenerator()->GetName(), '\n',
+               this->GetGlobalGenerator()->GetName(),
+               "\n"
                "Modules are supported only by Ninja, Ninja Multi-Config, "
                "and Visual Studio generators for VS 17.4 and newer.  "
                "See the cmake-cxxmodules(7) manual for details.  "

+ 2 - 3
Source/cmGeneratorTarget_Link.cxx

@@ -450,9 +450,8 @@ bool cmGeneratorTarget::VerifyLinkItemColons(LinkItemRole role,
     e = cmStrCat(e, "The link interface of target \"", this->GetName(),
                  "\" contains");
   }
-  e =
-    cmStrCat(e, ":\n  ", item.AsStr(), "\n", "but the target was not found.  ",
-             missingTargetPossibleReasons);
+  e = cmStrCat(e, ":\n  ", item.AsStr(), "\nbut the target was not found.  ",
+               missingTargetPossibleReasons);
   cmListFileBacktrace backtrace = item.Backtrace;
   if (backtrace.Empty()) {
     backtrace = this->GetBacktrace();

+ 1 - 1
Source/cmGhsMultiTargetGenerator.cxx

@@ -756,7 +756,7 @@ std::string cmGhsMultiTargetGenerator::WriteObjectLangOverride(
   std::string ret;
   cmValue rawLangProp = sourceFile->GetProperty("LANGUAGE");
   if (rawLangProp) {
-    ret = cmStrCat(" [", *rawLangProp, "]");
+    ret = cmStrCat(" [", *rawLangProp, ']');
   }
 
   return ret;

+ 9 - 6
Source/cmGlobalGhsMultiGenerator.cxx

@@ -101,11 +101,14 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts,
 
   /* check if the toolset changed from last generate */
   if (cmNonempty(prevTool) && !cmSystemTools::ComparePath(gbuild, *prevTool)) {
-    std::string const& e = cmStrCat(
-      "toolset build tool: ", gbuild, '\n',
-      "Does not match the previously used build tool: ", *prevTool, '\n',
-      "Either remove the CMakeCache.txt file and CMakeFiles "
-      "directory or choose a different binary directory.");
+    std::string const& e =
+      cmStrCat("toolset build tool: ", gbuild,
+               "\n"
+               "Does not match the previously used build tool: ",
+               *prevTool,
+               "\n"
+               "Either remove the CMakeCache.txt file and CMakeFiles "
+               "directory or choose a different binary directory.");
     mf->IssueMessage(MessageType::FATAL_ERROR, e);
     return false;
   }
@@ -377,7 +380,7 @@ void cmGlobalGhsMultiGenerator::WriteTargets(cmLocalGenerator* root)
 
     // create target build file
     std::string name = cmStrCat(target->GetName(), ".tgt", FILE_EXTENSION);
-    std::string fname = cmStrCat(rootBinaryDir, "/", name);
+    std::string fname = cmStrCat(rootBinaryDir, '/', name);
     cmGeneratedFileStream fbld(fname);
     fbld.SetCopyIfDifferent(true);
     this->WriteFileHeader(fbld);

+ 4 - 4
Source/cmGlobalNinjaGenerator.cxx

@@ -1799,7 +1799,7 @@ void cmGlobalNinjaGenerator::WriteBuiltinTargets(std::ostream& os)
     build.Outputs.emplace_back(this->GetInstallParallelTargetName());
     for (auto const& mf : this->Makefiles) {
       build.ExplicitDeps.emplace_back(
-        this->ConvertToNinjaPath(cmStrCat(mf->GetCurrentBinaryDirectory(), "/",
+        this->ConvertToNinjaPath(cmStrCat(mf->GetCurrentBinaryDirectory(), '/',
                                           this->GetInstallLocalTargetName())));
     }
     WriteBuild(os, build);
@@ -2098,7 +2098,7 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
         build.Variables["TARGETS"] = cmStrCat(
           this->BuildAlias(
             this->NinjaOutputPath(GetByproductsForCleanTargetName()), config),
-          " ", this->NinjaOutputPath(GetByproductsForCleanTargetName()));
+          ' ', this->NinjaOutputPath(GetByproductsForCleanTargetName()));
       }
       build.ExplicitDeps.clear();
       if (additionalFiles) {
@@ -2217,8 +2217,8 @@ void cmGlobalNinjaGenerator::WriteTargetInstrument(std::ostream& os)
   {
     cmNinjaRule rule("START_INSTRUMENT");
     rule.Command = cmStrCat(
-      "\"", cmSystemTools::GetCTestCommand(), "\" --start-instrumentation \"",
-      this->GetCMakeInstance()->GetHomeOutputDirectory(), "\"");
+      '"', cmSystemTools::GetCTestCommand(), "\" --start-instrumentation \"",
+      this->GetCMakeInstance()->GetHomeOutputDirectory(), '"');
     /*
      * On Unix systems, Ninja will prefix the command with `/bin/sh -c`.
      * Use exec so that Ninja is the parent process of the command.

+ 4 - 2
Source/cmGlobalVisualStudio10Generator.cxx

@@ -297,8 +297,10 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
                    this->GetPlatformToolsetString(),
                    ",version=", this->GeneratorToolsetVersion,
                    "\n"
-                   "has multiple matches installed at\n",
-                   "  ", auxProps, "\n",
+                   "has multiple matches installed at\n"
+                   "  ",
+                   auxProps,
+                   "\n"
                    "The toolset and version specification must resolve \n"
                    "to a single installed toolset"));
 

+ 4 - 4
Source/cmGlobalXCodeGenerator.cxx

@@ -2264,7 +2264,7 @@ void cmGlobalXCodeGenerator::AddCommandsToBuildPhase(
   cdir = cmSystemTools::ConvertToOutputPath(cdir);
   std::string makecmd = cmStrCat(
     "make -C ", cdir, " -f ", cmSystemTools::ConvertToOutputPath(makefile),
-    "$CONFIGURATION", " OBJDIR=$(basename \"$OBJECT_FILE_DIR_normal\") all");
+    "$CONFIGURATION OBJDIR=$(basename \"$OBJECT_FILE_DIR_normal\") all");
   buildphase->AddAttribute("shellScript", this->CreateString(makecmd));
   buildphase->AddAttribute("showEnvVarsInLog", this->CreateString("0"));
 }
@@ -2553,7 +2553,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
           this->CurrentLocalGenerator->IssueMessage(
             MessageType::AUTHOR_WARNING,
             cmStrCat("Unknown Swift_COMPILATION_MODE on target '",
-                     gtgt->GetName(), "'"));
+                     gtgt->GetName(), '\''));
           break;
       }
     }
@@ -3182,7 +3182,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateUtilityTarget(
 
   cmXCodeObject* target = this->CreateObject(
     cmXCodeObject::PBXAggregateTarget,
-    cmStrCat("PBXAggregateTarget:", gtgt->GetName(), ":", targetBinaryPath));
+    cmStrCat("PBXAggregateTarget:", gtgt->GetName(), ':', targetBinaryPath));
   target->SetComment(gtgt->GetName());
   cmXCodeObject* buildPhases = this->CreateObject(cmXCodeObject::OBJECT_LIST);
   std::vector<cmXCodeObject*> emptyContentVector;
@@ -3412,7 +3412,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeTarget(
 
   cmXCodeObject* target = this->CreateObject(
     cmXCodeObject::PBXNativeTarget,
-    cmStrCat("PBXNativeTarget:", gtgt->GetName(), ":", targetBinaryPath));
+    cmStrCat("PBXNativeTarget:", gtgt->GetName(), ':', targetBinaryPath));
 
   target->AddAttribute("buildPhases", buildPhases);
   cmXCodeObject* buildRules = this->CreateObject(cmXCodeObject::OBJECT_LIST);

+ 1 - 1
Source/cmIncludeCommand.cxx

@@ -96,7 +96,7 @@ bool cmIncludeCommand(std::vector<std::string> const& args,
             status.GetMakefile().IssueMessage(
               MessageType::AUTHOR_WARNING,
               cmStrCat(cmPolicies::GetPolicyWarning(ModulePolicy->second),
-                       "\n"));
+                       '\n'));
             CM_FALLTHROUGH;
           }
           case cmPolicies::OLD:

+ 3 - 2
Source/cmInstallCommand.cxx

@@ -999,7 +999,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
           if (!target.HasKnownObjectFileLocation(&reason)) {
             status.SetError(
               cmStrCat("TARGETS given OBJECT library \"", target.GetName(),
-                       "\" whose objects may not be installed", reason, "."));
+                       "\" whose objects may not be installed", reason, '.'));
             return false;
           }
 
@@ -1604,7 +1604,8 @@ bool HandleFilesMode(std::vector<std::string> const& args,
     if (gg->IsExportedTargetsFile(file)) {
       helper.Makefile->IssueMessage(
         MessageType::FATAL_ERROR,
-        cmStrCat("The file\n  ", file, '\n',
+        cmStrCat("The file\n  ", file,
+                 "\n"
                  "was generated by the export() command.  "
                  "It may not be installed with the install() command.  "
                  "Use the install(EXPORT) mechanism instead.  "

+ 1 - 1
Source/cmInstallDirectoryGenerator.cxx

@@ -85,7 +85,7 @@ void cmInstallDirectoryGenerator::GenerateScriptForConfig(
   cmMakefile const& mf = *this->LocalGenerator->GetMakefile();
   for (std::string& d : dirs) {
     if (!cmSystemTools::FileIsFullPath(d)) {
-      d = cmStrCat(mf.GetCurrentSourceDirectory(), "/", d);
+      d = cmStrCat(mf.GetCurrentSourceDirectory(), '/', d);
     }
   }
 

+ 1 - 1
Source/cmInstallScriptHandler.cxx

@@ -165,7 +165,7 @@ int cmInstallScriptHandler::Install(unsigned int j,
         cmStrCat("install_manifest_", md5.HashString(this->component), ".txt");
     }
   }
-  cmGeneratedFileStream fout(cmStrCat(this->binaryDir, "/", install_manifest));
+  cmGeneratedFileStream fout(cmStrCat(this->binaryDir, '/', install_manifest));
   fout.SetCopyIfDifferent(true);
   for (auto const& dir : this->directories) {
     auto local_manifest = cmStrCat(dir, "/install_local_manifest.txt");

+ 1 - 1
Source/cmInstallTargetGenerator.cxx

@@ -425,7 +425,7 @@ void cmInstallTargetGenerator::GetInstallObjectNames(
 {
   this->Target->GetTargetObjectNames(config, objects);
   for (std::string& o : objects) {
-    o = cmStrCat(computeInstallObjectDir(this->Target, config), "/", o);
+    o = cmStrCat(computeInstallObjectDir(this->Target, config), '/', o);
   }
 }
 

+ 7 - 7
Source/cmInstrumentation.cxx

@@ -229,7 +229,7 @@ int cmInstrumentation::CollectTimingData(cmInstrumentationQuery::Hook hook)
   std::string const& directory = cmStrCat(this->timingDirv1, "/data");
   std::string const& file_name =
     cmStrCat("index-", ComputeSuffixTime(), ".json");
-  std::string index_path = cmStrCat(directory, "/", file_name);
+  std::string index_path = cmStrCat(directory, '/', file_name);
   cmSystemTools::Touch(index_path, true);
 
   // Gather Snippets
@@ -287,7 +287,7 @@ int cmInstrumentation::CollectTimingData(cmInstrumentationQuery::Hook hook)
 
   // Execute callbacks
   for (auto& cb : this->callbacks) {
-    cmSystemTools::RunSingleCommand(cmStrCat(cb, " \"", index_path, "\""),
+    cmSystemTools::RunSingleCommand(cmStrCat(cb, " \"", index_path, '"'),
                                     nullptr, nullptr, nullptr, nullptr,
                                     cmSystemTools::OUTPUT_PASSTHROUGH);
   }
@@ -299,7 +299,7 @@ int cmInstrumentation::CollectTimingData(cmInstrumentationQuery::Hook hook)
 
   // Delete files
   for (auto const& f : index["snippets"]) {
-    cmSystemTools::RemoveFile(cmStrCat(directory, "/", f.asString()));
+    cmSystemTools::RemoveFile(cmStrCat(directory, '/', f.asString()));
   }
   cmSystemTools::RemoveFile(index_path);
 
@@ -386,9 +386,9 @@ void cmInstrumentation::WriteInstrumentationJson(Json::Value& root,
   wbuilder["indentation"] = "\t";
   std::unique_ptr<Json::StreamWriter> JsonWriter =
     std::unique_ptr<Json::StreamWriter>(wbuilder.newStreamWriter());
-  std::string const& directory = cmStrCat(this->timingDirv1, "/", subdir);
+  std::string const& directory = cmStrCat(this->timingDirv1, '/', subdir);
   cmSystemTools::MakeDirectory(directory);
-  cmsys::ofstream ftmp(cmStrCat(directory, "/", file_name).c_str());
+  cmsys::ofstream ftmp(cmStrCat(directory, '/', file_name).c_str());
   JsonWriter->write(root, &ftmp);
   ftmp << "\n";
   ftmp.close();
@@ -531,7 +531,7 @@ int cmInstrumentation::InstrumentCommand(
         for (auto const& output : root["outputs"]) {
           root["outputSizes"].append(
             static_cast<Json::Value::UInt64>(cmSystemTools::FileLength(
-              cmStrCat(this->binaryDir, "/", output.asCString()))));
+              cmStrCat(this->binaryDir, '/', output.asCString()))));
         }
       }
     }
@@ -542,7 +542,7 @@ int cmInstrumentation::InstrumentCommand(
   // Write Json
   cmsys::SystemInformation info;
   std::string const& file_name = cmStrCat(
-    command_type, "-",
+    command_type, '-',
     this->ComputeSuffixHash(cmStrCat(command_str, info.GetProcessId())),
     this->ComputeSuffixTime(), ".json");
   this->WriteInstrumentationJson(root, "data", file_name);

+ 3 - 3
Source/cmInstrumentationCommand.cxx

@@ -30,7 +30,7 @@ bool validateVersion(std::string const& key, std::string const& versionString,
                      int& version, cmExecutionStatus& status)
 {
   if (!std::all_of(versionString.begin(), versionString.end(), isCharDigit)) {
-    status.SetError(cmStrCat("given a non-integer ", key, "."));
+    status.SetError(cmStrCat("given a non-integer ", key, '.'));
     return false;
   }
   version = std::atoi(versionString.c_str());
@@ -118,7 +118,7 @@ bool cmInstrumentationCommand(std::vector<std::string> const& args,
     cmInstrumentationQuery::Query query;
     if (!queryParser(arg, query)) {
       status.SetError(
-        cmStrCat("given invalid argument to QUERIES \"", arg, "\""));
+        cmStrCat("given invalid argument to QUERIES \"", arg, '"'));
       return false;
     }
     queries.insert(query);
@@ -131,7 +131,7 @@ bool cmInstrumentationCommand(std::vector<std::string> const& args,
     cmInstrumentationQuery::Hook hook;
     if (!hookParser(arg, hook)) {
       status.SetError(
-        cmStrCat("given invalid argument to HOOKS \"", arg, "\""));
+        cmStrCat("given invalid argument to HOOKS \"", arg, '"'));
       return false;
     }
     hooks.insert(hook);

+ 1 - 1
Source/cmInstrumentationQuery.cxx

@@ -60,7 +60,7 @@ static std::function<bool(E&, Json::Value const*, cmJSONState*)> EnumHelper(
       }
     }
     state->AddErrorAtValue(
-      cmStrCat("Not a valid ", type, ": \"", value->asString(), "\""), value);
+      cmStrCat("Not a valid ", type, ": \"", value->asString(), '"'), value);
     return false;
   };
 }

+ 2 - 2
Source/cmJSONHelpers.cxx

@@ -20,7 +20,7 @@ ErrorGenerator EXPECTED_TYPE(std::string const& type)
       state->AddErrorAtValue(cmStrCat("Expected ", type), value);
       return;
     }
-    std::string errMsg = cmStrCat("\"", state->key(), "\" expected ", type);
+    std::string errMsg = cmStrCat('"', state->key(), "\" expected ", type);
     if (value && value->isConvertibleTo(Json::ValueType::stringValue)) {
       errMsg = cmStrCat(errMsg, ", got: ", value->asString());
     }
@@ -114,7 +114,7 @@ ErrorGenerator INVALID_NAMED_OBJECT_KEY(
         if (it->first.rfind("$vector_item_", 0) == 0) {
           continue;
         }
-        return cmStrCat("\"", it->first, "\"");
+        return cmStrCat('"', it->first, '"');
       }
       return "root";
     })(errorType, extraFields);

+ 2 - 2
Source/cmJSONState.cxx

@@ -95,9 +95,9 @@ std::string cmJSONState::GetErrorMessage(bool showContext)
     if (!filenameName.empty() && loc.line > 0) {
       message = cmStrCat(message, filenameName, ':', loc.line, ": ");
     }
-    message = cmStrCat(message, error.GetErrorMessage(), "\n");
+    message = cmStrCat(message, error.GetErrorMessage(), '\n');
     if (showContext && loc.line > 0) {
-      message = cmStrCat(message, GetJsonContext(loc), "\n");
+      message = cmStrCat(message, GetJsonContext(loc), '\n');
     }
   }
   message.pop_back();

+ 4 - 4
Source/cmLinkLineComputer.cxx

@@ -145,10 +145,10 @@ void cmLinkLineComputer::ComputeLinkPath(
         }
 
         linkPathNoBT +=
-          cmStrCat(" ", libPathFlag,
+          cmStrCat(' ', libPathFlag,
                    this->ConvertToOutputForExisting(
                      item.Target->GetDirectory(cli.GetConfig(), type)),
-                   libPathTerminator, " ");
+                   libPathTerminator, ' ');
       }
     }
 
@@ -158,9 +158,9 @@ void cmLinkLineComputer::ComputeLinkPath(
   }
 
   for (BT<std::string> libDir : cli.GetDirectoriesWithBacktraces()) {
-    libDir.Value = cmStrCat(" ", libPathFlag,
+    libDir.Value = cmStrCat(' ', libPathFlag,
                             this->ConvertToOutputForExisting(libDir.Value),
-                            libPathTerminator, " ");
+                            libPathTerminator, ' ');
     linkPath.emplace_back(libDir);
   }
 

+ 5 - 5
Source/cmList.cxx

@@ -359,7 +359,7 @@ public:
       throw transform_error(
         cmStrCat("sub-command TRANSFORM, selector FOR "
                  "expects <start> to be no greater than <stop> (",
-                 this->Start, " > ", this->Stop, ")"));
+                 this->Start, " > ", this->Stop, ')'));
     }
 
     // compute indexes
@@ -534,7 +534,7 @@ public:
     }
     if (!this->ReplaceHelper->IsReplaceExpressionValid()) {
       throw transform_error(cmStrCat("sub-command TRANSFORM, action REPLACE: ",
-                                     this->ReplaceHelper->GetError(), "."));
+                                     this->ReplaceHelper->GetError(), '.'));
     }
   }
   void Initialize(TransformSelector* selector,
@@ -552,7 +552,7 @@ public:
       if (!this->ReplaceHelper->Replace(s, output)) {
         throw transform_error(
           cmStrCat("sub-command TRANSFORM, action REPLACE: ",
-                   this->ReplaceHelper->GetError(), "."));
+                   this->ReplaceHelper->GetError(), '.'));
       }
 
       return output;
@@ -855,7 +855,7 @@ cmList::size_type cmList::ComputeIndex(index_type pos, bool boundCheck) const
       if (index < 0 || length <= static_cast<size_type>(index)) {
         throw std::out_of_range(cmStrCat("index: ", pos, " out of range (-",
                                          this->Values.size(), ", ",
-                                         this->Values.size() - 1, ")"));
+                                         this->Values.size() - 1, ')'));
       }
     }
     return index;
@@ -881,7 +881,7 @@ cmList::size_type cmList::ComputeInsertIndex(index_type pos,
       if (index < 0 || length < static_cast<size_type>(index)) {
         throw std::out_of_range(cmStrCat("index: ", pos, " out of range (-",
                                          this->Values.size(), ", ",
-                                         this->Values.size(), ")"));
+                                         this->Values.size(), ')'));
       }
     }
     return index;

+ 11 - 11
Source/cmLocalGenerator.cxx

@@ -1742,7 +1742,7 @@ std::vector<BT<std::string>> cmLocalGenerator::GetTargetCompileFlags(
           this->IssueMessage(
             MessageType::AUTHOR_WARNING,
             cmStrCat("Unknown Swift_COMPILATION_MODE on target '",
-                     target->GetName(), "'"));
+                     target->GetName(), '\''));
         }
       }
       this->AppendFlags(compileFlags, swiftCompileModeFlag);
@@ -2776,7 +2776,7 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
 
           target->Target->AppendProperty(
             cmStrCat(lang, "_COMPILE_OPTIONS_USE_PCH"),
-            cmStrCat("$<$<CONFIG:", config, ">:", useMultiArchPch, ">"));
+            cmStrCat("$<$<CONFIG:", config, ">:", useMultiArchPch, '>'));
         }
       }
 
@@ -2825,7 +2825,7 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
             if (!ReuseFrom) {
               pch_sf->AppendProperty(
                 "OBJECT_OUTPUTS",
-                cmStrCat("$<$<CONFIG:", config, ">:", pchFile, ">"));
+                cmStrCat("$<$<CONFIG:", config, ">:", pchFile, '>'));
             } else {
               auto* reuseTarget =
                 this->GlobalGenerator->FindGeneratorTarget(*ReuseFrom);
@@ -2894,7 +2894,7 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
                 }
                 target->Target->AppendProperty(
                   cmStrCat(linkerProperty, configUpper),
-                  cmStrCat(" ",
+                  cmStrCat(' ',
                            this->ConvertToOutputFormat(pchSourceObj, SHELL)),
                   cm::nullopt, true);
               } else if (reuseTarget->GetType() ==
@@ -2935,10 +2935,10 @@ void cmLocalGenerator::CopyPchCompilePdb(
   cmGeneratorTarget* reuseTarget, std::vector<std::string> const& extensions)
 {
   std::string const pdb_prefix =
-    this->GetGlobalGenerator()->IsMultiConfig() ? cmStrCat(config, "/") : "";
+    this->GetGlobalGenerator()->IsMultiConfig() ? cmStrCat(config, '/') : "";
 
   std::string const target_compile_pdb_dir =
-    cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/",
+    cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), '/',
              target->GetName(), ".dir/");
 
   std::string const copy_script = cmStrCat(
@@ -2954,10 +2954,10 @@ void cmLocalGenerator::CopyPchCompilePdb(
   for (auto const& extension : extensions) {
     std::string const from_file =
       cmStrCat(reuseTarget->GetLocalGenerator()->GetCurrentBinaryDirectory(),
-               "/", ReuseFrom, ".dir/${PDB_PREFIX}", ReuseFrom, extension);
+               '/', ReuseFrom, ".dir/${PDB_PREFIX}", ReuseFrom, extension);
 
     std::string const to_dir =
-      cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/",
+      cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), '/',
                target->GetName(), ".dir/${PDB_PREFIX}");
 
     std::string const to_file = cmStrCat(to_dir, ReuseFrom, extension);
@@ -2996,7 +2996,7 @@ void cmLocalGenerator::CopyPchCompilePdb(
 
   auto configGenex = [&](cm::string_view expr) -> std::string {
     if (this->GetGlobalGenerator()->IsMultiConfig()) {
-      return cmStrCat("$<$<CONFIG:", config, ">:", expr, ">");
+      return cmStrCat("$<$<CONFIG:", config, ">:", expr, '>');
     }
     return std::string(expr);
   };
@@ -3122,7 +3122,7 @@ cmLocalGenerator::UnitySource cmLocalGenerator::WriteUnitySource(
       cm::string_view sep;
       for (size_t ci : ubs.Configs) {
         cond = cmStrCat(*cond, sep, "defined(CMAKE_UNITY_CONFIG_",
-                        cmSystemTools::UpperCase(configs[ci]), ")");
+                        cmSystemTools::UpperCase(configs[ci]), ')');
         sep = " || "_s;
       }
     }
@@ -4781,7 +4781,7 @@ std::vector<std::string> ComputeISPCExtraObjects(
 
   for (auto const& ispcTarget : ispcSuffixes) {
     computedObjects.emplace_back(
-      cmStrCat(normalizedDir, "/", objNameNoExt, "_", ispcTarget, extension));
+      cmStrCat(normalizedDir, '/', objNameNoExt, '_', ispcTarget, extension));
   }
 
   return computedObjects;

+ 1 - 1
Source/cmLocalNinjaGenerator.cxx

@@ -920,7 +920,7 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher(
                           : outputs[i],
                         cmOutputConverter::SHELL));
     if (i != outputs.size() - 1) {
-      output = cmStrCat(output, ",");
+      output = cmStrCat(output, ',');
     }
   }
   vars.Output = output.c_str();

+ 2 - 2
Source/cmLocalUnixMakefileGenerator3.cxx

@@ -1048,7 +1048,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
                                 : outputs[i],
                               cmOutputConverter::SHELL));
           if (i != outputs.size() - 1) {
-            output = cmStrCat(output, ",");
+            output = cmStrCat(output, ',');
           }
         }
         vars.Output = output.c_str();
@@ -1109,7 +1109,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
   // Prefix the commands with the jobserver prefix "+"
   if (ccg.GetCC().GetJobserverAware() && gg->IsGNUMakeJobServerAware()) {
     std::transform(commands1.begin(), commands1.end(), commands1.begin(),
-                   [](std::string const& cmd) { return cmStrCat("+", cmd); });
+                   [](std::string const& cmd) { return cmStrCat('+', cmd); });
   }
 
   // push back the custom commands

+ 2 - 2
Source/cmMakefileTargetGenerator.cxx

@@ -753,7 +753,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
 
   // Add language-specific flags.
   std::string const langFlags =
-    cmStrCat("$(", lang, "_FLAGS", filterArch, ")");
+    cmStrCat("$(", lang, "_FLAGS", filterArch, ')');
   this->LocalGenerator->AppendFlags(flags, langFlags);
 
   cmGeneratorExpressionInterpreter genexInterpreter(
@@ -1008,7 +1008,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
             "CUDA_SEPARABLE_COMPILATION")) {
         std::string const& rdcFlag =
           this->Makefile->GetRequiredDefinition("_CMAKE_CUDA_RDC_FLAG");
-        cudaCompileMode = cmStrCat(cudaCompileMode, rdcFlag, " ");
+        cudaCompileMode = cmStrCat(cudaCompileMode, rdcFlag, ' ');
       }
 
       static std::array<cm::string_view, 4> const compileModes{

+ 6 - 6
Source/cmNinjaNormalTargetGenerator.cxx

@@ -204,24 +204,24 @@ std::string cmNinjaNormalTargetGenerator::LanguageLinkerRule(
   std::string const& config) const
 {
   return cmStrCat(
-    this->TargetLinkLanguage(config), "_",
+    this->TargetLinkLanguage(config), '_',
     cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()),
     "_LINKER__",
     cmGlobalNinjaGenerator::EncodeRuleName(
       this->GetGeneratorTarget()->GetName()),
-    "_", config);
+    '_', config);
 }
 
 std::string cmNinjaNormalTargetGenerator::LanguageLinkerDeviceRule(
   std::string const& config) const
 {
   return cmStrCat(
-    this->TargetLinkLanguage(config), "_",
+    this->TargetLinkLanguage(config), '_',
     cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()),
     "_DEVICE_LINKER__",
     cmGlobalNinjaGenerator::EncodeRuleName(
       this->GetGeneratorTarget()->GetName()),
-    "_", config);
+    '_', config);
 }
 
 std::string cmNinjaNormalTargetGenerator::LanguageLinkerCudaDeviceRule(
@@ -845,7 +845,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement(
 
   std::string targetOutputDir =
     cmStrCat(this->GetLocalGenerator()->GetTargetDirectory(genTarget),
-             globalGen->ConfigDirectory(config), "/");
+             globalGen->ConfigDirectory(config), '/');
   targetOutputDir = globalGen->ExpandCFGIntDir(targetOutputDir, config);
 
   std::string targetOutputReal =
@@ -981,7 +981,7 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkStatement(
   if (config != fileConfig) {
     std::string targetOutputFileConfigDir =
       cmStrCat(this->GetLocalGenerator()->GetTargetDirectory(genTarget),
-               globalGen->ConfigDirectory(fileConfig), "/");
+               globalGen->ConfigDirectory(fileConfig), '/');
     targetOutputFileConfigDir =
       globalGen->ExpandCFGIntDir(outputDir, fileConfig);
     if (outputDir == targetOutputFileConfigDir) {

+ 8 - 5
Source/cmNinjaTargetGenerator.cxx

@@ -594,8 +594,10 @@ std::string GetScanCommand(
   cm::optional<cm::string_view> srcOrigFile = cm::nullopt)
 {
   return cmStrCat(cmakeCmd, " -E cmake_ninja_depends --tdi=", tdi,
-                  " --lang=", lang, " --src=", srcFile, " --out=$out",
-                  " --dep=$DEP_FILE --obj=$OBJ_FILE --ddi=", ddiFile,
+                  " --lang=", lang, " --src=", srcFile,
+                  " --out=$out"
+                  " --dep=$DEP_FILE --obj=$OBJ_FILE --ddi=",
+                  ddiFile,
                   srcOrigFile ? cmStrCat(" --src-orig=", *srcOrigFile) : "");
 }
 
@@ -928,7 +930,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(std::string const& lang,
           "CUDA_SEPARABLE_COMPILATION")) {
       std::string const& rdcFlag =
         this->Makefile->GetRequiredDefinition("_CMAKE_CUDA_RDC_FLAG");
-      cudaCompileMode = cmStrCat(cudaCompileMode, rdcFlag, " ");
+      cudaCompileMode = cmStrCat(cudaCompileMode, rdcFlag, ' ');
     }
     static std::array<cm::string_view, 4> const compileModes{
       { "PTX"_s, "CUBIN"_s, "FATBIN"_s, "OPTIX"_s }
@@ -1299,7 +1301,8 @@ void cmNinjaTargetGenerator::GenerateSwiftOutputFileMap(
   }();
 
   std::string mapFilePath =
-    cmStrCat(this->GeneratorTarget->GetSupportDirectory(), '/', config, '/',
+    cmStrCat(this->GeneratorTarget->GetSupportDirectory(), '/', config,
+             "/"
              "output-file-map.json");
 
   // build the global target dependencies
@@ -2300,7 +2303,7 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
           "CUDA_SEPARABLE_COMPILATION")) {
       std::string const& rdcFlag =
         this->Makefile->GetRequiredDefinition("_CMAKE_CUDA_RDC_FLAG");
-      cudaCompileMode = cmStrCat(cudaCompileMode, rdcFlag, " ");
+      cudaCompileMode = cmStrCat(cudaCompileMode, rdcFlag, ' ');
     }
     static std::array<cm::string_view, 4> const compileModes{
       { "PTX"_s, "CUBIN"_s, "FATBIN"_s, "OPTIX"_s }

+ 1 - 1
Source/cmNinjaUtilityTargetGenerator.cxx

@@ -68,7 +68,7 @@ void cmNinjaUtilityTargetGenerator::WriteUtilBuildStatements(
     configDir = gg->ConfigDirectory(fileConfig);
   }
   std::string utilCommandName =
-    cmStrCat(lg->GetCurrentBinaryDirectory(), "/CMakeFiles", configDir, "/",
+    cmStrCat(lg->GetCurrentBinaryDirectory(), "/CMakeFiles", configDir, '/',
              this->GetTargetName(), ".util");
   utilCommandName = this->ConvertToNinjaPath(utilCommandName);
 

+ 3 - 3
Source/cmPkgConfigResolver.cxx

@@ -64,17 +64,17 @@ std::string cmPkgConfigVersionReq::string() const
     case ANY:
       return "";
     case LT:
-      return cmStrCat("<", Version);
+      return cmStrCat('<', Version);
     case LT_EQ:
       return cmStrCat("<=", Version);
     case EQ:
-      return cmStrCat("=", Version);
+      return cmStrCat('=', Version);
     case NEQ:
       return cmStrCat("!=", Version);
     case GT_EQ:
       return cmStrCat(">=", Version);
     case GT:
-      return cmStrCat(">", Version);
+      return cmStrCat('>', Version);
   }
   return "";
 }

+ 1 - 1
Source/cmPolicies.cxx

@@ -225,7 +225,7 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile* mf,
       MessageType::FATAL_ERROR,
       cmStrCat("An attempt was made to set the policy version of CMake to \"",
                version_min,
-               "\" which is greater than this version of CMake.  ",
+               "\" which is greater than this version of CMake.  "
                "This is not allowed because the greater version may have new "
                "policies not known to this CMake.  "
                "You may need a newer CMake version to build this project."));

+ 2 - 2
Source/cmQtAutoGenGlobalInitializer.cxx

@@ -143,8 +143,8 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
             "AUTOGEN: No valid Qt version found for target ",
             target->GetName(), ".  ",
             cmQtAutoGen::Tools(mocDisabled, uicDisabled, rccDisabled),
-            " disabled.  Consider adding:\n", "  find_package(Qt", version,
-            " COMPONENTS ", component, ")\n", "to your CMakeLists.txt file.");
+            " disabled.  Consider adding:\n  find_package(Qt", version,
+            " COMPONENTS ", component, ")\nto your CMakeLists.txt file.");
           target->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, msg);
         }
         if (mocIsValid || uicIsValid || rccIsValid) {

+ 12 - 10
Source/cmQtAutoGenInitializer.cxx

@@ -1204,7 +1204,8 @@ bool cmQtAutoGenInitializer::InitScanFiles()
       this->Makefile->IssueMessage(
         MessageType::AUTHOR_WARNING,
         cmStrCat(
-          cmPolicies::GetPolicyWarning(cmPolicies::CMP0071), '\n',
+          cmPolicies::GetPolicyWarning(cmPolicies::CMP0071),
+          "\n"
           "For compatibility, CMake is excluding the GENERATED source "
           "file(s):\n",
           files, "from processing by ",
@@ -1235,9 +1236,10 @@ bool cmQtAutoGenInitializer::InitScanFiles()
     this->Makefile->IssueMessage(
       MessageType::AUTHOR_WARNING,
       cmStrCat(
-        cmPolicies::GetPolicyWarning(cmPolicies::CMP0100), '\n',
-        "For compatibility, CMake is excluding the header file(s):\n", files,
-        "from processing by ",
+        cmPolicies::GetPolicyWarning(cmPolicies::CMP0100),
+        "\n"
+        "For compatibility, CMake is excluding the header file(s):\n",
+        files, "from processing by ",
         cmQtAutoGen::Tools(this->Moc.Enabled, this->Uic.Enabled, false),
         ".  If any of the files should be processed, set CMP0100 to NEW.  "
         "If any of the files should not be processed, "
@@ -1271,7 +1273,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
       if (this->MultiConfig && !this->GlobalGen->IsXcode() &&
           this->UseBetterGraph) {
         qrc.OutputFile = cmStrCat(this->Dir.Build, '/', qrc.QrcPathChecksum,
-                                  "_$<CONFIG>", "/qrc_", qrc.QrcName, ".cpp");
+                                  "_$<CONFIG>/qrc_", qrc.QrcName, ".cpp");
       } else {
         qrc.OutputFile = cmStrCat(this->Dir.Build, '/', qrc.QrcPathChecksum,
                                   "/qrc_", qrc.QrcName, ".cpp");
@@ -1572,7 +1574,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
           cmStrCat(this->Dir.Build, "/deps_");
         std::string const timestampFileName =
           timestampFileWithoutConfig + configView;
-        outputFile = cmStrCat(this->Dir.Build, "/", timestampFileName);
+        outputFile = cmStrCat(this->Dir.Build, '/', timestampFileName);
         auto const depFileWithConfig =
           cmStrCat(depFileWithoutConfig, configView);
         depFile = depFileWithConfig;
@@ -1585,18 +1587,18 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
           auto tempDepFile = depFileWithoutConfig + config;
           outputFileWithConfig.Config[config] = tempTimestampFileName;
           this->AutogenTarget.DepFileRuleName.Config[config] =
-            cmStrCat(this->Dir.RelativeBuild, "/", tempTimestampFileName);
+            cmStrCat(this->Dir.RelativeBuild, '/', tempTimestampFileName);
           this->AutogenTarget.DepFile.Config[config] = tempDepFile;
         }
         this->AddGeneratedSource(outputFileWithConfig, this->Moc);
       } else {
         cm::string_view const timestampFileName = "timestamp";
-        outputFile = cmStrCat(this->Dir.Build, "/", timestampFileName);
+        outputFile = cmStrCat(this->Dir.Build, '/', timestampFileName);
         this->AutogenTarget.DepFile.Default =
           cmStrCat(this->Dir.Build, "/deps");
         depFile = this->AutogenTarget.DepFile.Default;
         this->AutogenTarget.DepFileRuleName.Default =
-          cmStrCat(this->Dir.RelativeBuild, "/", timestampFileName);
+          cmStrCat(this->Dir.RelativeBuild, '/', timestampFileName);
         commandLines.push_back(cmMakeCommandLine(
           { cmSystemTools::GetCMakeCommand(), "-E", "touch", outputFile }));
         this->AddGeneratedSource(outputFile, this->Moc);
@@ -1772,7 +1774,7 @@ bool cmQtAutoGenInitializer::InitRccTargets()
             auto resourceFilesWithConfig = cmStrCat(
               "$<$<CONFIG:", config,
               ">:", cmList{ qrc.Resources.Config.at(config) }.to_string(),
-              ">");
+              '>');
             ccDepends.emplace_back(std::move(resourceFilesWithConfig));
           }
         } else {

+ 3 - 3
Source/cmQtAutoMocUic.cxx

@@ -1302,7 +1302,7 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::EvalSource(
                  ".\nRunning moc on the source\n  ",
                  this->MessagePath(sourceFile.FileName), "!\nBetter include ",
                  this->MessagePath(sourceBase + ".moc"),
-                 " for compatibility with regular mode.\n",
+                 " for compatibility with regular mode.\n"
                  "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
 
       // Create mapping
@@ -1370,7 +1370,7 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::EvalSource(
             " macro.\nRunning moc on the header\n  ",
             this->MessagePath(headerHandle->FileName), "!\nBetter include ",
             this->MessagePath("moc_" + incKey.Base + ".cpp"),
-            " for a compatibility with regular mode.\n",
+            " for a compatibility with regular mode.\n"
             "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
       } else {
         this->Log().Warning(
@@ -1382,7 +1382,7 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::EvalSource(
             ".\nRunning moc on the header\n  ",
             this->MessagePath(headerHandle->FileName), "!\nBetter include ",
             this->MessagePath("moc_" + incKey.Base + ".cpp"),
-            " for compatibility with regular mode.\n",
+            " for compatibility with regular mode.\n"
             "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
       }
       // Create mapping

+ 4 - 3
Source/cmQtAutoRcc.cxx

@@ -144,7 +144,7 @@ bool cmQtAutoRccT::InitFromInfo(InfoT const& info)
   this->QrcFileDir_ = cmSystemTools::GetFilenamePath(this->QrcFile_);
   if (IsMultiConfig() && !this->IsXcode() && this->UseBetterGraph_) {
     this->RccFilePublic_ =
-      cmStrCat(this->AutogenBuildDir_, '/', this->RccPathChecksum_, "_",
+      cmStrCat(this->AutogenBuildDir_, '/', this->RccPathChecksum_, '_',
                this->InfoConfig(), '/', this->RccFileName_);
   } else {
     this->RccFilePublic_ =
@@ -511,8 +511,9 @@ bool cmQtAutoRccT::GenerateWrapper()
   if (this->IsMultiConfig()) {
     // Wrapper file content
     std::string content =
-      cmStrCat("// This is an autogenerated configuration wrapper file.\n",
-               "// Changes will be overwritten.\n", "#include <",
+      cmStrCat("// This is an autogenerated configuration wrapper file.\n"
+               "// Changes will be overwritten.\n"
+               "#include <",
                this->MultiConfigOutput(), ">\n");
 
     // Compare with existing file content

+ 1 - 1
Source/cmRST.cxx

@@ -348,7 +348,7 @@ void cmRST::OutputMarkupLines(bool inlineMarkup)
 {
   for (auto line : this->MarkupLines) {
     if (!line.empty()) {
-      line = cmStrCat(" ", line);
+      line = cmStrCat(' ', line);
     }
     this->OutputLine(line, inlineMarkup);
   }

+ 2 - 1
Source/cmReturnCommand.cxx

@@ -22,7 +22,8 @@ bool cmReturnCommand(std::vector<std::string> const& args,
         status.GetMakefile().IssueMessage(
           MessageType::AUTHOR_WARNING,
           cmStrCat(
-            cmPolicies::GetPolicyWarning(cmPolicies::CMP0140), '\n',
+            cmPolicies::GetPolicyWarning(cmPolicies::CMP0140),
+            "\n"
             "return() checks its arguments when the policy is set to NEW. "
             "Since the policy is not set the OLD behavior will be used so "
             "the arguments will be ignored."));

+ 2 - 2
Source/cmRulePlaceholderExpander.cxx

@@ -36,7 +36,7 @@ std::string cmRulePlaceholderExpander::ExpandVariable(
         // Add launcher as part of expansion so that it always appears
         // immediately before the command itself, regardless of whether the
         // overall rule template contains other content at the front.
-        result = cmStrCat(this->ReplaceValues->Launcher, " ", result);
+        result = cmStrCat(this->ReplaceValues->Launcher, ' ', result);
       }
       return result;
     }
@@ -317,7 +317,7 @@ std::string cmRulePlaceholderExpander::ExpandVariable(
       // Add launcher as part of expansion so that it always appears
       // immediately before the command itself, regardless of whether the
       // overall rule template contains other content at the front.
-      ret = cmStrCat(this->ReplaceValues->Launcher, " ", ret);
+      ret = cmStrCat(this->ReplaceValues->Launcher, ' ', ret);
     }
 
     // if there are required arguments to the compiler add it

+ 1 - 1
Source/cmSetPropertyCommand.cxx

@@ -799,7 +799,7 @@ bool HandleCacheMode(cmExecutionStatus& status,
   } else if (propertyName == "TYPE") {
     if (!cmState::IsCacheEntryType(propertyValue)) {
       status.SetError(
-        cmStrCat("given invalid CACHE entry TYPE \"", propertyValue, "\""));
+        cmStrCat("given invalid CACHE entry TYPE \"", propertyValue, '"'));
       return false;
     }
   } else if (propertyName != "HELPSTRING" && propertyName != "STRINGS" &&

+ 1 - 1
Source/cmStringCommand.cxx

@@ -171,7 +171,7 @@ bool HandleConfigureCommand(std::vector<std::string> const& args,
     } else if (args[i] == "ESCAPE_QUOTES") {
       escapeQuotes = true;
     } else {
-      status.SetError(cmStrCat("Unrecognized argument \"", args[i], "\""));
+      status.SetError(cmStrCat("Unrecognized argument \"", args[i], '"'));
       return false;
     }
   }

+ 1 - 1
Source/cmSystemTools.cxx

@@ -1075,7 +1075,7 @@ std::string cmSystemTools::FileExistsInParentDirectories(
   cmSystemTools::ConvertToUnixSlashes(dir);
   std::string prevDir;
   while (dir != prevDir) {
-    std::string path = cmStrCat(dir, "/", file);
+    std::string path = cmStrCat(dir, '/', file);
     if (cmSystemTools::FileExists(path)) {
       return path;
     }

+ 5 - 7
Source/cmTarget.cxx

@@ -730,8 +730,7 @@ bool FileSetType::WriteProperties(cmTarget* tgt, cmTargetInternals* impl,
     } else {
       impl->AddDirectoryToFileSet(
         tgt, fileSetName, value, this->TypeName,
-        cmStrCat(this->ArbitraryDescription, " \"", fileSetName, "\""),
-        action);
+        cmStrCat(this->ArbitraryDescription, " \"", fileSetName, '"'), action);
     }
     return true;
   }
@@ -744,8 +743,7 @@ bool FileSetType::WriteProperties(cmTarget* tgt, cmTargetInternals* impl,
     } else {
       impl->AddPathToFileSet(
         tgt, fileSetName, value, this->TypeName,
-        cmStrCat(this->ArbitraryDescription, " \"", fileSetName, "\""),
-        action);
+        cmStrCat(this->ArbitraryDescription, " \"", fileSetName, '"'), action);
     }
     return true;
   }
@@ -2141,7 +2139,7 @@ void cmTarget::SetProperty(std::string const& prop, cmValue value)
       this->impl->Properties.SetProperty(prop, value);
     } else {
       auto e = cmStrCat(prop, " property is not supported by ", compiler,
-                        "  compiler version ", compilerVersion, ".");
+                        "  compiler version ", compilerVersion, '.');
       this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e);
       return;
     }
@@ -3095,11 +3093,11 @@ std::string cmTarget::ImportedGetFullPath(
         }
 
         if (!config.empty()) {
-          configuration = cmStrCat(" configuration \"", config, "\"");
+          configuration = cmStrCat(" configuration \"", config, '"');
         }
 
         return cmStrCat(unset, " not set for imported target \"",
-                        this->GetName(), "\"", configuration, ".");
+                        this->GetName(), '"', configuration, '.');
       };
 
       switch (this->GetPolicyStatus(cmPolicies::CMP0111)) {

+ 1 - 1
Source/cmTargetLinkLibrariesCommand.cxx

@@ -429,7 +429,7 @@ bool TLL::HandleLibrary(ProcessingState currentProcessingState,
           "Target \"", lib, "\" of type ",
           cmState::GetTargetTypeName(tgt->GetType()),
           " may not be linked into another target. One may link only to "
-          "INTERFACE, OBJECT, STATIC or SHARED libraries, or to ",
+          "INTERFACE, OBJECT, STATIC or SHARED libraries, or to "
           "executables with the ENABLE_EXPORTS property set."));
     }
 

+ 3 - 3
Source/cmTargetSourcesCommand.cxx

@@ -213,7 +213,7 @@ bool TargetSourcesImpl::HandleOneFileSet(
 
   if (!unparsed.empty()) {
     this->SetError(
-      cmStrCat("Unrecognized keyword: \"", unparsed.front(), "\""));
+      cmStrCat("Unrecognized keyword: \"", unparsed.front(), '"'));
     return false;
   }
 
@@ -289,7 +289,7 @@ bool TargetSourcesImpl::HandleOneFileSet(
     if (!args.Type.empty() && args.Type != type) {
       this->SetError(cmStrCat(
         "Type \"", args.Type, "\" for file set \"", fileSet.first->GetName(),
-        "\" does not match original type \"", type, "\""));
+        "\" does not match original type \"", type, '"'));
       return false;
     }
 
@@ -317,7 +317,7 @@ bool TargetSourcesImpl::HandleOneFileSet(
     if (type == "HEADERS"_s) {
       for (auto const& dir : cmList{ baseDirectories }) {
         auto interfaceDirectoriesGenex =
-          cmStrCat("$<BUILD_INTERFACE:", dir, ">");
+          cmStrCat("$<BUILD_INTERFACE:", dir, '>');
         if (cmFileSetVisibilityIsForSelf(visibility)) {
           this->Target->AppendProperty("INCLUDE_DIRECTORIES",
                                        interfaceDirectoriesGenex,

+ 1 - 1
Source/cmTryRunCommand.cxx

@@ -176,7 +176,7 @@ bool TryRunCommandImpl::TryRunCode(std::vector<std::string> const& argv)
     } else {
       std::string runArgs;
       if (arguments.RunArgs) {
-        runArgs = cmStrCat(" ", cmJoin(*arguments.RunArgs, " "));
+        runArgs = cmStrCat(' ', cmJoin(*arguments.RunArgs, " "));
       }
 
       // "run" it and capture the output

+ 1 - 1
Source/cmVisualStudio10TargetGenerator.cxx

@@ -3450,7 +3450,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
       if (configName == this->Configurations[0]) {
         std::string message =
           cmStrCat("For the target \"", this->GeneratorTarget->GetName(),
-                   "\" the /clr compiler flag was added manually. ",
+                   "\" the /clr compiler flag was added manually. "
                    "Set usage of C++/CLI by setting COMMON_LANGUAGE_RUNTIME "
                    "target property.");
         this->Makefile->IssueMessage(MessageType::WARNING, message);

+ 42 - 29
Source/cmake.cxx

@@ -1468,7 +1468,7 @@ void cmake::SetArgs(std::vector<std::string> const& args)
   if (!extraProvidedPath.empty() && this->GetWorkingMode() == NORMAL_MODE) {
     this->IssueMessage(MessageType::WARNING,
                        cmStrCat("Ignoring extra path from command line:\n \"",
-                                extraProvidedPath, "\""));
+                                extraProvidedPath, '"'));
   }
   if (!possibleUnknownArg.empty() && this->GetWorkingMode() != SCRIPT_MODE) {
     cmSystemTools::Error(cmStrCat("Unknown argument ", possibleUnknownArg));
@@ -1591,7 +1591,7 @@ void cmake::SetArgs(std::vector<std::string> const& args)
     }
     if (!expandedPreset->ConditionResult) {
       cmSystemTools::Error(cmStrCat("Could not use disabled preset \"",
-                                    preset->second.Unexpanded.Name, "\""));
+                                    preset->second.Unexpanded.Name, '"'));
       return;
     }
 
@@ -2121,9 +2121,9 @@ void cmake::SetHomeDirectoryViaCommandLine(std::string const& path)
   auto prev_path = this->GetHomeDirectory();
   if (prev_path != path && !prev_path.empty() &&
       this->GetWorkingMode() == NORMAL_MODE) {
-    this->IssueMessage(MessageType::WARNING,
-                       cmStrCat("Ignoring extra path from command line:\n \"",
-                                prev_path, "\""));
+    this->IssueMessage(
+      MessageType::WARNING,
+      cmStrCat("Ignoring extra path from command line:\n \"", prev_path, '"'));
   }
   this->SetHomeDirectory(path);
 }
@@ -2224,7 +2224,7 @@ int cmake::DoPreConfigureChecks()
 {
   // Make sure the Source directory contains a CMakeLists.txt file.
   std::string srcList =
-    cmStrCat(this->GetHomeDirectory(), "/", this->CMakeListName);
+    cmStrCat(this->GetHomeDirectory(), '/', this->CMakeListName);
   if (!cmSystemTools::FileExists(srcList)) {
     std::ostringstream err;
     if (cmSystemTools::FileIsDirectory(this->GetHomeDirectory())) {
@@ -2511,11 +2511,14 @@ int cmake::ActualConfigure()
   cmValue genName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR");
   if (genName) {
     if (!this->GlobalGenerator->MatchesGeneratorName(*genName)) {
-      std::string message = cmStrCat(
-        "Error: generator : ", this->GlobalGenerator->GetName(), '\n',
-        "Does not match the generator used previously: ", *genName, '\n',
-        "Either remove the CMakeCache.txt file and CMakeFiles "
-        "directory or choose a different binary directory.");
+      std::string message =
+        cmStrCat("Error: generator : ", this->GlobalGenerator->GetName(),
+                 "\n"
+                 "Does not match the generator used previously: ",
+                 *genName,
+                 "\n"
+                 "Either remove the CMakeCache.txt file and CMakeFiles "
+                 "directory or choose a different binary directory.");
       cmSystemTools::Error(message);
       return -2;
     }
@@ -2541,11 +2544,14 @@ int cmake::ActualConfigure()
   if (cmValue instance =
         this->State->GetInitializedCacheValue("CMAKE_GENERATOR_INSTANCE")) {
     if (this->GeneratorInstanceSet && this->GeneratorInstance != *instance) {
-      std::string message = cmStrCat(
-        "Error: generator instance: ", this->GeneratorInstance, '\n',
-        "Does not match the instance used previously: ", *instance, '\n',
-        "Either remove the CMakeCache.txt file and CMakeFiles "
-        "directory or choose a different binary directory.");
+      std::string message =
+        cmStrCat("Error: generator instance: ", this->GeneratorInstance,
+                 "\n"
+                 "Does not match the instance used previously: ",
+                 *instance,
+                 "\n"
+                 "Either remove the CMakeCache.txt file and CMakeFiles "
+                 "directory or choose a different binary directory.");
       cmSystemTools::Error(message);
       return -2;
     }
@@ -2559,11 +2565,14 @@ int cmake::ActualConfigure()
         this->State->GetInitializedCacheValue("CMAKE_GENERATOR_PLATFORM")) {
     if (this->GeneratorPlatformSet &&
         this->GeneratorPlatform != *platformName) {
-      std::string message = cmStrCat(
-        "Error: generator platform: ", this->GeneratorPlatform, '\n',
-        "Does not match the platform used previously: ", *platformName, '\n',
-        "Either remove the CMakeCache.txt file and CMakeFiles "
-        "directory or choose a different binary directory.");
+      std::string message =
+        cmStrCat("Error: generator platform: ", this->GeneratorPlatform,
+                 "\n"
+                 "Does not match the platform used previously: ",
+                 *platformName,
+                 "\n"
+                 "Either remove the CMakeCache.txt file and CMakeFiles "
+                 "directory or choose a different binary directory.");
       cmSystemTools::Error(message);
       return -2;
     }
@@ -2576,8 +2585,11 @@ int cmake::ActualConfigure()
         this->State->GetInitializedCacheValue("CMAKE_GENERATOR_TOOLSET")) {
     if (this->GeneratorToolsetSet && this->GeneratorToolset != *tsName) {
       std::string message =
-        cmStrCat("Error: generator toolset: ", this->GeneratorToolset, '\n',
-                 "Does not match the toolset used previously: ", *tsName, '\n',
+        cmStrCat("Error: generator toolset: ", this->GeneratorToolset,
+                 "\n"
+                 "Does not match the toolset used previously: ",
+                 *tsName,
+                 "\n"
                  "Either remove the CMakeCache.txt file and CMakeFiles "
                  "directory or choose a different binary directory.");
       cmSystemTools::Error(message);
@@ -2692,12 +2704,12 @@ int cmake::ActualConfigure()
   if (this->Instrumentation->HasQuery()) {
     std::string launcher;
     if (mf->IsOn("CTEST_USE_LAUNCHERS")) {
-      launcher =
-        cmStrCat("\"", cmSystemTools::GetCTestCommand(), "\" --launch ",
-                 "--current-build-dir <CMAKE_CURRENT_BINARY_DIR> ");
+      launcher = cmStrCat('"', cmSystemTools::GetCTestCommand(),
+                          "\" --launch "
+                          "--current-build-dir <CMAKE_CURRENT_BINARY_DIR> ");
     } else {
       launcher =
-        cmStrCat("\"", cmSystemTools::GetCTestCommand(), "\" --instrument ");
+        cmStrCat('"', cmSystemTools::GetCTestCommand(), "\" --instrument ");
     }
     std::string common_args =
       cmStrCat(" --target-name <TARGET_NAME> --build-dir \"",
@@ -2705,13 +2717,14 @@ int cmake::ActualConfigure()
     this->State->SetGlobalProperty(
       "RULE_LAUNCH_COMPILE",
       cmStrCat(
-        launcher, "--command-type compile", common_args, "--config <CONFIG> ",
+        launcher, "--command-type compile", common_args,
+        "--config <CONFIG> "
         "--output <OBJECT> --source <SOURCE> --language <LANGUAGE> -- "));
     this->State->SetGlobalProperty(
       "RULE_LAUNCH_LINK",
       cmStrCat(
         launcher, "--command-type link", common_args,
-        "--output <TARGET> --target-type <TARGET_TYPE> --config <CONFIG> ",
+        "--output <TARGET> --target-type <TARGET_TYPE> --config <CONFIG> "
         "--language <LANGUAGE> --target-labels \"<TARGET_LABELS>\" -- "));
     this->State->SetGlobalProperty(
       "RULE_LAUNCH_CUSTOM",

+ 1 - 1
Tests/CMakeLib/testStringAlgorithms.cxx

@@ -142,7 +142,7 @@ int testStringAlgorithms(int /*unused*/, char* /*unused*/[])
     long long int nlli = -130000ll;
     unsigned long long int nulli = 130000ull;
     std::string val =
-      cmStrCat("<test>", ni, ',', nui, ',', nli, ",", nuli, ", ", nlli,
+      cmStrCat("<test>", ni, ',', nui, ',', nli, ',', nuli, ", ", nlli,
                std::string(", "), nulli, cm::string_view("</test>"));
     std::string expect =
       "<test>-1100,1100,-12000,12000, -130000, 130000</test>";

+ 312 - 0
Utilities/ast-grep/rule-tests/__snapshots__/cmstrcat-adjacent-literals-snapshot.yml

@@ -0,0 +1,312 @@
+id: cmstrcat-adjacent-literals
+snapshots:
+  cmStrCat("literal", "literal"):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 9
+      end: 18
+    - source: cmStrCat("literal", "literal")
+      style: secondary
+      start: 0
+      end: 30
+    - source: ','
+      style: secondary
+      start: 18
+      end: 19
+    - source: '"literal"'
+      style: secondary
+      start: 20
+      end: 29
+  cmStrCat("literal", "literal", "literal"):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 9
+      end: 18
+    - source: cmStrCat("literal", "literal", "literal")
+      style: secondary
+      start: 0
+      end: 41
+    - source: ','
+      style: secondary
+      start: 18
+      end: 19
+    - source: '"literal"'
+      style: secondary
+      start: 20
+      end: 29
+  cmStrCat("literal", "literal", "literal", variable):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 9
+      end: 18
+    - source: cmStrCat("literal", "literal", "literal", variable)
+      style: secondary
+      start: 0
+      end: 51
+    - source: '"literal"'
+      style: secondary
+      start: 20
+      end: 29
+  cmStrCat("literal", "literal", variable):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 9
+      end: 18
+    - source: cmStrCat("literal", "literal", variable)
+      style: secondary
+      start: 0
+      end: 40
+    - source: ','
+      style: secondary
+      start: 18
+      end: 19
+    - source: '"literal"'
+      style: secondary
+      start: 20
+      end: 29
+  cmStrCat(variable, "literal", "literal" "literal"):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 19
+      end: 28
+    - source: cmStrCat(variable, "literal", "literal" "literal")
+      style: secondary
+      start: 0
+      end: 50
+    - source: ','
+      style: secondary
+      start: 28
+      end: 29
+    - source: '"literal" "literal"'
+      style: secondary
+      start: 30
+      end: 49
+  cmStrCat(variable, "literal", "literal"):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 19
+      end: 28
+    - source: cmStrCat(variable, "literal", "literal")
+      style: secondary
+      start: 0
+      end: 40
+    - source: ','
+      style: secondary
+      start: 28
+      end: 29
+    - source: '"literal"'
+      style: secondary
+      start: 30
+      end: 39
+  cmStrCat(variable, "literal", "literal", "literal"):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 19
+      end: 28
+    - source: cmStrCat(variable, "literal", "literal", "literal")
+      style: secondary
+      start: 0
+      end: 51
+    - source: ','
+      style: secondary
+      start: 28
+      end: 29
+    - source: '"literal"'
+      style: secondary
+      start: 30
+      end: 39
+  cmStrCat(variable, "literal", "literal", "literal", variable, "literal"):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 19
+      end: 28
+    - source: cmStrCat(variable, "literal", "literal", "literal", variable, "literal")
+      style: secondary
+      start: 0
+      end: 72
+    - source: ','
+      style: secondary
+      start: 28
+      end: 29
+    - source: '"literal"'
+      style: secondary
+      start: 30
+      end: 39
+  cmStrCat(variable, "literal", "literal", variable):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 19
+      end: 28
+    - source: cmStrCat(variable, "literal", "literal", variable)
+      style: secondary
+      start: 0
+      end: 50
+    - source: ','
+      style: secondary
+      start: 28
+      end: 29
+    - source: '"literal"'
+      style: secondary
+      start: 30
+      end: 39
+  cmStrCat(variable, "literal", "string_view"_s, variable):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 19
+      end: 28
+    - source: cmStrCat(variable, "literal", "string_view"_s, variable)
+      style: secondary
+      start: 0
+      end: 56
+    - source: _s
+      style: secondary
+      start: 43
+      end: 45
+    - source: ','
+      style: secondary
+      start: 28
+      end: 29
+    - source: '"string_view"_s'
+      style: secondary
+      start: 30
+      end: 45
+  cmStrCat(variable, "literal", 'l', variable):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 19
+      end: 28
+    - source: cmStrCat(variable, "literal", 'l', variable)
+      style: secondary
+      start: 0
+      end: 44
+    - source: ','
+      style: secondary
+      start: 28
+      end: 29
+    - source: '''l'''
+      style: secondary
+      start: 30
+      end: 33
+  cmStrCat(variable, "literal", R"(raw_literal)", variable):
+    labels:
+    - source: '"literal"'
+      style: primary
+      start: 19
+      end: 28
+    - source: cmStrCat(variable, "literal", R"(raw_literal)", variable)
+      style: secondary
+      start: 0
+      end: 57
+    - source: ','
+      style: secondary
+      start: 28
+      end: 29
+    - source: R"(raw_literal)"
+      style: secondary
+      start: 30
+      end: 46
+  cmStrCat(variable, "string_view"_s, "literal", variable):
+    labels:
+    - source: '"string_view"_s'
+      style: primary
+      start: 19
+      end: 34
+    - source: _s
+      style: secondary
+      start: 32
+      end: 34
+    - source: cmStrCat(variable, "string_view"_s, "literal", variable)
+      style: secondary
+      start: 0
+      end: 56
+    - source: ','
+      style: secondary
+      start: 34
+      end: 35
+    - source: '"literal"'
+      style: secondary
+      start: 36
+      end: 45
+  cmStrCat(variable, 'c', "literal" "literal"):
+    labels:
+    - source: '''c'''
+      style: primary
+      start: 19
+      end: 22
+    - source: cmStrCat(variable, 'c', "literal" "literal")
+      style: secondary
+      start: 0
+      end: 44
+    - source: ','
+      style: secondary
+      start: 22
+      end: 23
+    - source: '"literal" "literal"'
+      style: secondary
+      start: 24
+      end: 43
+  cmStrCat(variable, 'c', "literal", variable):
+    labels:
+    - source: '''c'''
+      style: primary
+      start: 19
+      end: 22
+    - source: cmStrCat(variable, 'c', "literal", variable)
+      style: secondary
+      start: 0
+      end: 44
+    - source: ','
+      style: secondary
+      start: 22
+      end: 23
+    - source: '"literal"'
+      style: secondary
+      start: 24
+      end: 33
+  cmStrCat(variable, 'c', 'l', variable):
+    labels:
+    - source: '''c'''
+      style: primary
+      start: 19
+      end: 22
+    - source: cmStrCat(variable, 'c', 'l', variable)
+      style: secondary
+      start: 0
+      end: 38
+    - source: ','
+      style: secondary
+      start: 22
+      end: 23
+    - source: '''l'''
+      style: secondary
+      start: 24
+      end: 27
+  cmStrCat(variable, R"(raw_literal)", "literal", variable):
+    labels:
+    - source: R"(raw_literal)"
+      style: primary
+      start: 19
+      end: 35
+    - source: cmStrCat(variable, R"(raw_literal)", "literal", variable)
+      style: secondary
+      start: 0
+      end: 57
+    - source: ','
+      style: secondary
+      start: 35
+      end: 36
+    - source: '"literal"'
+      style: secondary
+      start: 37
+      end: 46

+ 342 - 0
Utilities/ast-grep/rule-tests/__snapshots__/cmstrcat-to-char-literal-snapshot.yml

@@ -0,0 +1,342 @@
+id: cmstrcat-to-char-literal
+snapshots:
+  cmStrCat("'"):
+    fixed: cmStrCat('\'')
+    labels:
+    - source: '"''"'
+      style: primary
+      start: 9
+      end: 12
+    - source: cmStrCat("'")
+      style: secondary
+      start: 0
+      end: 13
+  cmStrCat("'", other):
+    fixed: cmStrCat('\'', other)
+    labels:
+    - source: '"''"'
+      style: primary
+      start: 9
+      end: 12
+    - source: cmStrCat("'", other)
+      style: secondary
+      start: 0
+      end: 20
+    - source: ','
+      style: secondary
+      start: 12
+      end: 13
+    - source: (
+      style: secondary
+      start: 8
+      end: 9
+  cmStrCat("\""):
+    fixed: cmStrCat('"')
+    labels:
+    - source: '"\""'
+      style: primary
+      start: 9
+      end: 13
+    - source: cmStrCat("\"")
+      style: secondary
+      start: 0
+      end: 14
+  cmStrCat("\"", other):
+    fixed: cmStrCat('"', other)
+    labels:
+    - source: '"\""'
+      style: primary
+      start: 9
+      end: 13
+    - source: cmStrCat("\"", other)
+      style: secondary
+      start: 0
+      end: 21
+    - source: ','
+      style: secondary
+      start: 13
+      end: 14
+    - source: (
+      style: secondary
+      start: 8
+      end: 9
+  cmStrCat("\'"):
+    fixed: cmStrCat('\'')
+    labels:
+    - source: '"\''"'
+      style: primary
+      start: 9
+      end: 13
+    - source: cmStrCat("\'")
+      style: secondary
+      start: 0
+      end: 14
+  cmStrCat("\'", other):
+    fixed: cmStrCat('\'', other)
+    labels:
+    - source: '"\''"'
+      style: primary
+      start: 9
+      end: 13
+    - source: cmStrCat("\'", other)
+      style: secondary
+      start: 0
+      end: 21
+    - source: ','
+      style: secondary
+      start: 13
+      end: 14
+    - source: (
+      style: secondary
+      start: 8
+      end: 9
+  cmStrCat("\n"):
+    fixed: cmStrCat('\n')
+    labels:
+    - source: '"\n"'
+      style: primary
+      start: 9
+      end: 13
+    - source: cmStrCat("\n")
+      style: secondary
+      start: 0
+      end: 14
+  cmStrCat("\n", other):
+    fixed: cmStrCat('\n', other)
+    labels:
+    - source: '"\n"'
+      style: primary
+      start: 9
+      end: 13
+    - source: cmStrCat("\n", other)
+      style: secondary
+      start: 0
+      end: 21
+    - source: ','
+      style: secondary
+      start: 13
+      end: 14
+    - source: (
+      style: secondary
+      start: 8
+      end: 9
+  cmStrCat("n"):
+    fixed: cmStrCat('n')
+    labels:
+    - source: '"n"'
+      style: primary
+      start: 9
+      end: 12
+    - source: cmStrCat("n")
+      style: secondary
+      start: 0
+      end: 13
+  cmStrCat("n", other):
+    fixed: cmStrCat('n', other)
+    labels:
+    - source: '"n"'
+      style: primary
+      start: 9
+      end: 12
+    - source: cmStrCat("n", other)
+      style: secondary
+      start: 0
+      end: 20
+    - source: ','
+      style: secondary
+      start: 12
+      end: 13
+    - source: (
+      style: secondary
+      start: 8
+      end: 9
+  cmStrCat(other, "'"):
+    fixed: cmStrCat(other, '\'')
+    labels:
+    - source: '"''"'
+      style: primary
+      start: 16
+      end: 19
+    - source: cmStrCat(other, "'")
+      style: secondary
+      start: 0
+      end: 20
+    - source: )
+      style: secondary
+      start: 19
+      end: 20
+    - source: ','
+      style: secondary
+      start: 14
+      end: 15
+  cmStrCat(other, "'", other):
+    fixed: cmStrCat(other, '\'', other)
+    labels:
+    - source: '"''"'
+      style: primary
+      start: 16
+      end: 19
+    - source: cmStrCat(other, "'", other)
+      style: secondary
+      start: 0
+      end: 27
+    - source: ','
+      style: secondary
+      start: 19
+      end: 20
+    - source: ','
+      style: secondary
+      start: 14
+      end: 15
+  cmStrCat(other, "\""):
+    fixed: cmStrCat(other, '"')
+    labels:
+    - source: '"\""'
+      style: primary
+      start: 16
+      end: 20
+    - source: cmStrCat(other, "\"")
+      style: secondary
+      start: 0
+      end: 21
+    - source: )
+      style: secondary
+      start: 20
+      end: 21
+    - source: ','
+      style: secondary
+      start: 14
+      end: 15
+  cmStrCat(other, "\"", other):
+    fixed: cmStrCat(other, '"', other)
+    labels:
+    - source: '"\""'
+      style: primary
+      start: 16
+      end: 20
+    - source: cmStrCat(other, "\"", other)
+      style: secondary
+      start: 0
+      end: 28
+    - source: ','
+      style: secondary
+      start: 20
+      end: 21
+    - source: ','
+      style: secondary
+      start: 14
+      end: 15
+  cmStrCat(other, "\'"):
+    fixed: cmStrCat(other, '\'')
+    labels:
+    - source: '"\''"'
+      style: primary
+      start: 16
+      end: 20
+    - source: cmStrCat(other, "\'")
+      style: secondary
+      start: 0
+      end: 21
+    - source: )
+      style: secondary
+      start: 20
+      end: 21
+    - source: ','
+      style: secondary
+      start: 14
+      end: 15
+  cmStrCat(other, "\'", other):
+    fixed: cmStrCat(other, '\'', other)
+    labels:
+    - source: '"\''"'
+      style: primary
+      start: 16
+      end: 20
+    - source: cmStrCat(other, "\'", other)
+      style: secondary
+      start: 0
+      end: 28
+    - source: ','
+      style: secondary
+      start: 20
+      end: 21
+    - source: ','
+      style: secondary
+      start: 14
+      end: 15
+  cmStrCat(other, "\n"):
+    fixed: cmStrCat(other, '\n')
+    labels:
+    - source: '"\n"'
+      style: primary
+      start: 16
+      end: 20
+    - source: cmStrCat(other, "\n")
+      style: secondary
+      start: 0
+      end: 21
+    - source: )
+      style: secondary
+      start: 20
+      end: 21
+    - source: ','
+      style: secondary
+      start: 14
+      end: 15
+  cmStrCat(other, "\n", other):
+    fixed: cmStrCat(other, '\n', other)
+    labels:
+    - source: '"\n"'
+      style: primary
+      start: 16
+      end: 20
+    - source: cmStrCat(other, "\n", other)
+      style: secondary
+      start: 0
+      end: 28
+    - source: ','
+      style: secondary
+      start: 20
+      end: 21
+    - source: ','
+      style: secondary
+      start: 14
+      end: 15
+  cmStrCat(other, "n"):
+    fixed: cmStrCat(other, 'n')
+    labels:
+    - source: '"n"'
+      style: primary
+      start: 16
+      end: 19
+    - source: cmStrCat(other, "n")
+      style: secondary
+      start: 0
+      end: 20
+    - source: )
+      style: secondary
+      start: 19
+      end: 20
+    - source: ','
+      style: secondary
+      start: 14
+      end: 15
+  cmStrCat(other, "n", other):
+    fixed: cmStrCat(other, 'n', other)
+    labels:
+    - source: '"n"'
+      style: primary
+      start: 16
+      end: 19
+    - source: cmStrCat(other, "n", other)
+      style: secondary
+      start: 0
+      end: 27
+    - source: ','
+      style: secondary
+      start: 19
+      end: 20
+    - source: ','
+      style: secondary
+      start: 14
+      end: 15

+ 39 - 0
Utilities/ast-grep/rule-tests/cmstrcat-adjacent-literals-test.yml

@@ -0,0 +1,39 @@
+---
+id: cmstrcat-adjacent-literals
+valid:
+  - 'cmStrCat("literal", variable)'
+  - 'cmStrCat(variable, "literal")'
+  - 'cmStrCat(variable, "literal", variable)'
+  - 'cmStrCat(variable, variable, "literal")'
+  - 'cmStrCat("literal", variable, variable)'
+  - 'cmStrCat(variable, "literal", variable)'
+  - 'cmStrCat("literal", binary + expr, "literal")'
+  - 'cmStrCat("literal", cond ? t : f, "literal")'
+  - 'cmStrCat("literal", field.expr, "literal")'
+  - 'cmStrCat("literal", identifier, "literal")'
+  - 'cmStrCat("literal", [lambda](){}, "literal")'
+  - 'cmStrCat("literal", 4, "literal")'
+  - 'cmStrCat("literal", (parens), "literal")'
+  - 'cmStrCat("literal", *ptr_expr, "literal")'
+  - 'cmStrCat("literal", qualified::ident, "literal")'
+  - 'cmStrCat("literal", subscript[expr], "literal")'
+  - 'cmStrCat("literal", +unary_expr, "literal")'
+  - 'cmStrCat("literal", ++update, "literal")'
+  - 'cmStrCat("literal", "udl"_unit, "literal")'
+invalid:
+  - 'cmStrCat("literal", "literal")'
+  - 'cmStrCat("literal", "literal", "literal")'
+  - 'cmStrCat("literal", "literal", variable)'
+  - 'cmStrCat(variable, "literal", "literal")'
+  - 'cmStrCat(variable, "literal", "literal", "literal")'
+  - 'cmStrCat(variable, "literal", "literal", "literal", variable, "literal")'
+  - 'cmStrCat(variable, "literal", "literal", variable)'
+  - "cmStrCat(variable, \"literal\", 'l', variable)"
+  - "cmStrCat(variable, 'c', 'l', variable)"
+  - "cmStrCat(variable, 'c', \"literal\", variable)"
+  - "cmStrCat(variable, 'c', \"literal\" \"literal\")"
+  - 'cmStrCat(variable, "literal", "literal" "literal")'
+  - 'cmStrCat(variable, "literal", R"(raw_literal)", variable)'
+  - 'cmStrCat(variable, R"(raw_literal)", "literal", variable)'
+  - 'cmStrCat(variable, "literal", "string_view"_s, variable)'
+  - 'cmStrCat(variable, "string_view"_s, "literal", variable)'

+ 24 - 0
Utilities/ast-grep/rule-tests/cmstrcat-to-char-literal-test.yml

@@ -0,0 +1,24 @@
+---
+id: cmstrcat-to-char-literal
+valid:
+  - 'cmStrCat(other, "li")'
+  - 'cmStrCat(other, variable)'
+  - "cmStrCat(other, 'c')"
+  - "cmStrCat(other, '\\n')"
+  - "cmStrCat(other, \"a\" \"b\")"
+invalid:
+  - 'cmStrCat(other, "\n")'
+  - 'cmStrCat(other, "n")'
+  - 'cmStrCat(other, "\"")'
+  - "cmStrCat(other, \"\\'\")"
+  - "cmStrCat(other, \"'\")"
+  - 'cmStrCat("\n", other)'
+  - 'cmStrCat("n", other)'
+  - 'cmStrCat("\"", other)'
+  - "cmStrCat(\"\\'\", other)"
+  - "cmStrCat(\"'\", other)"
+  - 'cmStrCat(other, "\n", other)'
+  - 'cmStrCat(other, "n", other)'
+  - 'cmStrCat(other, "\"", other)'
+  - "cmStrCat(other, \"\\'\", other)"
+  - "cmStrCat(other, \"'\", other)"

+ 19 - 0
Utilities/ast-grep/rules/cmstrcat-adjacent-literals.yml

@@ -0,0 +1,19 @@
+---
+id: cmstrcat-adjacent-literals
+language: Cpp
+severity: warning
+message: Adjacent `cmStrCat` arguments which are string literals should be combined
+ignores:
+  - Utilities/ClangTidyModule/Tests/**
+rule:
+  matches: string-literal
+  inside:
+    matches: cmstrcat-call
+    stopBy:
+      kind: call_expression
+  precedes:
+    matches: string-literal
+    follows:
+      pattern: ','
+    stopBy:
+      matches: cmstrcat-arg

+ 36 - 0
Utilities/ast-grep/rules/cmstrcat-to-char-literal.yaml

@@ -0,0 +1,36 @@
+---
+id: cmstrcat-to-char-literal
+language: Cpp
+severity: warning
+message: "`cmStrCat` string literal arguments which can be char literals should be"
+rule:
+  kind: string_literal
+  pattern: $ARG
+  follows:
+    regex: '(,|[(])'
+  precedes:
+    regex: '(,|[)])'
+  inside:
+    matches: cmstrcat-call
+    stopBy:
+      kind: call_expression
+constraints:
+  ARG:
+    regex: '^"(.|\\.)"$'
+transform:
+  ARG_CHANGE_QUOTE:
+    replace:
+      source: $ARG
+      replace: '(^"|"$)'
+      by: "'"
+  ARG_ESCAPE_SINGLE_QUOTE:
+    replace:
+      source: $ARG_CHANGE_QUOTE
+      replace: "'''"
+      by: "'\\''"
+  ARG_OUT:
+    replace:
+      source: $ARG_ESCAPE_SINGLE_QUOTE
+      replace: '\\"'
+      by: '"'
+fix: $ARG_OUT

+ 23 - 0
Utilities/ast-grep/utils/cmstrcat-arg.yml

@@ -0,0 +1,23 @@
+---
+id: cmstrcat-arg
+language: Cpp
+rule:
+  any:
+    - kind: binary_expression
+    - kind: call_expression
+    - kind: char_literal
+    - kind: concatenated_string
+    - kind: conditional_expression
+    - kind: field_expression
+    - kind: identifier
+    - kind: lambda_expression
+    - kind: number_literal
+    - kind: parenthesized_expression
+    - kind: pointer_expression
+    - kind: qualified_identifier
+    - kind: raw_string_literal
+    - kind: string_literal
+    - kind: subscript_expression
+    - kind: unary_expression
+    - kind: update_expression
+    - kind: user_defined_literal

+ 5 - 0
Utilities/ast-grep/utils/cmstrcat-call.yml

@@ -0,0 +1,5 @@
+---
+id: cmstrcat-call
+language: Cpp
+rule:
+  pattern: cmStrCat($$$)

+ 13 - 0
Utilities/ast-grep/utils/string-literal.yml

@@ -0,0 +1,13 @@
+---
+id: string-literal
+language: Cpp
+rule:
+  any:
+    - kind: char_literal
+    - kind: concatenated_string
+    - kind: raw_string_literal
+    - kind: string_literal
+    - kind: user_defined_literal
+      has:
+        kind: literal_suffix
+        regex: '^_s$'

+ 6 - 0
sgconfig.yml

@@ -0,0 +1,6 @@
+ruleDirs:
+- Utilities/ast-grep/rules
+testConfigs:
+- testDir: Utilities/ast-grep/rule-tests
+utilDirs:
+- Utilities/ast-grep/utils