From e6a27adf9f1a17f13c5af888f778fde4cddebfac Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Thu, 25 Jul 2019 16:40:33 +0200
Subject: cmCommand refactor: cmBreakCommand

---
 Source/cmBreakCommand.cxx | 14 +++++++-------
 Source/cmBreakCommand.h   | 26 +++-----------------------
 Source/cmCommands.cxx     |  2 +-
 3 files changed, 11 insertions(+), 31 deletions(-)

diff --git a/Source/cmBreakCommand.cxx b/Source/cmBreakCommand.cxx
index d07898f..95db689 100644
--- a/Source/cmBreakCommand.cxx
+++ b/Source/cmBreakCommand.cxx
@@ -10,14 +10,14 @@
 #include "cmPolicies.h"
 
 // cmBreakCommand
-bool cmBreakCommand::InitialPass(std::vector<std::string> const& args,
-                                 cmExecutionStatus& status)
+bool cmBreakCommand(std::vector<std::string> const& args,
+                    cmExecutionStatus& status)
 {
-  if (!this->Makefile->IsLoopBlock()) {
+  if (!status.GetMakefile().IsLoopBlock()) {
     bool issueMessage = true;
     std::ostringstream e;
     MessageType messageType = MessageType::AUTHOR_WARNING;
-    switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0055)) {
+    switch (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0055)) {
       case cmPolicies::WARN:
         e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0055) << "\n";
         break;
@@ -34,7 +34,7 @@ bool cmBreakCommand::InitialPass(std::vector<std::string> const& args,
     if (issueMessage) {
       e << "A BREAK command was found outside of a proper "
            "FOREACH or WHILE loop scope.";
-      this->Makefile->IssueMessage(messageType, e.str());
+      status.GetMakefile().IssueMessage(messageType, e.str());
       if (messageType == MessageType::FATAL_ERROR) {
         return false;
       }
@@ -47,7 +47,7 @@ bool cmBreakCommand::InitialPass(std::vector<std::string> const& args,
     bool issueMessage = true;
     std::ostringstream e;
     MessageType messageType = MessageType::AUTHOR_WARNING;
-    switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0055)) {
+    switch (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0055)) {
       case cmPolicies::WARN:
         e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0055) << "\n";
         break;
@@ -63,7 +63,7 @@ bool cmBreakCommand::InitialPass(std::vector<std::string> const& args,
 
     if (issueMessage) {
       e << "The BREAK command does not accept any arguments.";
-      this->Makefile->IssueMessage(messageType, e.str());
+      status.GetMakefile().IssueMessage(messageType, e.str());
       if (messageType == MessageType::FATAL_ERROR) {
         return false;
       }
diff --git a/Source/cmBreakCommand.h b/Source/cmBreakCommand.h
index e6f218e..e6ce6fe 100644
--- a/Source/cmBreakCommand.h
+++ b/Source/cmBreakCommand.h
@@ -8,34 +8,14 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmBreakCommand
+/**
  * \brief Break from an enclosing foreach or while loop
  *
  * cmBreakCommand returns from an enclosing foreach or while loop
  */
-class cmBreakCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmBreakCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-};
+bool cmBreakCommand(std::vector<std::string> const& args,
+                    cmExecutionStatus& status);
 
 #endif
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 8565e1c..540f1ac 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -116,7 +116,7 @@
 
 void GetScriptingCommands(cmState* state)
 {
-  state->AddBuiltinCommand("break", cm::make_unique<cmBreakCommand>());
+  state->AddBuiltinCommand("break", cmBreakCommand);
   state->AddBuiltinCommand("cmake_minimum_required",
                            cm::make_unique<cmCMakeMinimumRequired>());
   state->AddBuiltinCommand("cmake_policy",
-- 
cgit v0.12


From dc629b5d97cd5486b2b0b385680a163e594922ae Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Thu, 25 Jul 2019 16:46:18 +0200
Subject: cmCommand refactor: cmCMakeMinimumRequired

---
 Source/cmCMakeMinimumRequired.cxx | 50 +++++++++++++++++++++++----------------
 Source/cmCMakeMinimumRequired.h   | 30 +++--------------------
 Source/cmCommands.cxx             |  3 +--
 3 files changed, 34 insertions(+), 49 deletions(-)

diff --git a/Source/cmCMakeMinimumRequired.cxx b/Source/cmCMakeMinimumRequired.cxx
index f2eae38..f93c266 100644
--- a/Source/cmCMakeMinimumRequired.cxx
+++ b/Source/cmCMakeMinimumRequired.cxx
@@ -5,26 +5,32 @@
 #include <sstream>
 #include <stdio.h>
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmSystemTools.h"
 #include "cmVersion.h"
 
-class cmExecutionStatus;
+namespace {
+bool EnforceUnknownArguments(std::string const& version_max,
+                             std::vector<std::string> const& unknown_arguments,
+                             cmExecutionStatus& status);
+}
 
 // cmCMakeMinimumRequired
-bool cmCMakeMinimumRequired::InitialPass(std::vector<std::string> const& args,
-                                         cmExecutionStatus&)
+bool cmCMakeMinimumRequired(std::vector<std::string> const& args,
+                            cmExecutionStatus& status)
 {
   // Process arguments.
   std::string version_string;
   bool doing_version = false;
+  std::vector<std::string> unknown_arguments;
   for (std::string const& arg : args) {
     if (arg == "VERSION") {
       doing_version = true;
     } else if (arg == "FATAL_ERROR") {
       if (doing_version) {
-        this->SetError("called with no value for VERSION.");
+        status.SetError("called with no value for VERSION.");
         return false;
       }
       doing_version = false;
@@ -32,17 +38,17 @@ bool cmCMakeMinimumRequired::InitialPass(std::vector<std::string> const& args,
       doing_version = false;
       version_string = arg;
     } else {
-      this->UnknownArguments.push_back(arg);
+      unknown_arguments.push_back(arg);
     }
   }
   if (doing_version) {
-    this->SetError("called with no value for VERSION.");
+    status.SetError("called with no value for VERSION.");
     return false;
   }
 
   // Make sure there was a version to check.
   if (version_string.empty()) {
-    return this->EnforceUnknownArguments(std::string());
+    return EnforceUnknownArguments(std::string(), unknown_arguments, status);
   }
 
   // Separate the <min> version and any trailing ...<max> component.
@@ -56,12 +62,13 @@ bool cmCMakeMinimumRequired::InitialPass(std::vector<std::string> const& args,
     std::ostringstream e;
     e << "VERSION \"" << version_string
       << R"(" does not have a version on both sides of "...".)";
-    this->SetError(e.str());
+    status.SetError(e.str());
     return false;
   }
 
   // Save the required version string.
-  this->Makefile->AddDefinition("CMAKE_MINIMUM_REQUIRED_VERSION", version_min);
+  status.GetMakefile().AddDefinition("CMAKE_MINIMUM_REQUIRED_VERSION",
+                                     version_min);
 
   // Get the current version number.
   unsigned int current_major = cmVersion::GetMajorVersion();
@@ -79,7 +86,7 @@ bool cmCMakeMinimumRequired::InitialPass(std::vector<std::string> const& args,
              &required_minor, &required_patch, &required_tweak) < 2) {
     std::ostringstream e;
     e << "could not parse VERSION \"" << version_min << "\".";
-    this->SetError(e.str());
+    status.SetError(e.str());
     return false;
   }
 
@@ -95,32 +102,34 @@ bool cmCMakeMinimumRequired::InitialPass(std::vector<std::string> const& args,
     e << "CMake " << version_min
       << " or higher is required.  You are running version "
       << cmVersion::GetCMakeVersion();
-    this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+    status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str());
     cmSystemTools::SetFatalErrorOccured();
     return true;
   }
 
   // The version is not from the future, so enforce unknown arguments.
-  if (!this->EnforceUnknownArguments(version_max)) {
+  if (!EnforceUnknownArguments(version_max, unknown_arguments, status)) {
     return false;
   }
 
   if (required_major < 2 || (required_major == 2 && required_minor < 4)) {
-    this->Makefile->IssueMessage(
+    status.GetMakefile().IssueMessage(
       MessageType::AUTHOR_WARNING,
       "Compatibility with CMake < 2.4 is not supported by CMake >= 3.0.");
-    this->Makefile->SetPolicyVersion("2.4", version_max);
+    status.GetMakefile().SetPolicyVersion("2.4", version_max);
   } else {
-    this->Makefile->SetPolicyVersion(version_min, version_max);
+    status.GetMakefile().SetPolicyVersion(version_min, version_max);
   }
 
   return true;
 }
 
-bool cmCMakeMinimumRequired::EnforceUnknownArguments(
-  std::string const& version_max)
+namespace {
+bool EnforceUnknownArguments(std::string const& version_max,
+                             std::vector<std::string> const& unknown_arguments,
+                             cmExecutionStatus& status)
 {
-  if (this->UnknownArguments.empty()) {
+  if (unknown_arguments.empty()) {
     return true;
   }
 
@@ -149,7 +158,8 @@ bool cmCMakeMinimumRequired::EnforceUnknownArguments(
   }
 
   std::ostringstream e;
-  e << "called with unknown argument \"" << this->UnknownArguments[0] << "\".";
-  this->SetError(e.str());
+  e << "called with unknown argument \"" << unknown_arguments[0] << "\".";
+  status.SetError(e.str());
   return false;
 }
+}
diff --git a/Source/cmCMakeMinimumRequired.h b/Source/cmCMakeMinimumRequired.h
index 3881133..53f78f6 100644
--- a/Source/cmCMakeMinimumRequired.h
+++ b/Source/cmCMakeMinimumRequired.h
@@ -8,38 +8,14 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmCMakeMinimumRequired
+/**
  * \brief cmake_minimum_required command
  *
  * cmCMakeMinimumRequired implements the cmake_minimum_required CMake command
  */
-class cmCMakeMinimumRequired : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmCMakeMinimumRequired>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-
-private:
-  std::vector<std::string> UnknownArguments;
-  bool EnforceUnknownArguments(std::string const& version_max);
-};
+bool cmCMakeMinimumRequired(std::vector<std::string> const& args,
+                            cmExecutionStatus& status);
 
 #endif
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 540f1ac..996ce97 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -117,8 +117,7 @@
 void GetScriptingCommands(cmState* state)
 {
   state->AddBuiltinCommand("break", cmBreakCommand);
-  state->AddBuiltinCommand("cmake_minimum_required",
-                           cm::make_unique<cmCMakeMinimumRequired>());
+  state->AddBuiltinCommand("cmake_minimum_required", cmCMakeMinimumRequired);
   state->AddBuiltinCommand("cmake_policy",
                            cm::make_unique<cmCMakePolicyCommand>());
   state->AddBuiltinCommand("configure_file",
-- 
cgit v0.12


From 01949a02df765cc4ad273b6163622f55d4f569ca Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Thu, 25 Jul 2019 16:49:35 +0200
Subject: cmCommand refactor: cmConfigureFileCommand

---
 Source/cmCommands.cxx             |  3 +-
 Source/cmConfigureFileCommand.cxx | 73 ++++++++++++++++++---------------------
 Source/cmConfigureFileCommand.h   | 34 ++----------------
 3 files changed, 37 insertions(+), 73 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 996ce97..3e7fa72 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -120,8 +120,7 @@ void GetScriptingCommands(cmState* state)
   state->AddBuiltinCommand("cmake_minimum_required", cmCMakeMinimumRequired);
   state->AddBuiltinCommand("cmake_policy",
                            cm::make_unique<cmCMakePolicyCommand>());
-  state->AddBuiltinCommand("configure_file",
-                           cm::make_unique<cmConfigureFileCommand>());
+  state->AddBuiltinCommand("configure_file", cmConfigureFileCommand);
   state->AddBuiltinCommand("continue", cm::make_unique<cmContinueCommand>());
   state->AddBuiltinCommand("exec_program",
                            cm::make_unique<cmExecProgramCommand>());
diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx
index 0917d11..701214e 100644
--- a/Source/cmConfigureFileCommand.cxx
+++ b/Source/cmConfigureFileCommand.cxx
@@ -4,76 +4,77 @@
 
 #include <sstream>
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
+#include "cmNewLineStyle.h"
 #include "cmSystemTools.h"
 
-class cmExecutionStatus;
-
 // cmConfigureFileCommand
-bool cmConfigureFileCommand::InitialPass(std::vector<std::string> const& args,
-                                         cmExecutionStatus&)
+bool cmConfigureFileCommand(std::vector<std::string> const& args,
+                            cmExecutionStatus& status)
 {
   if (args.size() < 2) {
-    this->SetError("called with incorrect number of arguments, expected 2");
+    status.SetError("called with incorrect number of arguments, expected 2");
     return false;
   }
 
   std::string const& inFile = args[0];
-  this->InputFile = cmSystemTools::CollapseFullPath(
-    inFile, this->Makefile->GetCurrentSourceDirectory());
+  const std::string inputFile = cmSystemTools::CollapseFullPath(
+    inFile, status.GetMakefile().GetCurrentSourceDirectory());
 
   // If the input location is a directory, error out.
-  if (cmSystemTools::FileIsDirectory(this->InputFile)) {
+  if (cmSystemTools::FileIsDirectory(inputFile)) {
     std::ostringstream e;
     /* clang-format off */
     e << "input location\n"
-      << "  " << this->InputFile << "\n"
+      << "  " << inputFile << "\n"
       << "is a directory but a file was expected.";
     /* clang-format on */
-    this->SetError(e.str());
+    status.SetError(e.str());
     return false;
   }
 
   std::string const& outFile = args[1];
-  this->OutputFile = cmSystemTools::CollapseFullPath(
-    outFile, this->Makefile->GetCurrentBinaryDirectory());
+  std::string outputFile = cmSystemTools::CollapseFullPath(
+    outFile, status.GetMakefile().GetCurrentBinaryDirectory());
 
   // If the output location is already a directory put the file in it.
-  if (cmSystemTools::FileIsDirectory(this->OutputFile)) {
-    this->OutputFile += "/";
-    this->OutputFile += cmSystemTools::GetFilenameName(inFile);
+  if (cmSystemTools::FileIsDirectory(outputFile)) {
+    outputFile += "/";
+    outputFile += cmSystemTools::GetFilenameName(inFile);
   }
 
-  if (!this->Makefile->CanIWriteThisFile(this->OutputFile)) {
-    std::string e = "attempted to configure a file: " + this->OutputFile +
+  if (!status.GetMakefile().CanIWriteThisFile(outputFile)) {
+    std::string e = "attempted to configure a file: " + outputFile +
       " into a source directory.";
-    this->SetError(e);
+    status.SetError(e);
     cmSystemTools::SetFatalErrorOccured();
     return false;
   }
   std::string errorMessage;
-  if (!this->NewLineStyle.ReadFromArguments(args, errorMessage)) {
-    this->SetError(errorMessage);
+  cmNewLineStyle newLineStyle;
+  if (!newLineStyle.ReadFromArguments(args, errorMessage)) {
+    status.SetError(errorMessage);
     return false;
   }
-  this->CopyOnly = false;
-  this->EscapeQuotes = false;
+  bool copyOnly = false;
+  bool escapeQuotes = false;
 
   std::string unknown_args;
-  this->AtOnly = false;
+  bool atOnly = false;
   for (unsigned int i = 2; i < args.size(); ++i) {
     if (args[i] == "COPYONLY") {
-      this->CopyOnly = true;
-      if (this->NewLineStyle.IsValid()) {
-        this->SetError("COPYONLY could not be used in combination "
-                       "with NEWLINE_STYLE");
+      copyOnly = true;
+      if (newLineStyle.IsValid()) {
+        status.SetError("COPYONLY could not be used in combination "
+                        "with NEWLINE_STYLE");
         return false;
       }
     } else if (args[i] == "ESCAPE_QUOTES") {
-      this->EscapeQuotes = true;
+      escapeQuotes = true;
     } else if (args[i] == "@ONLY") {
-      this->AtOnly = true;
+      atOnly = true;
     } else if (args[i] == "IMMEDIATE") {
       /* Ignore legacy option.  */
     } else if (args[i] == "NEWLINE_STYLE" || args[i] == "LF" ||
@@ -89,20 +90,14 @@ bool cmConfigureFileCommand::InitialPass(std::vector<std::string> const& args,
   if (!unknown_args.empty()) {
     std::string msg = "configure_file called with unknown argument(s):\n";
     msg += unknown_args;
-    this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, msg);
+    status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, msg);
   }
 
-  if (!this->ConfigureFile()) {
-    this->SetError("Problem configuring file");
+  if (!status.GetMakefile().ConfigureFile(
+        inputFile, outputFile, copyOnly, atOnly, escapeQuotes, newLineStyle)) {
+    status.SetError("Problem configuring file");
     return false;
   }
 
   return true;
 }
-
-int cmConfigureFileCommand::ConfigureFile()
-{
-  return this->Makefile->ConfigureFile(this->InputFile, this->OutputFile,
-                                       this->CopyOnly, this->AtOnly,
-                                       this->EscapeQuotes, this->NewLineStyle);
-}
diff --git a/Source/cmConfigureFileCommand.h b/Source/cmConfigureFileCommand.h
index b3a99d7..c7f95b8 100644
--- a/Source/cmConfigureFileCommand.h
+++ b/Source/cmConfigureFileCommand.h
@@ -8,38 +8,8 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-#include "cmNewLineStyle.h"
-
 class cmExecutionStatus;
 
-class cmConfigureFileCommand : public cmCommand
-{
-public:
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmConfigureFileCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the input file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-
-private:
-  int ConfigureFile();
-
-  cmNewLineStyle NewLineStyle;
-
-  std::string InputFile;
-  std::string OutputFile;
-  bool CopyOnly = false;
-  bool EscapeQuotes = false;
-  bool AtOnly = false;
-};
-
+bool cmConfigureFileCommand(std::vector<std::string> const& args,
+                            cmExecutionStatus& status);
 #endif
-- 
cgit v0.12


From 0005e17d504fd50ebaec3860f4f213765e815b13 Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Thu, 25 Jul 2019 16:52:50 +0200
Subject: cmCommand refactor: cmContinueCommand

---
 Source/cmCommands.cxx        |  2 +-
 Source/cmContinueCommand.cxx | 20 +++++++++++---------
 Source/cmContinueCommand.h   | 26 +++-----------------------
 3 files changed, 15 insertions(+), 33 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 3e7fa72..429a599 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -121,7 +121,7 @@ void GetScriptingCommands(cmState* state)
   state->AddBuiltinCommand("cmake_policy",
                            cm::make_unique<cmCMakePolicyCommand>());
   state->AddBuiltinCommand("configure_file", cmConfigureFileCommand);
-  state->AddBuiltinCommand("continue", cm::make_unique<cmContinueCommand>());
+  state->AddBuiltinCommand("continue", cmContinueCommand);
   state->AddBuiltinCommand("exec_program",
                            cm::make_unique<cmExecProgramCommand>());
   state->AddBuiltinCommand("execute_process",
diff --git a/Source/cmContinueCommand.cxx b/Source/cmContinueCommand.cxx
index 48f1f41..bb63dff 100644
--- a/Source/cmContinueCommand.cxx
+++ b/Source/cmContinueCommand.cxx
@@ -8,13 +8,14 @@
 #include "cmSystemTools.h"
 
 // cmContinueCommand
-bool cmContinueCommand::InitialPass(std::vector<std::string> const& args,
-                                    cmExecutionStatus& status)
+bool cmContinueCommand(std::vector<std::string> const& args,
+                       cmExecutionStatus& status)
 {
-  if (!this->Makefile->IsLoopBlock()) {
-    this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
-                                 "A CONTINUE command was found outside of a "
-                                 "proper FOREACH or WHILE loop scope.");
+  if (!status.GetMakefile().IsLoopBlock()) {
+    status.GetMakefile().IssueMessage(
+      MessageType::FATAL_ERROR,
+      "A CONTINUE command was found outside of a "
+      "proper FOREACH or WHILE loop scope.");
     cmSystemTools::SetFatalErrorOccured();
     return true;
   }
@@ -22,9 +23,10 @@ bool cmContinueCommand::InitialPass(std::vector<std::string> const& args,
   status.SetContinueInvoked();
 
   if (!args.empty()) {
-    this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
-                                 "The CONTINUE command does not accept any "
-                                 "arguments.");
+    status.GetMakefile().IssueMessage(
+      MessageType::FATAL_ERROR,
+      "The CONTINUE command does not accept any "
+      "arguments.");
     cmSystemTools::SetFatalErrorOccured();
     return true;
   }
diff --git a/Source/cmContinueCommand.h b/Source/cmContinueCommand.h
index a85010a..ff903aa 100644
--- a/Source/cmContinueCommand.h
+++ b/Source/cmContinueCommand.h
@@ -8,34 +8,14 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmContinueCommand
+/**
  * \brief Continue from an enclosing foreach or while loop
  *
  * cmContinueCommand returns from an enclosing foreach or while loop
  */
-class cmContinueCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmContinueCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-};
+bool cmContinueCommand(std::vector<std::string> const& args,
+                       cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From 0d87f5d83e52ceb72f754331a9fd3d7189680297 Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Thu, 25 Jul 2019 17:01:45 +0200
Subject: cmCommand refactor: cmExecProgramCommand

---
 Source/cmCommands.cxx           |  3 +--
 Source/cmExecProgramCommand.cxx | 36 +++++++++++++++++++++---------------
 Source/cmExecProgramCommand.h   | 33 +++------------------------------
 3 files changed, 25 insertions(+), 47 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 429a599..0f73293 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -122,8 +122,7 @@ void GetScriptingCommands(cmState* state)
                            cm::make_unique<cmCMakePolicyCommand>());
   state->AddBuiltinCommand("configure_file", cmConfigureFileCommand);
   state->AddBuiltinCommand("continue", cmContinueCommand);
-  state->AddBuiltinCommand("exec_program",
-                           cm::make_unique<cmExecProgramCommand>());
+  state->AddBuiltinCommand("exec_program", cmExecProgramCommand);
   state->AddBuiltinCommand("execute_process",
                            cm::make_unique<cmExecuteProcessCommand>());
   state->AddBuiltinCommand("file", cmFileCommand);
diff --git a/Source/cmExecProgramCommand.cxx b/Source/cmExecProgramCommand.cxx
index bc1d173..75716c0 100644
--- a/Source/cmExecProgramCommand.cxx
+++ b/Source/cmExecProgramCommand.cxx
@@ -5,18 +5,25 @@
 #include "cmsys/Process.h"
 #include <stdio.h>
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmProcessOutput.h"
 #include "cmSystemTools.h"
 
-class cmExecutionStatus;
+typedef cmProcessOutput::Encoding Encoding;
+
+namespace {
+bool RunCommand(std::string command, std::string& output, int& retVal,
+                const char* directory = nullptr, bool verbose = true,
+                Encoding encoding = cmProcessOutput::Auto);
+}
 
 // cmExecProgramCommand
-bool cmExecProgramCommand::InitialPass(std::vector<std::string> const& args,
-                                       cmExecutionStatus&)
+bool cmExecProgramCommand(std::vector<std::string> const& args,
+                          cmExecutionStatus& status)
 {
   if (args.empty()) {
-    this->SetError("called with incorrect number of arguments");
+    status.SetError("called with incorrect number of arguments");
     return false;
   }
   std::string arguments;
@@ -34,7 +41,7 @@ bool cmExecProgramCommand::InitialPass(std::vector<std::string> const& args,
       haveoutput_variable = true;
     } else if (haveoutput_variable) {
       if (!output_variable.empty()) {
-        this->SetError("called with incorrect number of arguments");
+        status.SetError("called with incorrect number of arguments");
         return false;
       }
       output_variable = arg;
@@ -47,7 +54,7 @@ bool cmExecProgramCommand::InitialPass(std::vector<std::string> const& args,
       havereturn_variable = true;
     } else if (havereturn_variable) {
       if (!return_variable.empty()) {
-        this->SetError("called with incorrect number of arguments");
+        status.SetError("called with incorrect number of arguments");
         return false;
       }
       return_variable = arg;
@@ -82,11 +89,9 @@ bool cmExecProgramCommand::InitialPass(std::vector<std::string> const& args,
   bool result = true;
   if (args.size() - count == 2) {
     cmSystemTools::MakeDirectory(args[1]);
-    result = cmExecProgramCommand::RunCommand(command, output, retVal,
-                                              args[1].c_str(), verbose);
+    result = RunCommand(command, output, retVal, args[1].c_str(), verbose);
   } else {
-    result = cmExecProgramCommand::RunCommand(command, output, retVal, nullptr,
-                                              verbose);
+    result = RunCommand(command, output, retVal, nullptr, verbose);
   }
   if (!result) {
     retVal = -1;
@@ -103,21 +108,21 @@ bool cmExecProgramCommand::InitialPass(std::vector<std::string> const& args,
     }
 
     std::string coutput = std::string(output, first, last - first + 1);
-    this->Makefile->AddDefinition(output_variable, coutput);
+    status.GetMakefile().AddDefinition(output_variable, coutput);
   }
 
   if (!return_variable.empty()) {
     char buffer[100];
     sprintf(buffer, "%d", retVal);
-    this->Makefile->AddDefinition(return_variable, buffer);
+    status.GetMakefile().AddDefinition(return_variable, buffer);
   }
 
   return true;
 }
 
-bool cmExecProgramCommand::RunCommand(std::string command, std::string& output,
-                                      int& retVal, const char* dir,
-                                      bool verbose, Encoding encoding)
+namespace {
+bool RunCommand(std::string command, std::string& output, int& retVal,
+                const char* dir, bool verbose, Encoding encoding)
 {
   if (cmSystemTools::GetRunCommandOutput()) {
     verbose = false;
@@ -284,3 +289,4 @@ bool cmExecProgramCommand::RunCommand(std::string command, std::string& output,
 
   return true;
 }
+}
diff --git a/Source/cmExecProgramCommand.h b/Source/cmExecProgramCommand.h
index 70f833a..7c751e1 100644
--- a/Source/cmExecProgramCommand.h
+++ b/Source/cmExecProgramCommand.h
@@ -8,43 +8,16 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-#include "cmProcessOutput.h"
-
 class cmExecutionStatus;
 
-/** \class cmExecProgramCommand
+/**
  * \brief Command that adds a target to the build system.
  *
  * cmExecProgramCommand adds an extra target to the build system.
  * This is useful when you would like to add special
  * targets like "install,", "clean," and so on.
  */
-class cmExecProgramCommand : public cmCommand
-{
-public:
-  typedef cmProcessOutput::Encoding Encoding;
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmExecProgramCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-
-private:
-  static bool RunCommand(std::string command, std::string& output, int& retVal,
-                         const char* directory = nullptr, bool verbose = true,
-                         Encoding encoding = cmProcessOutput::Auto);
-};
+bool cmExecProgramCommand(std::vector<std::string> const& args,
+                          cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From 3e5eb45ec1fd977b709da6e36966b0b13d185214 Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Thu, 25 Jul 2019 17:31:39 +0200
Subject: cmCommand refactor: cmExecuteProcessCommand

---
 Source/cmCommands.cxx              |  3 +-
 Source/cmExecuteProcessCommand.cxx | 78 ++++++++++++++++++++------------------
 Source/cmExecuteProcessCommand.h   | 26 ++-----------
 3 files changed, 46 insertions(+), 61 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 0f73293..ea9bddb 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -123,8 +123,7 @@ void GetScriptingCommands(cmState* state)
   state->AddBuiltinCommand("configure_file", cmConfigureFileCommand);
   state->AddBuiltinCommand("continue", cmContinueCommand);
   state->AddBuiltinCommand("exec_program", cmExecProgramCommand);
-  state->AddBuiltinCommand("execute_process",
-                           cm::make_unique<cmExecuteProcessCommand>());
+  state->AddBuiltinCommand("execute_process", cmExecuteProcessCommand);
   state->AddBuiltinCommand("file", cmFileCommand);
   state->AddBuiltinCommand("find_file", cm::make_unique<cmFindFileCommand>());
   state->AddBuiltinCommand("find_library",
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx
index 465f4b3..acf2a83 100644
--- a/Source/cmExecuteProcessCommand.cxx
+++ b/Source/cmExecuteProcessCommand.cxx
@@ -8,20 +8,21 @@
 #include <algorithm>
 #include <ctype.h> /* isspace */
 #include <iostream>
+#include <memory>
 #include <stdio.h>
 #include <vector>
 
 #include "cmAlgorithms.h"
 #include "cmArgumentParser.h"
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmProcessOutput.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 
-class cmExecutionStatus;
-
-static bool cmExecuteProcessCommandIsWhitespace(char c)
+namespace {
+bool cmExecuteProcessCommandIsWhitespace(char c)
 {
   return (isspace(static_cast<int>(c)) || c == '\n' || c == '\r');
 }
@@ -30,13 +31,14 @@ void cmExecuteProcessCommandFixText(std::vector<char>& output,
                                     bool strip_trailing_whitespace);
 void cmExecuteProcessCommandAppend(std::vector<char>& output, const char* data,
                                    int length);
+}
 
 // cmExecuteProcessCommand
-bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
-                                          cmExecutionStatus&)
+bool cmExecuteProcessCommand(std::vector<std::string> const& args,
+                             cmExecutionStatus& status)
 {
   if (args.empty()) {
-    this->SetError("called with incorrect number of arguments");
+    status.SetError("called with incorrect number of arguments");
     return false;
   }
 
@@ -87,31 +89,31 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
     parser.Parse(args, &unparsedArguments, &keywordsMissingValue);
 
   if (!keywordsMissingValue.empty()) {
-    this->SetError(" called with no value for " +
-                   keywordsMissingValue.front() + ".");
+    status.SetError(" called with no value for " +
+                    keywordsMissingValue.front() + ".");
     return false;
   }
   if (!unparsedArguments.empty()) {
-    this->SetError(" given unknown argument \"" + unparsedArguments.front() +
-                   "\".");
+    status.SetError(" given unknown argument \"" + unparsedArguments.front() +
+                    "\".");
     return false;
   }
 
-  if (!this->Makefile->CanIWriteThisFile(arguments.OutputFile)) {
-    this->SetError("attempted to output into a file: " + arguments.OutputFile +
-                   " into a source directory.");
+  if (!status.GetMakefile().CanIWriteThisFile(arguments.OutputFile)) {
+    status.SetError("attempted to output into a file: " +
+                    arguments.OutputFile + " into a source directory.");
     cmSystemTools::SetFatalErrorOccured();
     return false;
   }
 
   // Check for commands given.
   if (arguments.Commands.empty()) {
-    this->SetError(" called with no COMMAND argument.");
+    status.SetError(" called with no COMMAND argument.");
     return false;
   }
   for (std::vector<std::string> const& cmd : arguments.Commands) {
     if (cmd.empty()) {
-      this->SetError(" given COMMAND argument with no value.");
+      status.SetError(" given COMMAND argument with no value.");
       return false;
     }
   }
@@ -120,7 +122,7 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
   double timeout = -1;
   if (!arguments.Timeout.empty()) {
     if (sscanf(arguments.Timeout.c_str(), "%lg", &timeout) != 1) {
-      this->SetError(" called with TIMEOUT value that could not be parsed.");
+      status.SetError(" called with TIMEOUT value that could not be parsed.");
       return false;
     }
   }
@@ -180,8 +182,8 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
   bool echo_stdout = false;
   bool echo_stderr = false;
   bool echo_output_from_variable = true;
-  std::string echo_output =
-    this->Makefile->GetSafeDefinition("CMAKE_EXECUTE_PROCESS_COMMAND_ECHO");
+  std::string echo_output = status.GetMakefile().GetSafeDefinition(
+    "CMAKE_EXECUTE_PROCESS_COMMAND_ECHO");
   if (!arguments.CommandEcho.empty()) {
     echo_output_from_variable = false;
     echo_output = arguments.CommandEcho;
@@ -204,7 +206,7 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
       if (!echo_output_from_variable) {
         error += " for COMMAND_ECHO.";
       }
-      this->Makefile->IssueMessage(MessageType::FATAL_ERROR, error);
+      status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, error);
       return true;
     }
   }
@@ -278,11 +280,13 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
 
   // Store the output obtained.
   if (!arguments.OutputVariable.empty() && !tempOutput.empty()) {
-    this->Makefile->AddDefinition(arguments.OutputVariable, tempOutput.data());
+    status.GetMakefile().AddDefinition(arguments.OutputVariable,
+                                       tempOutput.data());
   }
   if (!merge_output && !arguments.ErrorVariable.empty() &&
       !tempError.empty()) {
-    this->Makefile->AddDefinition(arguments.ErrorVariable, tempError.data());
+    status.GetMakefile().AddDefinition(arguments.ErrorVariable,
+                                       tempError.data());
   }
 
   // Store the result of running the process.
@@ -292,19 +296,19 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
         int v = cmsysProcess_GetExitValue(cp);
         char buf[16];
         sprintf(buf, "%d", v);
-        this->Makefile->AddDefinition(arguments.ResultVariable, buf);
+        status.GetMakefile().AddDefinition(arguments.ResultVariable, buf);
       } break;
       case cmsysProcess_State_Exception:
-        this->Makefile->AddDefinition(arguments.ResultVariable,
-                                      cmsysProcess_GetExceptionString(cp));
+        status.GetMakefile().AddDefinition(
+          arguments.ResultVariable, cmsysProcess_GetExceptionString(cp));
         break;
       case cmsysProcess_State_Error:
-        this->Makefile->AddDefinition(arguments.ResultVariable,
-                                      cmsysProcess_GetErrorString(cp));
+        status.GetMakefile().AddDefinition(arguments.ResultVariable,
+                                           cmsysProcess_GetErrorString(cp));
         break;
       case cmsysProcess_State_Expired:
-        this->Makefile->AddDefinition(arguments.ResultVariable,
-                                      "Process terminated due to timeout");
+        status.GetMakefile().AddDefinition(
+          arguments.ResultVariable, "Process terminated due to timeout");
         break;
     }
   }
@@ -332,20 +336,20 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
               break;
           }
         }
-        this->Makefile->AddDefinition(arguments.ResultsVariable,
-                                      cmJoin(res, ";"));
+        status.GetMakefile().AddDefinition(arguments.ResultsVariable,
+                                           cmJoin(res, ";"));
       } break;
       case cmsysProcess_State_Exception:
-        this->Makefile->AddDefinition(arguments.ResultsVariable,
-                                      cmsysProcess_GetExceptionString(cp));
+        status.GetMakefile().AddDefinition(
+          arguments.ResultsVariable, cmsysProcess_GetExceptionString(cp));
         break;
       case cmsysProcess_State_Error:
-        this->Makefile->AddDefinition(arguments.ResultsVariable,
-                                      cmsysProcess_GetErrorString(cp));
+        status.GetMakefile().AddDefinition(arguments.ResultsVariable,
+                                           cmsysProcess_GetErrorString(cp));
         break;
       case cmsysProcess_State_Expired:
-        this->Makefile->AddDefinition(arguments.ResultsVariable,
-                                      "Process terminated due to timeout");
+        status.GetMakefile().AddDefinition(
+          arguments.ResultsVariable, "Process terminated due to timeout");
         break;
     }
   }
@@ -353,6 +357,7 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
   return true;
 }
 
+namespace {
 void cmExecuteProcessCommandFixText(std::vector<char>& output,
                                     bool strip_trailing_whitespace)
 {
@@ -398,3 +403,4 @@ void cmExecuteProcessCommandAppend(std::vector<char>& output, const char* data,
 #endif
   cmAppend(output, data, data + length);
 }
+}
diff --git a/Source/cmExecuteProcessCommand.h b/Source/cmExecuteProcessCommand.h
index 1d5445f..9c4b600 100644
--- a/Source/cmExecuteProcessCommand.h
+++ b/Source/cmExecuteProcessCommand.h
@@ -8,35 +8,15 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmExecuteProcessCommand
+/**
  * \brief Command that adds a target to the build system.
  *
  * cmExecuteProcessCommand is a CMake language interface to the KWSys
  * Process Execution implementation.
  */
-class cmExecuteProcessCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmExecuteProcessCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-};
+bool cmExecuteProcessCommand(std::vector<std::string> const& args,
+                             cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From cce3600e3f789f6f2984d61c925170f92b35ee7d Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Thu, 25 Jul 2019 18:51:34 +0200
Subject: cmCommand refactor: cmForEachCommand

---
 Source/cmCommands.cxx       |  2 +-
 Source/cmForEachCommand.cxx | 30 ++++++++++++++++++------------
 Source/cmForEachCommand.h   | 28 ++--------------------------
 3 files changed, 21 insertions(+), 39 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index ea9bddb..f4f4c4a 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -133,7 +133,7 @@ void GetScriptingCommands(cmState* state)
   state->AddBuiltinCommand("find_path", cm::make_unique<cmFindPathCommand>());
   state->AddBuiltinCommand("find_program",
                            cm::make_unique<cmFindProgramCommand>());
-  state->AddBuiltinCommand("foreach", cm::make_unique<cmForEachCommand>());
+  state->AddBuiltinCommand("foreach", cmForEachCommand);
   state->AddBuiltinCommand("function", cm::make_unique<cmFunctionCommand>());
   state->AddBuiltinCommand("get_cmake_property",
                            cm::make_unique<cmGetCMakePropertyCommand>());
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
index 9c6f1b4..f0633aa 100644
--- a/Source/cmForEachCommand.cxx
+++ b/Source/cmForEachCommand.cxx
@@ -20,6 +20,9 @@
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 
+namespace {
+bool HandleInMode(std::vector<std::string> const& args, cmMakefile& makefile);
+
 class cmForEachFunctionBlocker : public cmFunctionBlocker
 {
 public:
@@ -102,20 +105,21 @@ bool cmForEachFunctionBlocker::Replay(
   mf.AddDefinition(this->Args[0], oldDef);
   return true;
 }
+}
 
-bool cmForEachCommand::InitialPass(std::vector<std::string> const& args,
-                                   cmExecutionStatus&)
+bool cmForEachCommand(std::vector<std::string> const& args,
+                      cmExecutionStatus& status)
 {
   if (args.empty()) {
-    this->SetError("called with incorrect number of arguments");
+    status.SetError("called with incorrect number of arguments");
     return false;
   }
   if (args.size() > 1 && args[1] == "IN") {
-    return this->HandleInMode(args);
+    return HandleInMode(args, status.GetMakefile());
   }
 
   // create a function blocker
-  auto fb = cm::make_unique<cmForEachFunctionBlocker>(this->Makefile);
+  auto fb = cm::make_unique<cmForEachFunctionBlocker>(&status.GetMakefile());
   if (args.size() > 1) {
     if (args[1] == "RANGE") {
       int start = 0;
@@ -145,7 +149,7 @@ bool cmForEachCommand::InitialPass(std::vector<std::string> const& args,
         std::ostringstream str;
         str << "called with incorrect range specification: start ";
         str << start << ", stop " << stop << ", step " << step;
-        this->SetError(str.str());
+        status.SetError(str.str());
         return false;
       }
       std::vector<std::string> range;
@@ -169,14 +173,15 @@ bool cmForEachCommand::InitialPass(std::vector<std::string> const& args,
   } else {
     fb->Args = args;
   }
-  this->Makefile->AddFunctionBlocker(std::move(fb));
+  status.GetMakefile().AddFunctionBlocker(std::move(fb));
 
   return true;
 }
 
-bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args)
+namespace {
+bool HandleInMode(std::vector<std::string> const& args, cmMakefile& makefile)
 {
-  auto fb = cm::make_unique<cmForEachFunctionBlocker>(this->Makefile);
+  auto fb = cm::make_unique<cmForEachFunctionBlocker>(&makefile);
   fb->Args.push_back(args[0]);
 
   enum Doing
@@ -194,7 +199,7 @@ bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args)
     } else if (args[i] == "ITEMS") {
       doing = DoingItems;
     } else if (doing == DoingLists) {
-      const char* value = this->Makefile->GetDefinition(args[i]);
+      const char* value = makefile.GetDefinition(args[i]);
       if (value && *value) {
         cmExpandList(value, fb->Args, true);
       }
@@ -202,12 +207,13 @@ bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args)
       std::ostringstream e;
       e << "Unknown argument:\n"
         << "  " << args[i] << "\n";
-      this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+      makefile.IssueMessage(MessageType::FATAL_ERROR, e.str());
       return true;
     }
   }
 
-  this->Makefile->AddFunctionBlocker(std::move(fb));
+  makefile.AddFunctionBlocker(std::move(fb));
 
   return true;
 }
+}
diff --git a/Source/cmForEachCommand.h b/Source/cmForEachCommand.h
index 135abf0..1feb965 100644
--- a/Source/cmForEachCommand.h
+++ b/Source/cmForEachCommand.h
@@ -8,33 +8,9 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
 /// Starts foreach() ... endforeach() block
-class cmForEachCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmForEachCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-
-private:
-  bool HandleInMode(std::vector<std::string> const& args);
-};
-
+bool cmForEachCommand(std::vector<std::string> const& args,
+                      cmExecutionStatus& status);
 #endif
-- 
cgit v0.12


From 9bbe95a0e71e6658a37fe9e755577c80ffa2da9c Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Thu, 25 Jul 2019 19:07:00 +0200
Subject: cmCommand refactor: cmFunctionCommand

---
 Source/cmCommands.cxx        |  2 +-
 Source/cmFunctionCommand.cxx | 11 +++++++----
 Source/cmFunctionCommand.h   | 24 ++----------------------
 3 files changed, 10 insertions(+), 27 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index f4f4c4a..461ffdf 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -134,7 +134,7 @@ void GetScriptingCommands(cmState* state)
   state->AddBuiltinCommand("find_program",
                            cm::make_unique<cmFindProgramCommand>());
   state->AddBuiltinCommand("foreach", cmForEachCommand);
-  state->AddBuiltinCommand("function", cm::make_unique<cmFunctionCommand>());
+  state->AddBuiltinCommand("function", cmFunctionCommand);
   state->AddBuiltinCommand("get_cmake_property",
                            cm::make_unique<cmGetCMakePropertyCommand>());
   state->AddBuiltinCommand("get_directory_property",
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index 610f516..f130e8d 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -5,6 +5,7 @@
 #include <sstream>
 #include <utility>
 
+#include "cm_memory.hxx"
 #include "cm_static_string_view.hxx"
 #include "cm_string_view.hxx"
 
@@ -18,6 +19,7 @@
 #include "cmState.h"
 #include "cmStringAlgorithms.h"
 
+namespace {
 // define the class for function commands
 class cmFunctionHelperCommand
 {
@@ -34,6 +36,7 @@ public:
   cmPolicies::PolicyMap Policies;
   std::string FilePath;
 };
+}
 
 bool cmFunctionHelperCommand::operator()(
   std::vector<cmListFileArgument> const& args,
@@ -145,11 +148,11 @@ bool cmFunctionFunctionBlocker::Replay(
   return true;
 }
 
-bool cmFunctionCommand::InitialPass(std::vector<std::string> const& args,
-                                    cmExecutionStatus&)
+bool cmFunctionCommand(std::vector<std::string> const& args,
+                       cmExecutionStatus& status)
 {
   if (args.empty()) {
-    this->SetError("called with incorrect number of arguments");
+    status.SetError("called with incorrect number of arguments");
     return false;
   }
 
@@ -157,7 +160,7 @@ bool cmFunctionCommand::InitialPass(std::vector<std::string> const& args,
   {
     auto fb = cm::make_unique<cmFunctionFunctionBlocker>();
     cmAppend(fb->Args, args);
-    this->Makefile->AddFunctionBlocker(std::move(fb));
+    status.GetMakefile().AddFunctionBlocker(std::move(fb));
   }
   return true;
 }
diff --git a/Source/cmFunctionCommand.h b/Source/cmFunctionCommand.h
index b334525..d6b549c 100644
--- a/Source/cmFunctionCommand.h
+++ b/Source/cmFunctionCommand.h
@@ -8,30 +8,10 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
 /// Starts function() ... endfunction() block
-class cmFunctionCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmFunctionCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-};
+bool cmFunctionCommand(std::vector<std::string> const& args,
+                       cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From 40ba0addac09b7389d7c554d5c6e9eed74f377e3 Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Thu, 25 Jul 2019 19:12:23 +0200
Subject: cmCommand refactor: cmGetCMakePropertyCommand

---
 Source/cmCommands.cxx                |  3 +--
 Source/cmGetCMakePropertyCommand.cxx | 19 +++++++++----------
 Source/cmGetCMakePropertyCommand.h   | 21 ++-------------------
 3 files changed, 12 insertions(+), 31 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 461ffdf..d170aa0 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -135,8 +135,7 @@ void GetScriptingCommands(cmState* state)
                            cm::make_unique<cmFindProgramCommand>());
   state->AddBuiltinCommand("foreach", cmForEachCommand);
   state->AddBuiltinCommand("function", cmFunctionCommand);
-  state->AddBuiltinCommand("get_cmake_property",
-                           cm::make_unique<cmGetCMakePropertyCommand>());
+  state->AddBuiltinCommand("get_cmake_property", cmGetCMakePropertyCommand);
   state->AddBuiltinCommand("get_directory_property",
                            cm::make_unique<cmGetDirectoryPropertyCommand>());
   state->AddBuiltinCommand("get_filename_component",
diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx
index 38fee28..ff4e312 100644
--- a/Source/cmGetCMakePropertyCommand.cxx
+++ b/Source/cmGetCMakePropertyCommand.cxx
@@ -4,19 +4,18 @@
 
 #include <set>
 
+#include "cmExecutionStatus.h"
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
 #include "cmState.h"
 #include "cmStringAlgorithms.h"
 
-class cmExecutionStatus;
-
 // cmGetCMakePropertyCommand
-bool cmGetCMakePropertyCommand::InitialPass(
-  std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmGetCMakePropertyCommand(std::vector<std::string> const& args,
+                               cmExecutionStatus& status)
 {
   if (args.size() < 2) {
-    this->SetError("called with incorrect number of arguments");
+    status.SetError("called with incorrect number of arguments");
     return false;
   }
 
@@ -24,29 +23,29 @@ bool cmGetCMakePropertyCommand::InitialPass(
   std::string output = "NOTFOUND";
 
   if (args[1] == "VARIABLES") {
-    if (const char* varsProp = this->Makefile->GetProperty("VARIABLES")) {
+    if (const char* varsProp = status.GetMakefile().GetProperty("VARIABLES")) {
       output = varsProp;
     }
   } else if (args[1] == "MACROS") {
     output.clear();
-    if (const char* macrosProp = this->Makefile->GetProperty("MACROS")) {
+    if (const char* macrosProp = status.GetMakefile().GetProperty("MACROS")) {
       output = macrosProp;
     }
   } else if (args[1] == "COMPONENTS") {
     const std::set<std::string>* components =
-      this->Makefile->GetGlobalGenerator()->GetInstallComponents();
+      status.GetMakefile().GetGlobalGenerator()->GetInstallComponents();
     output = cmJoin(*components, ";");
   } else {
     const char* prop = nullptr;
     if (!args[1].empty()) {
-      prop = this->Makefile->GetState()->GetGlobalProperty(args[1]);
+      prop = status.GetMakefile().GetState()->GetGlobalProperty(args[1]);
     }
     if (prop) {
       output = prop;
     }
   }
 
-  this->Makefile->AddDefinition(variable, output);
+  status.GetMakefile().AddDefinition(variable, output);
 
   return true;
 }
diff --git a/Source/cmGetCMakePropertyCommand.h b/Source/cmGetCMakePropertyCommand.h
index 7790a6b..7a6728c 100644
--- a/Source/cmGetCMakePropertyCommand.h
+++ b/Source/cmGetCMakePropertyCommand.h
@@ -8,26 +8,9 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-class cmGetCMakePropertyCommand : public cmCommand
-{
-public:
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmGetCMakePropertyCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the input file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-};
+bool cmGetCMakePropertyCommand(std::vector<std::string> const& args,
+                               cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From 067d1fa9c0d887efb35b859230d743307f04fecd Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Thu, 25 Jul 2019 19:19:50 +0200
Subject: cmCommand refactor: cmGetDirectoryPropertyCommand

---
 Source/cmCommands.cxx                    |  2 +-
 Source/cmGetDirectoryPropertyCommand.cxx | 45 ++++++++++++++++++--------------
 Source/cmGetDirectoryPropertyCommand.h   | 24 ++---------------
 3 files changed, 29 insertions(+), 42 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index d170aa0..2cce9b7 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -137,7 +137,7 @@ void GetScriptingCommands(cmState* state)
   state->AddBuiltinCommand("function", cmFunctionCommand);
   state->AddBuiltinCommand("get_cmake_property", cmGetCMakePropertyCommand);
   state->AddBuiltinCommand("get_directory_property",
-                           cm::make_unique<cmGetDirectoryPropertyCommand>());
+                           cmGetDirectoryPropertyCommand);
   state->AddBuiltinCommand("get_filename_component",
                            cm::make_unique<cmGetFilenameComponentCommand>());
   state->AddBuiltinCommand("get_property",
diff --git a/Source/cmGetDirectoryPropertyCommand.cxx b/Source/cmGetDirectoryPropertyCommand.cxx
index 98ccb0a..fa3d39c 100644
--- a/Source/cmGetDirectoryPropertyCommand.cxx
+++ b/Source/cmGetDirectoryPropertyCommand.cxx
@@ -2,20 +2,24 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmGetDirectoryPropertyCommand.h"
 
+#include "cmExecutionStatus.h"
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmPolicies.h"
 #include "cmSystemTools.h"
 
-class cmExecutionStatus;
+namespace {
+void StoreResult(cmMakefile& makefile, std::string const& variable,
+                 const char* prop);
+}
 
 // cmGetDirectoryPropertyCommand
-bool cmGetDirectoryPropertyCommand::InitialPass(
-  std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmGetDirectoryPropertyCommand(std::vector<std::string> const& args,
+                                   cmExecutionStatus& status)
 {
   if (args.size() < 2) {
-    this->SetError("called with incorrect number of arguments");
+    status.SetError("called with incorrect number of arguments");
     return false;
   }
 
@@ -24,18 +28,18 @@ bool cmGetDirectoryPropertyCommand::InitialPass(
   ++i;
 
   // get the directory argument if there is one
-  cmMakefile* dir = this->Makefile;
+  cmMakefile* dir = &status.GetMakefile();
   if (*i == "DIRECTORY") {
     ++i;
     if (i == args.end()) {
-      this->SetError(
+      status.SetError(
         "DIRECTORY argument provided without subsequent arguments");
       return false;
     }
     std::string sd = *i;
     // make sure the start dir is a full path
     if (!cmSystemTools::FileIsFullPath(sd)) {
-      sd = this->Makefile->GetCurrentSourceDirectory();
+      sd = status.GetMakefile().GetCurrentSourceDirectory();
       sd += "/";
       sd += *i;
     }
@@ -44,9 +48,9 @@ bool cmGetDirectoryPropertyCommand::InitialPass(
     sd = cmSystemTools::CollapseFullPath(sd);
 
     // lookup the makefile from the directory name
-    dir = this->Makefile->GetGlobalGenerator()->FindMakefile(sd);
+    dir = status.GetMakefile().GetGlobalGenerator()->FindMakefile(sd);
     if (!dir) {
-      this->SetError(
+      status.SetError(
         "DIRECTORY argument provided but requested directory not found. "
         "This could be because the directory argument was invalid or, "
         "it is valid but has not been processed yet.");
@@ -61,26 +65,27 @@ bool cmGetDirectoryPropertyCommand::InitialPass(
   if (*i == "DEFINITION") {
     ++i;
     if (i == args.end()) {
-      this->SetError("A request for a variable definition was made without "
-                     "providing the name of the variable to get.");
+      status.SetError("A request for a variable definition was made without "
+                      "providing the name of the variable to get.");
       return false;
     }
     std::string const& output = dir->GetSafeDefinition(*i);
-    this->Makefile->AddDefinition(variable, output);
+    status.GetMakefile().AddDefinition(variable, output);
     return true;
   }
 
   const char* prop = nullptr;
   if (!i->empty()) {
     if (*i == "DEFINITIONS") {
-      switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0059)) {
+      switch (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0059)) {
         case cmPolicies::WARN:
-          this->Makefile->IssueMessage(
+          status.GetMakefile().IssueMessage(
             MessageType::AUTHOR_WARNING,
             cmPolicies::GetPolicyWarning(cmPolicies::CMP0059));
           CM_FALLTHROUGH;
         case cmPolicies::OLD:
-          this->StoreResult(variable, this->Makefile->GetDefineFlagsCMP0059());
+          StoreResult(status.GetMakefile(), variable,
+                      status.GetMakefile().GetDefineFlagsCMP0059());
           return true;
         case cmPolicies::NEW:
         case cmPolicies::REQUIRED_ALWAYS:
@@ -90,12 +95,14 @@ bool cmGetDirectoryPropertyCommand::InitialPass(
     }
     prop = dir->GetProperty(*i);
   }
-  this->StoreResult(variable, prop);
+  StoreResult(status.GetMakefile(), variable, prop);
   return true;
 }
 
-void cmGetDirectoryPropertyCommand::StoreResult(std::string const& variable,
-                                                const char* prop)
+namespace {
+void StoreResult(cmMakefile& makefile, std::string const& variable,
+                 const char* prop)
 {
-  this->Makefile->AddDefinition(variable, prop ? prop : "");
+  makefile.AddDefinition(variable, prop ? prop : "");
+}
 }
diff --git a/Source/cmGetDirectoryPropertyCommand.h b/Source/cmGetDirectoryPropertyCommand.h
index 63a198a..f356ea5 100644
--- a/Source/cmGetDirectoryPropertyCommand.h
+++ b/Source/cmGetDirectoryPropertyCommand.h
@@ -8,29 +8,9 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-class cmGetDirectoryPropertyCommand : public cmCommand
-{
-public:
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmGetDirectoryPropertyCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the input file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-
-private:
-  void StoreResult(const std::string& variable, const char* prop);
-};
+bool cmGetDirectoryPropertyCommand(std::vector<std::string> const& args,
+                                   cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From 6377efd154a385349f2e826c1388e1d768bfcbcb Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Thu, 25 Jul 2019 19:24:45 +0200
Subject: cmCommand refactor: cmGetFilenameComponentCommand

---
 Source/cmCommands.cxx                    |  2 +-
 Source/cmGetFilenameComponentCommand.cxx | 25 ++++++++++++-------------
 Source/cmGetFilenameComponentCommand.h   | 26 +++-----------------------
 3 files changed, 16 insertions(+), 37 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 2cce9b7..d401b25 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -139,7 +139,7 @@ void GetScriptingCommands(cmState* state)
   state->AddBuiltinCommand("get_directory_property",
                            cmGetDirectoryPropertyCommand);
   state->AddBuiltinCommand("get_filename_component",
-                           cm::make_unique<cmGetFilenameComponentCommand>());
+                           cmGetFilenameComponentCommand);
   state->AddBuiltinCommand("get_property",
                            cm::make_unique<cmGetPropertyCommand>());
   state->AddBuiltinCommand("if", cmIfCommand);
diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx
index d56af3d..7d91a75 100644
--- a/Source/cmGetFilenameComponentCommand.cxx
+++ b/Source/cmGetFilenameComponentCommand.cxx
@@ -2,26 +2,25 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmGetFilenameComponentCommand.h"
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 
-class cmExecutionStatus;
-
 // cmGetFilenameComponentCommand
-bool cmGetFilenameComponentCommand::InitialPass(
-  std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmGetFilenameComponentCommand(std::vector<std::string> const& args,
+                                   cmExecutionStatus& status)
 {
   if (args.size() < 3) {
-    this->SetError("called with incorrect number of arguments");
+    status.SetError("called with incorrect number of arguments");
     return false;
   }
 
   // Check and see if the value has been stored in the cache
   // already, if so use that value
   if (args.size() >= 4 && args.back() == "CACHE") {
-    const char* cacheValue = this->Makefile->GetDefinition(args.front());
+    const char* cacheValue = status.GetMakefile().GetDefinition(args.front());
     if (cacheValue && !cmIsNOTFOUND(cacheValue)) {
       return true;
     }
@@ -33,7 +32,7 @@ bool cmGetFilenameComponentCommand::InitialPass(
     // Check the registry as the target application would view it.
     cmSystemTools::KeyWOW64 view = cmSystemTools::KeyWOW64_32;
     cmSystemTools::KeyWOW64 other_view = cmSystemTools::KeyWOW64_64;
-    if (this->Makefile->PlatformIs64Bit()) {
+    if (status.GetMakefile().PlatformIs64Bit()) {
       view = cmSystemTools::KeyWOW64_64;
       other_view = cmSystemTools::KeyWOW64_32;
     }
@@ -97,7 +96,7 @@ bool cmGetFilenameComponentCommand::InitialPass(
     // If the path given is relative, evaluate it relative to the
     // current source directory unless the user passes a different
     // base directory.
-    std::string baseDir = this->Makefile->GetCurrentSourceDirectory();
+    std::string baseDir = status.GetMakefile().GetCurrentSourceDirectory();
     for (unsigned int i = 3; i < args.size(); ++i) {
       if (args[i] == "BASE_DIR") {
         ++i;
@@ -114,24 +113,24 @@ bool cmGetFilenameComponentCommand::InitialPass(
     }
   } else {
     std::string err = "unknown component " + args[2];
-    this->SetError(err);
+    status.SetError(err);
     return false;
   }
 
   if (args.size() >= 4 && args.back() == "CACHE") {
     if (!programArgs.empty() && !storeArgs.empty()) {
-      this->Makefile->AddCacheDefinition(
+      status.GetMakefile().AddCacheDefinition(
         storeArgs, programArgs.c_str(), "",
         args[2] == "PATH" ? cmStateEnums::FILEPATH : cmStateEnums::STRING);
     }
-    this->Makefile->AddCacheDefinition(
+    status.GetMakefile().AddCacheDefinition(
       args.front(), result.c_str(), "",
       args[2] == "PATH" ? cmStateEnums::FILEPATH : cmStateEnums::STRING);
   } else {
     if (!programArgs.empty() && !storeArgs.empty()) {
-      this->Makefile->AddDefinition(storeArgs, programArgs);
+      status.GetMakefile().AddDefinition(storeArgs, programArgs);
     }
-    this->Makefile->AddDefinition(args.front(), result);
+    status.GetMakefile().AddDefinition(args.front(), result);
   }
 
   return true;
diff --git a/Source/cmGetFilenameComponentCommand.h b/Source/cmGetFilenameComponentCommand.h
index 1780b96..db5293b 100644
--- a/Source/cmGetFilenameComponentCommand.h
+++ b/Source/cmGetFilenameComponentCommand.h
@@ -8,35 +8,15 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmGetFilenameComponentCommand
+/**
  * \brief Get a specific component of a filename.
  *
  * cmGetFilenameComponentCommand is a utility command used to get the path,
  * name, extension or name without extension of a full filename.
  */
-class cmGetFilenameComponentCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmGetFilenameComponentCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-};
+bool cmGetFilenameComponentCommand(std::vector<std::string> const& args,
+                                   cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From fb57537a830444cd7ced203f92505bebd510f91a Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Fri, 2 Aug 2019 18:17:16 +0200
Subject: cmCommand_refactor: cmGetPropertyCommand

---
 Source/cmCommands.cxx           |   3 +-
 Source/cmGetPropertyCommand.cxx | 296 +++++++++++++++++++++++++---------------
 Source/cmGetPropertyCommand.h   |  50 +------
 3 files changed, 187 insertions(+), 162 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index d401b25..1842ae0 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -140,8 +140,7 @@ void GetScriptingCommands(cmState* state)
                            cmGetDirectoryPropertyCommand);
   state->AddBuiltinCommand("get_filename_component",
                            cmGetFilenameComponentCommand);
-  state->AddBuiltinCommand("get_property",
-                           cm::make_unique<cmGetPropertyCommand>());
+  state->AddBuiltinCommand("get_property", cmGetPropertyCommand);
   state->AddBuiltinCommand("if", cmIfCommand);
   state->AddBuiltinCommand("include", cm::make_unique<cmIncludeCommand>());
   state->AddBuiltinCommand("include_guard",
diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx
index de462ed..2f720f0 100644
--- a/Source/cmGetPropertyCommand.cxx
+++ b/Source/cmGetPropertyCommand.cxx
@@ -4,6 +4,7 @@
 
 #include <sstream>
 
+#include "cmExecutionStatus.h"
 #include "cmGlobalGenerator.h"
 #include "cmInstalledFile.h"
 #include "cmListFileCache.h"
@@ -20,24 +21,63 @@
 #include "cmTest.h"
 #include "cmake.h"
 
-class cmExecutionStatus;
 class cmMessenger;
 
-cmGetPropertyCommand::cmGetPropertyCommand()
+namespace {
+enum OutType
 {
-  this->InfoType = OutValue;
+  OutValue,
+  OutDefined,
+  OutBriefDoc,
+  OutFullDoc,
+  OutSet
+};
+
+// Implementation of result storage.
+bool StoreResult(OutType infoType, cmMakefile& makefile,
+                 const std::string& variable, const char* value);
+
+// Implementation of each property type.
+bool HandleGlobalMode(cmExecutionStatus& status, const std::string& name,
+                      OutType infoType, const std::string& variable,
+                      const std::string& propertyName);
+bool HandleDirectoryMode(cmExecutionStatus& status, const std::string& name,
+                         OutType infoType, const std::string& variable,
+                         const std::string& propertyName);
+bool HandleTargetMode(cmExecutionStatus& status, const std::string& name,
+                      OutType infoType, const std::string& variable,
+                      const std::string& propertyName);
+bool HandleSourceMode(cmExecutionStatus& status, const std::string& name,
+                      OutType infoType, const std::string& variable,
+                      const std::string& propertyName);
+bool HandleTestMode(cmExecutionStatus& status, const std::string& name,
+                    OutType infoType, const std::string& variable,
+                    const std::string& propertyName);
+bool HandleVariableMode(cmExecutionStatus& status, const std::string& name,
+                        OutType infoType, const std::string& variable,
+                        const std::string& propertyName);
+bool HandleCacheMode(cmExecutionStatus& status, const std::string& name,
+                     OutType infoType, const std::string& variable,
+                     const std::string& propertyName);
+bool HandleInstallMode(cmExecutionStatus& status, const std::string& name,
+                       OutType infoType, const std::string& variable,
+                       const std::string& propertyName);
 }
 
-bool cmGetPropertyCommand::InitialPass(std::vector<std::string> const& args,
-                                       cmExecutionStatus&)
+bool cmGetPropertyCommand(std::vector<std::string> const& args,
+                          cmExecutionStatus& status)
 {
+  OutType infoType = OutValue;
   if (args.size() < 3) {
-    this->SetError("called with incorrect number of arguments");
+    status.SetError("called with incorrect number of arguments");
     return false;
   }
 
   // The cmake variable in which to store the result.
-  this->Variable = args[0];
+  const std::string variable = args[0];
+
+  std::string name;
+  std::string propertyName;
 
   // Get the scope from which to get the property.
   cmProperty::ScopeType scope;
@@ -62,7 +102,7 @@ bool cmGetPropertyCommand::InitialPass(std::vector<std::string> const& args,
     e << "given invalid scope " << args[1] << ".  "
       << "Valid scopes are "
       << "GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, VARIABLE, CACHE, INSTALL.";
-    this->SetError(e.str());
+    status.SetError(e.str());
     return false;
   }
 
@@ -80,86 +120,92 @@ bool cmGetPropertyCommand::InitialPass(std::vector<std::string> const& args,
       doing = DoingProperty;
     } else if (args[i] == "BRIEF_DOCS") {
       doing = DoingNone;
-      this->InfoType = OutBriefDoc;
+      infoType = OutBriefDoc;
     } else if (args[i] == "FULL_DOCS") {
       doing = DoingNone;
-      this->InfoType = OutFullDoc;
+      infoType = OutFullDoc;
     } else if (args[i] == "SET") {
       doing = DoingNone;
-      this->InfoType = OutSet;
+      infoType = OutSet;
     } else if (args[i] == "DEFINED") {
       doing = DoingNone;
-      this->InfoType = OutDefined;
+      infoType = OutDefined;
     } else if (doing == DoingName) {
       doing = DoingNone;
-      this->Name = args[i];
+      name = args[i];
     } else if (doing == DoingProperty) {
       doing = DoingNone;
-      this->PropertyName = args[i];
+      propertyName = args[i];
     } else {
       std::ostringstream e;
       e << "given invalid argument \"" << args[i] << "\".";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
   }
 
   // Make sure a property name was found.
-  if (this->PropertyName.empty()) {
-    this->SetError("not given a PROPERTY <name> argument.");
+  if (propertyName.empty()) {
+    status.SetError("not given a PROPERTY <name> argument.");
     return false;
   }
 
   // Compute requested output.
-  if (this->InfoType == OutBriefDoc) {
+  if (infoType == OutBriefDoc) {
     // Lookup brief documentation.
     std::string output;
     if (cmPropertyDefinition const* def =
-          this->Makefile->GetState()->GetPropertyDefinition(this->PropertyName,
-                                                            scope)) {
+          status.GetMakefile().GetState()->GetPropertyDefinition(propertyName,
+                                                                 scope)) {
       output = def->GetShortDescription();
     } else {
       output = "NOTFOUND";
     }
-    this->Makefile->AddDefinition(this->Variable, output);
-  } else if (this->InfoType == OutFullDoc) {
+    status.GetMakefile().AddDefinition(variable, output);
+  } else if (infoType == OutFullDoc) {
     // Lookup full documentation.
     std::string output;
     if (cmPropertyDefinition const* def =
-          this->Makefile->GetState()->GetPropertyDefinition(this->PropertyName,
-                                                            scope)) {
+          status.GetMakefile().GetState()->GetPropertyDefinition(propertyName,
+                                                                 scope)) {
       output = def->GetFullDescription();
     } else {
       output = "NOTFOUND";
     }
-    this->Makefile->AddDefinition(this->Variable, output);
-  } else if (this->InfoType == OutDefined) {
+    status.GetMakefile().AddDefinition(variable, output);
+  } else if (infoType == OutDefined) {
     // Lookup if the property is defined
-    if (this->Makefile->GetState()->GetPropertyDefinition(this->PropertyName,
-                                                          scope)) {
-      this->Makefile->AddDefinition(this->Variable, "1");
+    if (status.GetMakefile().GetState()->GetPropertyDefinition(propertyName,
+                                                               scope)) {
+      status.GetMakefile().AddDefinition(variable, "1");
     } else {
-      this->Makefile->AddDefinition(this->Variable, "0");
+      status.GetMakefile().AddDefinition(variable, "0");
     }
   } else {
     // Dispatch property getting.
     switch (scope) {
       case cmProperty::GLOBAL:
-        return this->HandleGlobalMode();
+        return HandleGlobalMode(status, name, infoType, variable,
+                                propertyName);
       case cmProperty::DIRECTORY:
-        return this->HandleDirectoryMode();
+        return HandleDirectoryMode(status, name, infoType, variable,
+                                   propertyName);
       case cmProperty::TARGET:
-        return this->HandleTargetMode();
+        return HandleTargetMode(status, name, infoType, variable,
+                                propertyName);
       case cmProperty::SOURCE_FILE:
-        return this->HandleSourceMode();
+        return HandleSourceMode(status, name, infoType, variable,
+                                propertyName);
       case cmProperty::TEST:
-        return this->HandleTestMode();
+        return HandleTestMode(status, name, infoType, variable, propertyName);
       case cmProperty::VARIABLE:
-        return this->HandleVariableMode();
+        return HandleVariableMode(status, name, infoType, variable,
+                                  propertyName);
       case cmProperty::CACHE:
-        return this->HandleCacheMode();
+        return HandleCacheMode(status, name, infoType, variable, propertyName);
       case cmProperty::INSTALL:
-        return this->HandleInstallMode();
+        return HandleInstallMode(status, name, infoType, variable,
+                                 propertyName);
 
       case cmProperty::CACHED_VARIABLE:
         break; // should never happen
@@ -169,58 +215,65 @@ bool cmGetPropertyCommand::InitialPass(std::vector<std::string> const& args,
   return true;
 }
 
-bool cmGetPropertyCommand::StoreResult(const char* value)
+namespace {
+
+bool StoreResult(OutType infoType, cmMakefile& makefile,
+                 const std::string& variable, const char* value)
 {
-  if (this->InfoType == OutSet) {
-    this->Makefile->AddDefinition(this->Variable, value ? "1" : "0");
-  } else // if(this->InfoType == OutValue)
+  if (infoType == OutSet) {
+    makefile.AddDefinition(variable, value ? "1" : "0");
+  } else // if(infoType == OutValue)
   {
     if (value) {
-      this->Makefile->AddDefinition(this->Variable, value);
+      makefile.AddDefinition(variable, value);
     } else {
-      this->Makefile->RemoveDefinition(this->Variable);
+      makefile.RemoveDefinition(variable);
     }
   }
   return true;
 }
 
-bool cmGetPropertyCommand::HandleGlobalMode()
+bool HandleGlobalMode(cmExecutionStatus& status, const std::string& name,
+                      OutType infoType, const std::string& variable,
+                      const std::string& propertyName)
 {
-  if (!this->Name.empty()) {
-    this->SetError("given name for GLOBAL scope.");
+  if (!name.empty()) {
+    status.SetError("given name for GLOBAL scope.");
     return false;
   }
 
   // Get the property.
-  cmake* cm = this->Makefile->GetCMakeInstance();
-  return this->StoreResult(
-    cm->GetState()->GetGlobalProperty(this->PropertyName));
+  cmake* cm = status.GetMakefile().GetCMakeInstance();
+  return StoreResult(infoType, status.GetMakefile(), variable,
+                     cm->GetState()->GetGlobalProperty(propertyName));
 }
 
-bool cmGetPropertyCommand::HandleDirectoryMode()
+bool HandleDirectoryMode(cmExecutionStatus& status, const std::string& name,
+                         OutType infoType, const std::string& variable,
+                         const std::string& propertyName)
 {
   // Default to the current directory.
-  cmMakefile* mf = this->Makefile;
+  cmMakefile* mf = &status.GetMakefile();
 
   // Lookup the directory if given.
-  if (!this->Name.empty()) {
+  if (!name.empty()) {
     // Construct the directory name.  Interpret relative paths with
     // respect to the current directory.
-    std::string dir = this->Name;
+    std::string dir = name;
     if (!cmSystemTools::FileIsFullPath(dir)) {
-      dir = this->Makefile->GetCurrentSourceDirectory();
+      dir = status.GetMakefile().GetCurrentSourceDirectory();
       dir += "/";
-      dir += this->Name;
+      dir += name;
     }
 
     // The local generators are associated with collapsed paths.
     dir = cmSystemTools::CollapseFullPath(dir);
 
     // Lookup the generator.
-    mf = this->Makefile->GetGlobalGenerator()->FindMakefile(dir);
+    mf = status.GetMakefile().GetGlobalGenerator()->FindMakefile(dir);
     if (!mf) {
       // Could not find the directory.
-      this->SetError(
+      status.SetError(
         "DIRECTORY scope provided but requested directory was not found. "
         "This could be because the directory argument was invalid or, "
         "it is valid but has not been processed yet.");
@@ -228,14 +281,15 @@ bool cmGetPropertyCommand::HandleDirectoryMode()
     }
   }
 
-  if (this->PropertyName == "DEFINITIONS") {
+  if (propertyName == "DEFINITIONS") {
     switch (mf->GetPolicyStatus(cmPolicies::CMP0059)) {
       case cmPolicies::WARN:
         mf->IssueMessage(MessageType::AUTHOR_WARNING,
                          cmPolicies::GetPolicyWarning(cmPolicies::CMP0059));
         CM_FALLTHROUGH;
       case cmPolicies::OLD:
-        return this->StoreResult(mf->GetDefineFlagsCMP0059());
+        return StoreResult(infoType, status.GetMakefile(), variable,
+                           mf->GetDefineFlagsCMP0059());
       case cmPolicies::NEW:
       case cmPolicies::REQUIRED_ALWAYS:
       case cmPolicies::REQUIRED_IF_USED:
@@ -244,124 +298,142 @@ bool cmGetPropertyCommand::HandleDirectoryMode()
   }
 
   // Get the property.
-  return this->StoreResult(mf->GetProperty(this->PropertyName));
+  return StoreResult(infoType, status.GetMakefile(), variable,
+                     mf->GetProperty(propertyName));
 }
 
-bool cmGetPropertyCommand::HandleTargetMode()
+bool HandleTargetMode(cmExecutionStatus& status, const std::string& name,
+                      OutType infoType, const std::string& variable,
+                      const std::string& propertyName)
 {
-  if (this->Name.empty()) {
-    this->SetError("not given name for TARGET scope.");
+  if (name.empty()) {
+    status.SetError("not given name for TARGET scope.");
     return false;
   }
 
-  if (cmTarget* target = this->Makefile->FindTargetToUse(this->Name)) {
-    if (this->PropertyName == "ALIASED_TARGET") {
-      if (this->Makefile->IsAlias(this->Name)) {
-        return this->StoreResult(target->GetName().c_str());
+  if (cmTarget* target = status.GetMakefile().FindTargetToUse(name)) {
+    if (propertyName == "ALIASED_TARGET") {
+      if (status.GetMakefile().IsAlias(name)) {
+        return StoreResult(infoType, status.GetMakefile(), variable,
+                           target->GetName().c_str());
       }
-      return this->StoreResult(nullptr);
+      return StoreResult(infoType, status.GetMakefile(), variable, nullptr);
     }
     const char* prop_cstr = nullptr;
-    cmListFileBacktrace bt = this->Makefile->GetBacktrace();
-    cmMessenger* messenger = this->Makefile->GetMessenger();
+    cmListFileBacktrace bt = status.GetMakefile().GetBacktrace();
+    cmMessenger* messenger = status.GetMakefile().GetMessenger();
     if (cmTargetPropertyComputer::PassesWhitelist(
-          target->GetType(), this->PropertyName, messenger, bt)) {
-      prop_cstr =
-        target->GetComputedProperty(this->PropertyName, messenger, bt);
+          target->GetType(), propertyName, messenger, bt)) {
+      prop_cstr = target->GetComputedProperty(propertyName, messenger, bt);
       if (!prop_cstr) {
-        prop_cstr = target->GetProperty(this->PropertyName);
+        prop_cstr = target->GetProperty(propertyName);
       }
     }
-    return this->StoreResult(prop_cstr);
+    return StoreResult(infoType, status.GetMakefile(), variable, prop_cstr);
   }
   std::ostringstream e;
-  e << "could not find TARGET " << this->Name
+  e << "could not find TARGET " << name
     << ".  Perhaps it has not yet been created.";
-  this->SetError(e.str());
+  status.SetError(e.str());
   return false;
 }
 
-bool cmGetPropertyCommand::HandleSourceMode()
+bool HandleSourceMode(cmExecutionStatus& status, const std::string& name,
+                      OutType infoType, const std::string& variable,
+                      const std::string& propertyName)
 {
-  if (this->Name.empty()) {
-    this->SetError("not given name for SOURCE scope.");
+  if (name.empty()) {
+    status.SetError("not given name for SOURCE scope.");
     return false;
   }
 
   // Get the source file.
-  if (cmSourceFile* sf = this->Makefile->GetOrCreateSource(this->Name)) {
-    return this->StoreResult(sf->GetPropertyForUser(this->PropertyName));
+  if (cmSourceFile* sf = status.GetMakefile().GetOrCreateSource(name)) {
+    return StoreResult(infoType, status.GetMakefile(), variable,
+                       sf->GetPropertyForUser(propertyName));
   }
   std::ostringstream e;
-  e << "given SOURCE name that could not be found or created: " << this->Name;
-  this->SetError(e.str());
+  e << "given SOURCE name that could not be found or created: " << name;
+  status.SetError(e.str());
   return false;
 }
 
-bool cmGetPropertyCommand::HandleTestMode()
+bool HandleTestMode(cmExecutionStatus& status, const std::string& name,
+                    OutType infoType, const std::string& variable,
+                    const std::string& propertyName)
 {
-  if (this->Name.empty()) {
-    this->SetError("not given name for TEST scope.");
+  if (name.empty()) {
+    status.SetError("not given name for TEST scope.");
     return false;
   }
 
   // Loop over all tests looking for matching names.
-  if (cmTest* test = this->Makefile->GetTest(this->Name)) {
-    return this->StoreResult(test->GetProperty(this->PropertyName));
+  if (cmTest* test = status.GetMakefile().GetTest(name)) {
+    return StoreResult(infoType, status.GetMakefile(), variable,
+                       test->GetProperty(propertyName));
   }
 
   // If not found it is an error.
   std::ostringstream e;
-  e << "given TEST name that does not exist: " << this->Name;
-  this->SetError(e.str());
+  e << "given TEST name that does not exist: " << name;
+  status.SetError(e.str());
   return false;
 }
 
-bool cmGetPropertyCommand::HandleVariableMode()
+bool HandleVariableMode(cmExecutionStatus& status, const std::string& name,
+                        OutType infoType, const std::string& variable,
+                        const std::string& propertyName)
 {
-  if (!this->Name.empty()) {
-    this->SetError("given name for VARIABLE scope.");
+  if (!name.empty()) {
+    status.SetError("given name for VARIABLE scope.");
     return false;
   }
 
-  return this->StoreResult(this->Makefile->GetDefinition(this->PropertyName));
+  return StoreResult(infoType, status.GetMakefile(), variable,
+                     status.GetMakefile().GetDefinition(propertyName));
 }
 
-bool cmGetPropertyCommand::HandleCacheMode()
+bool HandleCacheMode(cmExecutionStatus& status, const std::string& name,
+                     OutType infoType, const std::string& variable,
+                     const std::string& propertyName)
 {
-  if (this->Name.empty()) {
-    this->SetError("not given name for CACHE scope.");
+  if (name.empty()) {
+    status.SetError("not given name for CACHE scope.");
     return false;
   }
 
   const char* value = nullptr;
-  if (this->Makefile->GetState()->GetCacheEntryValue(this->Name)) {
-    value = this->Makefile->GetState()->GetCacheEntryProperty(
-      this->Name, this->PropertyName);
+  if (status.GetMakefile().GetState()->GetCacheEntryValue(name)) {
+    value = status.GetMakefile().GetState()->GetCacheEntryProperty(
+      name, propertyName);
   }
-  this->StoreResult(value);
+  StoreResult(infoType, status.GetMakefile(), variable, value);
   return true;
 }
 
-bool cmGetPropertyCommand::HandleInstallMode()
+bool HandleInstallMode(cmExecutionStatus& status, const std::string& name,
+                       OutType infoType, const std::string& variable,
+                       const std::string& propertyName)
 {
-  if (this->Name.empty()) {
-    this->SetError("not given name for INSTALL scope.");
+  if (name.empty()) {
+    status.SetError("not given name for INSTALL scope.");
     return false;
   }
 
   // Get the installed file.
-  cmake* cm = this->Makefile->GetCMakeInstance();
+  cmake* cm = status.GetMakefile().GetCMakeInstance();
 
   if (cmInstalledFile* file =
-        cm->GetOrCreateInstalledFile(this->Makefile, this->Name)) {
+        cm->GetOrCreateInstalledFile(&status.GetMakefile(), name)) {
     std::string value;
-    bool isSet = file->GetProperty(this->PropertyName, value);
+    bool isSet = file->GetProperty(propertyName, value);
 
-    return this->StoreResult(isSet ? value.c_str() : nullptr);
+    return StoreResult(infoType, status.GetMakefile(), variable,
+                       isSet ? value.c_str() : nullptr);
   }
   std::ostringstream e;
-  e << "given INSTALL name that could not be found or created: " << this->Name;
-  this->SetError(e.str());
+  e << "given INSTALL name that could not be found or created: " << name;
+  status.SetError(e.str());
   return false;
 }
+}
diff --git a/Source/cmGetPropertyCommand.h b/Source/cmGetPropertyCommand.h
index 50e4014..cc600f4 100644
--- a/Source/cmGetPropertyCommand.h
+++ b/Source/cmGetPropertyCommand.h
@@ -8,55 +8,9 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-class cmGetPropertyCommand : public cmCommand
-{
-public:
-  cmGetPropertyCommand();
-
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmGetPropertyCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the input file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-
-private:
-  enum OutType
-  {
-    OutValue,
-    OutDefined,
-    OutBriefDoc,
-    OutFullDoc,
-    OutSet
-  };
-  std::string Variable;
-  std::string Name;
-  std::string PropertyName;
-  OutType InfoType;
-
-  // Implementation of result storage.
-  bool StoreResult(const char* value);
-
-  // Implementation of each property type.
-  bool HandleGlobalMode();
-  bool HandleDirectoryMode();
-  bool HandleTargetMode();
-  bool HandleSourceMode();
-  bool HandleTestMode();
-  bool HandleVariableMode();
-  bool HandleCacheMode();
-  bool HandleInstallMode();
-};
+bool cmGetPropertyCommand(std::vector<std::string> const& args,
+                          cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From f42dad7a5e8656b8eee9b9b928ab3ce9ba90fbf8 Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Fri, 2 Aug 2019 18:31:47 +0200
Subject: cmCommand refactor: cmIncludeCommand

---
 Source/cmCommands.cxx       |  2 +-
 Source/cmIncludeCommand.cxx | 49 +++++++++++++++++++++++----------------------
 Source/cmIncludeCommand.h   | 26 +++---------------------
 3 files changed, 29 insertions(+), 48 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 1842ae0..b6008f5 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -142,7 +142,7 @@ void GetScriptingCommands(cmState* state)
                            cmGetFilenameComponentCommand);
   state->AddBuiltinCommand("get_property", cmGetPropertyCommand);
   state->AddBuiltinCommand("if", cmIfCommand);
-  state->AddBuiltinCommand("include", cm::make_unique<cmIncludeCommand>());
+  state->AddBuiltinCommand("include", cmIncludeCommand);
   state->AddBuiltinCommand("include_guard",
                            cm::make_unique<cmIncludeGuardCommand>());
   state->AddBuiltinCommand("list", cm::make_unique<cmListCommand>());
diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx
index 0d608bb..723b633 100644
--- a/Source/cmIncludeCommand.cxx
+++ b/Source/cmIncludeCommand.cxx
@@ -4,21 +4,20 @@
 
 #include <sstream>
 
+#include "cmExecutionStatus.h"
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmPolicies.h"
 #include "cmSystemTools.h"
 
-class cmExecutionStatus;
-
 // cmIncludeCommand
-bool cmIncludeCommand::InitialPass(std::vector<std::string> const& args,
-                                   cmExecutionStatus&)
+bool cmIncludeCommand(std::vector<std::string> const& args,
+                      cmExecutionStatus& status)
 {
   if (args.empty() || args.size() > 4) {
-    this->SetError("called with wrong number of arguments.  "
-                   "include() only takes one file.");
+    status.SetError("called with wrong number of arguments.  "
+                    "include() only takes one file.");
     return false;
   }
   bool optional = false;
@@ -29,20 +28,20 @@ bool cmIncludeCommand::InitialPass(std::vector<std::string> const& args,
   for (unsigned int i = 1; i < args.size(); i++) {
     if (args[i] == "OPTIONAL") {
       if (optional) {
-        this->SetError("called with invalid arguments: OPTIONAL used twice");
+        status.SetError("called with invalid arguments: OPTIONAL used twice");
         return false;
       }
       optional = true;
     } else if (args[i] == "RESULT_VARIABLE") {
       if (!resultVarName.empty()) {
-        this->SetError("called with invalid arguments: "
-                       "only one result variable allowed");
+        status.SetError("called with invalid arguments: "
+                        "only one result variable allowed");
         return false;
       }
       if (++i < args.size()) {
         resultVarName = args[i];
       } else {
-        this->SetError("called with no value for RESULT_VARIABLE.");
+        status.SetError("called with no value for RESULT_VARIABLE.");
         return false;
       }
     } else if (args[i] == "NO_POLICY_SCOPE") {
@@ -52,14 +51,15 @@ bool cmIncludeCommand::InitialPass(std::vector<std::string> const& args,
     {
       std::string errorText = "called with invalid argument: ";
       errorText += args[i];
-      this->SetError(errorText);
+      status.SetError(errorText);
       return false;
     }
   }
 
   if (fname.empty()) {
-    this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING,
-                                 "include() given empty file name (ignored).");
+    status.GetMakefile().IssueMessage(
+      MessageType::AUTHOR_WARNING,
+      "include() given empty file name (ignored).");
     return true;
   }
 
@@ -67,22 +67,22 @@ bool cmIncludeCommand::InitialPass(std::vector<std::string> const& args,
     // Not a path. Maybe module.
     std::string module = fname;
     module += ".cmake";
-    std::string mfile = this->Makefile->GetModulesFile(module);
+    std::string mfile = status.GetMakefile().GetModulesFile(module);
     if (!mfile.empty()) {
       fname = mfile;
     }
   }
 
   std::string fname_abs = cmSystemTools::CollapseFullPath(
-    fname, this->Makefile->GetCurrentSourceDirectory());
+    fname, status.GetMakefile().GetCurrentSourceDirectory());
 
-  cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
+  cmGlobalGenerator* gg = status.GetMakefile().GetGlobalGenerator();
   if (gg->IsExportedTargetsFile(fname_abs)) {
     const char* modal = nullptr;
     std::ostringstream e;
     MessageType messageType = MessageType::AUTHOR_WARNING;
 
-    switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0024)) {
+    switch (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0024)) {
       case cmPolicies::WARN:
         e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0024) << "\n";
         modal = "should";
@@ -102,7 +102,7 @@ bool cmIncludeCommand::InitialPass(std::vector<std::string> const& args,
         << " not be used as the argument to the "
            "include() command.  Use ALIAS targets instead to refer to targets "
            "by alternative names.\n";
-      this->Makefile->IssueMessage(messageType, e.str());
+      status.GetMakefile().IssueMessage(messageType, e.str());
       if (messageType == MessageType::FATAL_ERROR) {
         return false;
       }
@@ -112,27 +112,28 @@ bool cmIncludeCommand::InitialPass(std::vector<std::string> const& args,
   }
 
   std::string listFile = cmSystemTools::CollapseFullPath(
-    fname, this->Makefile->GetCurrentSourceDirectory());
+    fname, status.GetMakefile().GetCurrentSourceDirectory());
   if (optional && !cmSystemTools::FileExists(listFile)) {
     if (!resultVarName.empty()) {
-      this->Makefile->AddDefinition(resultVarName, "NOTFOUND");
+      status.GetMakefile().AddDefinition(resultVarName, "NOTFOUND");
     }
     return true;
   }
 
-  bool readit = this->Makefile->ReadDependentFile(listFile, noPolicyScope);
+  bool readit =
+    status.GetMakefile().ReadDependentFile(listFile, noPolicyScope);
 
   // add the location of the included file if a result variable was given
   if (!resultVarName.empty()) {
-    this->Makefile->AddDefinition(resultVarName,
-                                  readit ? fname_abs.c_str() : "NOTFOUND");
+    status.GetMakefile().AddDefinition(
+      resultVarName, readit ? fname_abs.c_str() : "NOTFOUND");
   }
 
   if (!optional && !readit && !cmSystemTools::GetFatalErrorOccured()) {
     std::string m = "could not find load file:\n"
                     "  ";
     m += fname;
-    this->SetError(m);
+    status.SetError(m);
     return false;
   }
   return true;
diff --git a/Source/cmIncludeCommand.h b/Source/cmIncludeCommand.h
index 94d3fbd..b0dd779 100644
--- a/Source/cmIncludeCommand.h
+++ b/Source/cmIncludeCommand.h
@@ -8,35 +8,15 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmIncludeCommand
+/**
  * \brief cmIncludeCommand defines a list of distant
  *  files that can be "included" in the current list file.
  *  In almost every sense, this is identical to a C/C++
  *  #include command.  Arguments are first expended as usual.
  */
-class cmIncludeCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmIncludeCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-};
+bool cmIncludeCommand(std::vector<std::string> const& args,
+                      cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From ceab7bda44b06fc6fdb842b7a51ccc662c907fb9 Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Fri, 2 Aug 2019 18:35:08 +0200
Subject: cmCommand refactor: cmIncludeGuardCommand

---
 Source/cmCommands.cxx            |  3 +--
 Source/cmIncludeGuardCommand.cxx | 12 ++++++------
 Source/cmIncludeGuardCommand.h   | 26 +++-----------------------
 3 files changed, 10 insertions(+), 31 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index b6008f5..aafbf14 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -143,8 +143,7 @@ void GetScriptingCommands(cmState* state)
   state->AddBuiltinCommand("get_property", cmGetPropertyCommand);
   state->AddBuiltinCommand("if", cmIfCommand);
   state->AddBuiltinCommand("include", cmIncludeCommand);
-  state->AddBuiltinCommand("include_guard",
-                           cm::make_unique<cmIncludeGuardCommand>());
+  state->AddBuiltinCommand("include_guard", cmIncludeGuardCommand);
   state->AddBuiltinCommand("list", cm::make_unique<cmListCommand>());
   state->AddBuiltinCommand("macro", cm::make_unique<cmMacroCommand>());
   state->AddBuiltinCommand("make_directory",
diff --git a/Source/cmIncludeGuardCommand.cxx b/Source/cmIncludeGuardCommand.cxx
index e560910..ccb4496 100644
--- a/Source/cmIncludeGuardCommand.cxx
+++ b/Source/cmIncludeGuardCommand.cxx
@@ -50,11 +50,11 @@ bool CheckIncludeGuardIsSet(cmMakefile* mf, std::string const& includeGuardVar)
 } // anonymous namespace
 
 // cmIncludeGuardCommand
-bool cmIncludeGuardCommand::InitialPass(std::vector<std::string> const& args,
-                                        cmExecutionStatus& status)
+bool cmIncludeGuardCommand(std::vector<std::string> const& args,
+                           cmExecutionStatus& status)
 {
   if (args.size() > 1) {
-    this->SetError(
+    status.SetError(
       "given an invalid number of arguments. The command takes at "
       "most 1 argument.");
     return false;
@@ -69,15 +69,15 @@ bool cmIncludeGuardCommand::InitialPass(std::vector<std::string> const& args,
     } else if (arg == "GLOBAL") {
       scope = GLOBAL;
     } else {
-      this->SetError("given an invalid scope: " + arg);
+      status.SetError("given an invalid scope: " + arg);
       return false;
     }
   }
 
   std::string includeGuardVar = GetIncludeGuardVariableName(
-    this->Makefile->GetDefinition("CMAKE_CURRENT_LIST_FILE"));
+    status.GetMakefile().GetDefinition("CMAKE_CURRENT_LIST_FILE"));
 
-  cmMakefile* const mf = this->Makefile;
+  cmMakefile* const mf = &status.GetMakefile();
 
   switch (scope) {
     case VARIABLE:
diff --git a/Source/cmIncludeGuardCommand.h b/Source/cmIncludeGuardCommand.h
index 4306c4c..b86b760 100644
--- a/Source/cmIncludeGuardCommand.h
+++ b/Source/cmIncludeGuardCommand.h
@@ -8,35 +8,15 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmIncludeGuardCommand
+/**
  * \brief cmIncludeGuardCommand identical to C++ #pragma_once command
  * Can work in 3 modes: GLOBAL (works on global properties),
  * DIRECTORY(use directory property), VARIABLE(unnamed overload without
  * arguments) define an ordinary variable to be used as include guard checker
  */
-class cmIncludeGuardCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmIncludeGuardCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-};
+bool cmIncludeGuardCommand(std::vector<std::string> const& args,
+                           cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From 9ae9f3e77e375c143e5200624f12d15e2bba02d4 Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Fri, 2 Aug 2019 18:42:44 +0200
Subject: cmCommand refactor: cmMacroCommand

---
 Source/cmCommands.cxx     |  2 +-
 Source/cmMacroCommand.cxx | 11 +++++++----
 Source/cmMacroCommand.h   | 24 ++----------------------
 3 files changed, 10 insertions(+), 27 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index aafbf14..08bf182 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -145,7 +145,7 @@ void GetScriptingCommands(cmState* state)
   state->AddBuiltinCommand("include", cmIncludeCommand);
   state->AddBuiltinCommand("include_guard", cmIncludeGuardCommand);
   state->AddBuiltinCommand("list", cm::make_unique<cmListCommand>());
-  state->AddBuiltinCommand("macro", cm::make_unique<cmMacroCommand>());
+  state->AddBuiltinCommand("macro", cmMacroCommand);
   state->AddBuiltinCommand("make_directory",
                            cm::make_unique<cmMakeDirectoryCommand>());
   state->AddBuiltinCommand("mark_as_advanced",
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index 8689c8f..bc3c3ac 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -21,6 +21,8 @@
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 
+namespace {
+
 // define the class for macro commands
 class cmMacroHelperCommand
 {
@@ -178,12 +180,13 @@ bool cmMacroFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
   mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f));
   return true;
 }
+}
 
-bool cmMacroCommand::InitialPass(std::vector<std::string> const& args,
-                                 cmExecutionStatus&)
+bool cmMacroCommand(std::vector<std::string> const& args,
+                    cmExecutionStatus& status)
 {
   if (args.empty()) {
-    this->SetError("called with incorrect number of arguments");
+    status.SetError("called with incorrect number of arguments");
     return false;
   }
 
@@ -191,7 +194,7 @@ bool cmMacroCommand::InitialPass(std::vector<std::string> const& args,
   {
     auto fb = cm::make_unique<cmMacroFunctionBlocker>();
     cmAppend(fb->Args, args);
-    this->Makefile->AddFunctionBlocker(std::move(fb));
+    status.GetMakefile().AddFunctionBlocker(std::move(fb));
   }
   return true;
 }
diff --git a/Source/cmMacroCommand.h b/Source/cmMacroCommand.h
index 0d7083a..25091ea 100644
--- a/Source/cmMacroCommand.h
+++ b/Source/cmMacroCommand.h
@@ -8,30 +8,10 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
 /// Starts macro() ... endmacro() block
-class cmMacroCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmMacroCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-};
+bool cmMacroCommand(std::vector<std::string> const& args,
+                    cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From e0b7ff4af2a8f5a2c2f746c0976cd22367212c8a Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Sun, 4 Aug 2019 14:42:52 +0200
Subject: cmCommand refactor: cmListCommand

---
 Source/cmCommands.cxx    |   2 +-
 Source/cmListCommand.cxx | 415 +++++++++++++++++++++++++++--------------------
 Source/cmListCommand.h   |  51 +-----
 3 files changed, 244 insertions(+), 224 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 08bf182..285c48e 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -144,7 +144,7 @@ void GetScriptingCommands(cmState* state)
   state->AddBuiltinCommand("if", cmIfCommand);
   state->AddBuiltinCommand("include", cmIncludeCommand);
   state->AddBuiltinCommand("include_guard", cmIncludeGuardCommand);
-  state->AddBuiltinCommand("list", cm::make_unique<cmListCommand>());
+  state->AddBuiltinCommand("list", cmListCommand);
   state->AddBuiltinCommand("macro", cmMacroCommand);
   state->AddBuiltinCommand("make_directory",
                            cm::make_unique<cmMakeDirectoryCommand>());
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index cbb1d3a..4db80cd 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -18,6 +18,7 @@
 #include "cm_memory.hxx"
 
 #include "cmAlgorithms.h"
+#include "cmExecutionStatus.h"
 #include "cmGeneratorExpression.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
@@ -27,79 +28,124 @@
 #include "cmStringReplaceHelper.h"
 #include "cmSystemTools.h"
 
-class cmExecutionStatus;
+namespace {
+bool HandleLengthCommand(std::vector<std::string> const& args,
+                         cmExecutionStatus& status);
+bool HandleGetCommand(std::vector<std::string> const& args,
+                      cmExecutionStatus& status);
+bool HandleAppendCommand(std::vector<std::string> const& args,
+                         cmMakefile& makefile);
+bool HandlePrependCommand(std::vector<std::string> const& args,
+                          cmMakefile& makefile);
+bool HandlePopBackCommand(std::vector<std::string> const& args,
+                          cmMakefile& makefile);
+bool HandlePopFrontCommand(std::vector<std::string> const& args,
+                           cmMakefile& makefile);
+bool HandleFindCommand(std::vector<std::string> const& args,
+                       cmExecutionStatus& status);
+bool HandleInsertCommand(std::vector<std::string> const& args,
+                         cmExecutionStatus& status);
+bool HandleJoinCommand(std::vector<std::string> const& args,
+                       cmExecutionStatus& status);
+bool HandleRemoveAtCommand(std::vector<std::string> const& args,
+                           cmExecutionStatus& status);
+bool HandleRemoveItemCommand(std::vector<std::string> const& args,
+                             cmExecutionStatus& status);
+bool HandleRemoveDuplicatesCommand(std::vector<std::string> const& args,
+                                   cmExecutionStatus& status);
+bool HandleTransformCommand(std::vector<std::string> const& args,
+                            cmExecutionStatus& status);
+bool HandleSortCommand(std::vector<std::string> const& args,
+                       cmExecutionStatus& status);
+bool HandleSublistCommand(std::vector<std::string> const& args,
+                          cmExecutionStatus& status);
+bool HandleReverseCommand(std::vector<std::string> const& args,
+                          cmExecutionStatus& status);
+bool HandleFilterCommand(std::vector<std::string> const& args,
+                         cmExecutionStatus& status);
+bool FilterRegex(std::vector<std::string> const& args, bool includeMatches,
+                 std::string const& listName,
+                 std::vector<std::string>& varArgsExpanded,
+                 cmExecutionStatus& status);
+
+bool GetList(std::vector<std::string>& list, const std::string& var,
+             const cmMakefile& makefile);
+bool GetListString(std::string& listString, const std::string& var,
+                   const cmMakefile& makefile);
+}
 
-bool cmListCommand::InitialPass(std::vector<std::string> const& args,
-                                cmExecutionStatus&)
+bool cmListCommand(std::vector<std::string> const& args,
+                   cmExecutionStatus& status)
 {
   if (args.size() < 2) {
-    this->SetError("must be called with at least two arguments.");
+    status.SetError("must be called with at least two arguments.");
     return false;
   }
 
   const std::string& subCommand = args[0];
   if (subCommand == "LENGTH") {
-    return this->HandleLengthCommand(args);
+    return HandleLengthCommand(args, status);
   }
   if (subCommand == "GET") {
-    return this->HandleGetCommand(args);
+    return HandleGetCommand(args, status);
   }
   if (subCommand == "APPEND") {
-    return this->HandleAppendCommand(args);
+    return HandleAppendCommand(args, status.GetMakefile());
   }
   if (subCommand == "PREPEND") {
-    return this->HandlePrependCommand(args);
+    return HandlePrependCommand(args, status.GetMakefile());
   }
   if (subCommand == "POP_BACK") {
-    return this->HandlePopBackCommand(args);
+    return HandlePopBackCommand(args, status.GetMakefile());
   }
   if (subCommand == "POP_FRONT") {
-    return this->HandlePopFrontCommand(args);
+    return HandlePopFrontCommand(args, status.GetMakefile());
   }
   if (subCommand == "FIND") {
-    return this->HandleFindCommand(args);
+    return HandleFindCommand(args, status);
   }
   if (subCommand == "INSERT") {
-    return this->HandleInsertCommand(args);
+    return HandleInsertCommand(args, status);
   }
   if (subCommand == "JOIN") {
-    return this->HandleJoinCommand(args);
+    return HandleJoinCommand(args, status);
   }
   if (subCommand == "REMOVE_AT") {
-    return this->HandleRemoveAtCommand(args);
+    return HandleRemoveAtCommand(args, status);
   }
   if (subCommand == "REMOVE_ITEM") {
-    return this->HandleRemoveItemCommand(args);
+    return HandleRemoveItemCommand(args, status);
   }
   if (subCommand == "REMOVE_DUPLICATES") {
-    return this->HandleRemoveDuplicatesCommand(args);
+    return HandleRemoveDuplicatesCommand(args, status);
   }
   if (subCommand == "TRANSFORM") {
-    return this->HandleTransformCommand(args);
+    return HandleTransformCommand(args, status);
   }
   if (subCommand == "SORT") {
-    return this->HandleSortCommand(args);
+    return HandleSortCommand(args, status);
   }
   if (subCommand == "SUBLIST") {
-    return this->HandleSublistCommand(args);
+    return HandleSublistCommand(args, status);
   }
   if (subCommand == "REVERSE") {
-    return this->HandleReverseCommand(args);
+    return HandleReverseCommand(args, status);
   }
   if (subCommand == "FILTER") {
-    return this->HandleFilterCommand(args);
+    return HandleFilterCommand(args, status);
   }
 
   std::string e = "does not recognize sub-command " + subCommand;
-  this->SetError(e);
+  status.SetError(e);
   return false;
 }
 
-bool cmListCommand::GetListString(std::string& listString,
-                                  const std::string& var)
+namespace {
+bool GetListString(std::string& listString, const std::string& var,
+                   const cmMakefile& makefile)
 {
   // get the old value
-  const char* cacheValue = this->Makefile->GetDefinition(var);
+  const char* cacheValue = makefile.GetDefinition(var);
   if (!cacheValue) {
     return false;
   }
@@ -107,11 +153,11 @@ bool cmListCommand::GetListString(std::string& listString,
   return true;
 }
 
-bool cmListCommand::GetList(std::vector<std::string>& list,
-                            const std::string& var)
+bool GetList(std::vector<std::string>& list, const std::string& var,
+             const cmMakefile& makefile)
 {
   std::string listString;
-  if (!this->GetListString(listString, var)) {
+  if (!GetListString(listString, var, makefile)) {
     return false;
   }
   // if the size of the list
@@ -125,7 +171,7 @@ bool cmListCommand::GetList(std::vector<std::string>& list,
     return true;
   }
   // if we have empty elements we need to check policy CMP0007
-  switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0007)) {
+  switch (makefile.GetPolicyStatus(cmPolicies::CMP0007)) {
     case cmPolicies::WARN: {
       // Default is to warn and use old behavior
       // OLD behavior is to allow compatibility, so recall
@@ -137,7 +183,7 @@ bool cmListCommand::GetList(std::vector<std::string>& list,
       warn += " List has value = [";
       warn += listString;
       warn += "].";
-      this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, warn);
+      makefile.IssueMessage(MessageType::AUTHOR_WARNING, warn);
       return true;
     }
     case cmPolicies::OLD:
@@ -151,7 +197,7 @@ bool cmListCommand::GetList(std::vector<std::string>& list,
       return true;
     case cmPolicies::REQUIRED_IF_USED:
     case cmPolicies::REQUIRED_ALWAYS:
-      this->Makefile->IssueMessage(
+      makefile.IssueMessage(
         MessageType::FATAL_ERROR,
         cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0007));
       return false;
@@ -159,10 +205,11 @@ bool cmListCommand::GetList(std::vector<std::string>& list,
   return true;
 }
 
-bool cmListCommand::HandleLengthCommand(std::vector<std::string> const& args)
+bool HandleLengthCommand(std::vector<std::string> const& args,
+                         cmExecutionStatus& status)
 {
   if (args.size() != 3) {
-    this->SetError("sub-command LENGTH requires two arguments.");
+    status.SetError("sub-command LENGTH requires two arguments.");
     return false;
   }
 
@@ -172,19 +219,20 @@ bool cmListCommand::HandleLengthCommand(std::vector<std::string> const& args)
   // do not check the return value here
   // if the list var is not found varArgsExpanded will have size 0
   // and we will return 0
-  this->GetList(varArgsExpanded, listName);
+  GetList(varArgsExpanded, listName, status.GetMakefile());
   size_t length = varArgsExpanded.size();
   char buffer[1024];
   sprintf(buffer, "%d", static_cast<int>(length));
 
-  this->Makefile->AddDefinition(variableName, buffer);
+  status.GetMakefile().AddDefinition(variableName, buffer);
   return true;
 }
 
-bool cmListCommand::HandleGetCommand(std::vector<std::string> const& args)
+bool HandleGetCommand(std::vector<std::string> const& args,
+                      cmExecutionStatus& status)
 {
   if (args.size() < 4) {
-    this->SetError("sub-command GET requires at least three arguments.");
+    status.SetError("sub-command GET requires at least three arguments.");
     return false;
   }
 
@@ -192,13 +240,13 @@ bool cmListCommand::HandleGetCommand(std::vector<std::string> const& args)
   const std::string& variableName = args.back();
   // expand the variable
   std::vector<std::string> varArgsExpanded;
-  if (!this->GetList(varArgsExpanded, listName)) {
-    this->Makefile->AddDefinition(variableName, "NOTFOUND");
+  if (!GetList(varArgsExpanded, listName, status.GetMakefile())) {
+    status.GetMakefile().AddDefinition(variableName, "NOTFOUND");
     return true;
   }
   // FIXME: Add policy to make non-existing lists an error like empty lists.
   if (varArgsExpanded.empty()) {
-    this->SetError("GET given empty list");
+    status.SetError("GET given empty list");
     return false;
   }
 
@@ -217,17 +265,18 @@ bool cmListCommand::HandleGetCommand(std::vector<std::string> const& args)
       std::ostringstream str;
       str << "index: " << item << " out of range (-" << nitem << ", "
           << nitem - 1 << ")";
-      this->SetError(str.str());
+      status.SetError(str.str());
       return false;
     }
     value += varArgsExpanded[item];
   }
 
-  this->Makefile->AddDefinition(variableName, value);
+  status.GetMakefile().AddDefinition(variableName, value);
   return true;
 }
 
-bool cmListCommand::HandleAppendCommand(std::vector<std::string> const& args)
+bool HandleAppendCommand(std::vector<std::string> const& args,
+                         cmMakefile& makefile)
 {
   assert(args.size() >= 2);
 
@@ -239,7 +288,7 @@ bool cmListCommand::HandleAppendCommand(std::vector<std::string> const& args)
   std::string const& listName = args[1];
   // expand the variable
   std::string listString;
-  this->GetListString(listString, listName);
+  GetListString(listString, listName, makefile);
 
   // If `listString` or `args` is empty, no need to append `;`,
   // then index is going to be `1` and points to the end-of-string ";"
@@ -247,11 +296,12 @@ bool cmListCommand::HandleAppendCommand(std::vector<std::string> const& args)
     std::string::size_type(listString.empty() || args.empty());
   listString += &";"[offset] + cmJoin(cmMakeRange(args).advance(2), ";");
 
-  this->Makefile->AddDefinition(listName, listString);
+  makefile.AddDefinition(listName, listString);
   return true;
 }
 
-bool cmListCommand::HandlePrependCommand(std::vector<std::string> const& args)
+bool HandlePrependCommand(std::vector<std::string> const& args,
+                          cmMakefile& makefile)
 {
   assert(args.size() >= 2);
 
@@ -263,7 +313,7 @@ bool cmListCommand::HandlePrependCommand(std::vector<std::string> const& args)
   std::string const& listName = args[1];
   // expand the variable
   std::string listString;
-  this->GetListString(listString, listName);
+  GetListString(listString, listName, makefile);
 
   // If `listString` or `args` is empty, no need to append `;`,
   // then `offset` is going to be `1` and points to the end-of-string ";"
@@ -272,11 +322,12 @@ bool cmListCommand::HandlePrependCommand(std::vector<std::string> const& args)
   listString.insert(0,
                     cmJoin(cmMakeRange(args).advance(2), ";") + &";"[offset]);
 
-  this->Makefile->AddDefinition(listName, listString);
+  makefile.AddDefinition(listName, listString);
   return true;
 }
 
-bool cmListCommand::HandlePopBackCommand(std::vector<std::string> const& args)
+bool HandlePopBackCommand(std::vector<std::string> const& args,
+                          cmMakefile& makefile)
 {
   assert(args.size() >= 2);
 
@@ -284,10 +335,10 @@ bool cmListCommand::HandlePopBackCommand(std::vector<std::string> const& args)
   ++ai; // Skip subcommand name
   std::string const& listName = *ai++;
   std::vector<std::string> varArgsExpanded;
-  if (!this->GetList(varArgsExpanded, listName)) {
+  if (!GetList(varArgsExpanded, listName, makefile)) {
     // Can't get the list definition... undefine any vars given after.
     for (; ai != args.cend(); ++ai) {
-      this->Makefile->RemoveDefinition(*ai);
+      makefile.RemoveDefinition(*ai);
     }
     return true;
   }
@@ -300,29 +351,30 @@ bool cmListCommand::HandlePopBackCommand(std::vector<std::string> const& args)
       // Ok, assign elements to be removed to the given variables
       for (; !varArgsExpanded.empty() && ai != args.cend(); ++ai) {
         assert(!ai->empty());
-        this->Makefile->AddDefinition(*ai, varArgsExpanded.back());
+        makefile.AddDefinition(*ai, varArgsExpanded.back());
         varArgsExpanded.pop_back();
       }
       // Undefine the rest variables if the list gets empty earlier...
       for (; ai != args.cend(); ++ai) {
-        this->Makefile->RemoveDefinition(*ai);
+        makefile.RemoveDefinition(*ai);
       }
     }
 
-    this->Makefile->AddDefinition(listName, cmJoin(varArgsExpanded, ";"));
+    makefile.AddDefinition(listName, cmJoin(varArgsExpanded, ";"));
 
   } else if (ai !=
              args.cend()) { // The list is empty, but some args were given
     // Need to *undefine* 'em all, cuz there are no items to assign...
     for (; ai != args.cend(); ++ai) {
-      this->Makefile->RemoveDefinition(*ai);
+      makefile.RemoveDefinition(*ai);
     }
   }
 
   return true;
 }
 
-bool cmListCommand::HandlePopFrontCommand(std::vector<std::string> const& args)
+bool HandlePopFrontCommand(std::vector<std::string> const& args,
+                           cmMakefile& makefile)
 {
   assert(args.size() >= 2);
 
@@ -330,10 +382,10 @@ bool cmListCommand::HandlePopFrontCommand(std::vector<std::string> const& args)
   ++ai; // Skip subcommand name
   std::string const& listName = *ai++;
   std::vector<std::string> varArgsExpanded;
-  if (!this->GetList(varArgsExpanded, listName)) {
+  if (!GetList(varArgsExpanded, listName, makefile)) {
     // Can't get the list definition... undefine any vars given after.
     for (; ai != args.cend(); ++ai) {
-      this->Makefile->RemoveDefinition(*ai);
+      makefile.RemoveDefinition(*ai);
     }
     return true;
   }
@@ -347,32 +399,33 @@ bool cmListCommand::HandlePopFrontCommand(std::vector<std::string> const& args)
       auto vi = varArgsExpanded.begin();
       for (; vi != varArgsExpanded.end() && ai != args.cend(); ++ai, ++vi) {
         assert(!ai->empty());
-        this->Makefile->AddDefinition(*ai, *vi);
+        makefile.AddDefinition(*ai, *vi);
       }
       varArgsExpanded.erase(varArgsExpanded.begin(), vi);
       // Undefine the rest variables if the list gets empty earlier...
       for (; ai != args.cend(); ++ai) {
-        this->Makefile->RemoveDefinition(*ai);
+        makefile.RemoveDefinition(*ai);
       }
     }
 
-    this->Makefile->AddDefinition(listName, cmJoin(varArgsExpanded, ";"));
+    makefile.AddDefinition(listName, cmJoin(varArgsExpanded, ";"));
 
   } else if (ai !=
              args.cend()) { // The list is empty, but some args were given
     // Need to *undefine* 'em all, cuz there are no items to assign...
     for (; ai != args.cend(); ++ai) {
-      this->Makefile->RemoveDefinition(*ai);
+      makefile.RemoveDefinition(*ai);
     }
   }
 
   return true;
 }
 
-bool cmListCommand::HandleFindCommand(std::vector<std::string> const& args)
+bool HandleFindCommand(std::vector<std::string> const& args,
+                       cmExecutionStatus& status)
 {
   if (args.size() != 4) {
-    this->SetError("sub-command FIND requires three arguments.");
+    status.SetError("sub-command FIND requires three arguments.");
     return false;
   }
 
@@ -380,8 +433,8 @@ bool cmListCommand::HandleFindCommand(std::vector<std::string> const& args)
   const std::string& variableName = args.back();
   // expand the variable
   std::vector<std::string> varArgsExpanded;
-  if (!this->GetList(varArgsExpanded, listName)) {
-    this->Makefile->AddDefinition(variableName, "-1");
+  if (!GetList(varArgsExpanded, listName, status.GetMakefile())) {
+    status.GetMakefile().AddDefinition(variableName, "-1");
     return true;
   }
 
@@ -390,18 +443,19 @@ bool cmListCommand::HandleFindCommand(std::vector<std::string> const& args)
   if (it != varArgsExpanded.end()) {
     std::ostringstream indexStream;
     indexStream << std::distance(varArgsExpanded.begin(), it);
-    this->Makefile->AddDefinition(variableName, indexStream.str());
+    status.GetMakefile().AddDefinition(variableName, indexStream.str());
     return true;
   }
 
-  this->Makefile->AddDefinition(variableName, "-1");
+  status.GetMakefile().AddDefinition(variableName, "-1");
   return true;
 }
 
-bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args)
+bool HandleInsertCommand(std::vector<std::string> const& args,
+                         cmExecutionStatus& status)
 {
   if (args.size() < 4) {
-    this->SetError("sub-command INSERT requires at least three arguments.");
+    status.SetError("sub-command INSERT requires at least three arguments.");
     return false;
   }
 
@@ -410,11 +464,12 @@ bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args)
   // expand the variable
   int item = atoi(args[2].c_str());
   std::vector<std::string> varArgsExpanded;
-  if ((!this->GetList(varArgsExpanded, listName) || varArgsExpanded.empty()) &&
+  if ((!GetList(varArgsExpanded, listName, status.GetMakefile()) ||
+       varArgsExpanded.empty()) &&
       item != 0) {
     std::ostringstream str;
     str << "index: " << item << " out of range (0, 0)";
-    this->SetError(str.str());
+    status.SetError(str.str());
     return false;
   }
 
@@ -427,7 +482,7 @@ bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args)
       std::ostringstream str;
       str << "index: " << item << " out of range (-" << varArgsExpanded.size()
           << ", " << varArgsExpanded.size() << ")";
-      this->SetError(str.str());
+      status.SetError(str.str());
       return false;
     }
   }
@@ -436,17 +491,18 @@ bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args)
                          args.end());
 
   std::string value = cmJoin(varArgsExpanded, ";");
-  this->Makefile->AddDefinition(listName, value);
+  status.GetMakefile().AddDefinition(listName, value);
   return true;
 }
 
-bool cmListCommand::HandleJoinCommand(std::vector<std::string> const& args)
+bool HandleJoinCommand(std::vector<std::string> const& args,
+                       cmExecutionStatus& status)
 {
   if (args.size() != 4) {
     std::ostringstream error;
     error << "sub-command JOIN requires three arguments (" << args.size() - 1
           << " found).";
-    this->SetError(error.str());
+    status.SetError(error.str());
     return false;
   }
 
@@ -456,30 +512,30 @@ bool cmListCommand::HandleJoinCommand(std::vector<std::string> const& args)
 
   // expand the variable
   std::vector<std::string> varArgsExpanded;
-  if (!this->GetList(varArgsExpanded, listName)) {
-    this->Makefile->AddDefinition(variableName, "");
+  if (!GetList(varArgsExpanded, listName, status.GetMakefile())) {
+    status.GetMakefile().AddDefinition(variableName, "");
     return true;
   }
 
   std::string value =
     cmJoin(cmMakeRange(varArgsExpanded.begin(), varArgsExpanded.end()), glue);
 
-  this->Makefile->AddDefinition(variableName, value);
+  status.GetMakefile().AddDefinition(variableName, value);
   return true;
 }
 
-bool cmListCommand::HandleRemoveItemCommand(
-  std::vector<std::string> const& args)
+bool HandleRemoveItemCommand(std::vector<std::string> const& args,
+                             cmExecutionStatus& status)
 {
   if (args.size() < 3) {
-    this->SetError("sub-command REMOVE_ITEM requires two or more arguments.");
+    status.SetError("sub-command REMOVE_ITEM requires two or more arguments.");
     return false;
   }
 
   const std::string& listName = args[1];
   // expand the variable
   std::vector<std::string> varArgsExpanded;
-  if (!this->GetList(varArgsExpanded, listName)) {
+  if (!GetList(varArgsExpanded, listName, status.GetMakefile())) {
     return true;
   }
 
@@ -493,44 +549,45 @@ bool cmListCommand::HandleRemoveItemCommand(
     cmRemoveMatching(varArgsExpanded, cmMakeRange(remBegin, remEnd));
   std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin();
   std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";");
-  this->Makefile->AddDefinition(listName, value);
+  status.GetMakefile().AddDefinition(listName, value);
   return true;
 }
 
-bool cmListCommand::HandleReverseCommand(std::vector<std::string> const& args)
+bool HandleReverseCommand(std::vector<std::string> const& args,
+                          cmExecutionStatus& status)
 {
   assert(args.size() >= 2);
   if (args.size() > 2) {
-    this->SetError("sub-command REVERSE only takes one argument.");
+    status.SetError("sub-command REVERSE only takes one argument.");
     return false;
   }
 
   const std::string& listName = args[1];
   // expand the variable
   std::vector<std::string> varArgsExpanded;
-  if (!this->GetList(varArgsExpanded, listName)) {
+  if (!GetList(varArgsExpanded, listName, status.GetMakefile())) {
     return true;
   }
 
   std::string value = cmJoin(cmReverseRange(varArgsExpanded), ";");
 
-  this->Makefile->AddDefinition(listName, value);
+  status.GetMakefile().AddDefinition(listName, value);
   return true;
 }
 
-bool cmListCommand::HandleRemoveDuplicatesCommand(
-  std::vector<std::string> const& args)
+bool HandleRemoveDuplicatesCommand(std::vector<std::string> const& args,
+                                   cmExecutionStatus& status)
 {
   assert(args.size() >= 2);
   if (args.size() > 2) {
-    this->SetError("sub-command REMOVE_DUPLICATES only takes one argument.");
+    status.SetError("sub-command REMOVE_DUPLICATES only takes one argument.");
     return false;
   }
 
   const std::string& listName = args[1];
   // expand the variable
   std::vector<std::string> varArgsExpanded;
-  if (!this->GetList(varArgsExpanded, listName)) {
+  if (!GetList(varArgsExpanded, listName, status.GetMakefile())) {
     return true;
   }
 
@@ -539,12 +596,11 @@ bool cmListCommand::HandleRemoveDuplicatesCommand(
   std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin();
   std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";");
 
-  this->Makefile->AddDefinition(listName, value);
+  status.GetMakefile().AddDefinition(listName, value);
   return true;
 }
 
 // Helpers for list(TRANSFORM <list> ...)
-namespace {
 using transform_type = std::function<std::string(const std::string&)>;
 
 class transform_error : public std::runtime_error
@@ -759,13 +815,12 @@ public:
 private:
   cmStringReplaceHelper ReplaceHelper;
 };
-}
 
-bool cmListCommand::HandleTransformCommand(
-  std::vector<std::string> const& args)
+bool HandleTransformCommand(std::vector<std::string> const& args,
+                            cmExecutionStatus& status)
 {
   if (args.size() < 3) {
-    this->SetError(
+    status.SetError(
       "sub-command TRANSFORM requires an action to be specified.");
     return false;
   }
@@ -888,7 +943,7 @@ bool cmListCommand::HandleTransformCommand(
   if (descriptor == descriptors.end()) {
     std::ostringstream error;
     error << " sub-command TRANSFORM, " << args[index] << " invalid action.";
-    this->SetError(error.str());
+    status.SetError(error.str());
     return false;
   }
 
@@ -898,7 +953,7 @@ bool cmListCommand::HandleTransformCommand(
     std::ostringstream error;
     error << "sub-command TRANSFORM, action " << descriptor->Name
           << " expects " << descriptor->Arity << " argument(s).";
-    this->SetError(error.str());
+    status.SetError(error.str());
     return false;
   }
 
@@ -911,10 +966,10 @@ bool cmListCommand::HandleTransformCommand(
 
   if (command.Name == "REPLACE") {
     try {
-      command.Action =
-        cm::make_unique<TransformReplace>(command.Arguments, this->Makefile);
+      command.Action = cm::make_unique<TransformReplace>(
+        command.Arguments, &status.GetMakefile());
     } catch (const transform_error& e) {
-      this->SetError(e.what());
+      status.SetError(e.what());
       return false;
     }
   }
@@ -929,15 +984,15 @@ bool cmListCommand::HandleTransformCommand(
       std::ostringstream error;
       error << "sub-command TRANSFORM, selector already specified ("
             << command.Selector->Tag << ").";
-      this->SetError(error.str());
+      status.SetError(error.str());
       return false;
     }
 
     // REGEX selector
     if (args[index] == REGEX) {
       if (args.size() == ++index) {
-        this->SetError("sub-command TRANSFORM, selector REGEX expects "
-                       "'regular expression' argument.");
+        status.SetError("sub-command TRANSFORM, selector REGEX expects "
+                        "'regular expression' argument.");
         return false;
       }
 
@@ -947,7 +1002,7 @@ bool cmListCommand::HandleTransformCommand(
         error << "sub-command TRANSFORM, selector REGEX failed to compile "
                  "regex \"";
         error << args[index] << "\".";
-        this->SetError(error.str());
+        status.SetError(error.str());
         return false;
       }
 
@@ -977,7 +1032,7 @@ bool cmListCommand::HandleTransformCommand(
       }
 
       if (indexes.empty()) {
-        this->SetError(
+        status.SetError(
           "sub-command TRANSFORM, selector AT expects at least one "
           "numeric value.");
         return false;
@@ -992,8 +1047,9 @@ bool cmListCommand::HandleTransformCommand(
     // FOR selector
     if (args[index] == FOR) {
       if (args.size() <= ++index + 1) {
-        this->SetError("sub-command TRANSFORM, selector FOR expects, at least,"
-                       " two arguments.");
+        status.SetError(
+          "sub-command TRANSFORM, selector FOR expects, at least,"
+          " two arguments.");
         return false;
       }
 
@@ -1018,8 +1074,8 @@ bool cmListCommand::HandleTransformCommand(
         valid = false;
       }
       if (!valid) {
-        this->SetError("sub-command TRANSFORM, selector FOR expects, "
-                       "at least, two numeric values.");
+        status.SetError("sub-command TRANSFORM, selector FOR expects, "
+                        "at least, two numeric values.");
         return false;
       }
       // try to read a third numeric value for step
@@ -1040,8 +1096,8 @@ bool cmListCommand::HandleTransformCommand(
       }
 
       if (step < 0) {
-        this->SetError("sub-command TRANSFORM, selector FOR expects "
-                       "non negative numeric value for <step>.");
+        status.SetError("sub-command TRANSFORM, selector FOR expects "
+                        "non negative numeric value for <step>.");
       }
 
       command.Selector =
@@ -1053,8 +1109,8 @@ bool cmListCommand::HandleTransformCommand(
     // output variable
     if (args[index] == OUTPUT_VARIABLE) {
       if (args.size() == ++index) {
-        this->SetError("sub-command TRANSFORM, OUTPUT_VARIABLE "
-                       "expects variable name argument.");
+        status.SetError("sub-command TRANSFORM, OUTPUT_VARIABLE "
+                        "expects variable name argument.");
         return false;
       }
 
@@ -1066,14 +1122,14 @@ bool cmListCommand::HandleTransformCommand(
     error << "sub-command TRANSFORM, '"
           << cmJoin(cmMakeRange(args).advance(index), " ")
           << "': unexpected argument(s).";
-    this->SetError(error.str());
+    status.SetError(error.str());
     return false;
   }
 
   // expand the list variable
   std::vector<std::string> varArgsExpanded;
-  if (!this->GetList(varArgsExpanded, command.ListName)) {
-    this->Makefile->AddDefinition(command.OutputName, "");
+  if (!GetList(varArgsExpanded, command.ListName, status.GetMakefile())) {
+    status.GetMakefile().AddDefinition(command.OutputName, "");
     return true;
   }
 
@@ -1085,12 +1141,12 @@ bool cmListCommand::HandleTransformCommand(
   try {
     command.Selector->Transform(varArgsExpanded, descriptor->Transform);
   } catch (const transform_error& e) {
-    this->SetError(e.what());
+    status.SetError(e.what());
     return false;
   }
 
-  this->Makefile->AddDefinition(command.OutputName,
-                                cmJoin(varArgsExpanded, ";"));
+  status.GetMakefile().AddDefinition(command.OutputName,
+                                     cmJoin(varArgsExpanded, ";"));
 
   return true;
 }
@@ -1170,11 +1226,12 @@ protected:
   bool descending;
 };
 
-bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args)
+bool HandleSortCommand(std::vector<std::string> const& args,
+                       cmExecutionStatus& status)
 {
   assert(args.size() >= 2);
   if (args.size() > 8) {
-    this->SetError("sub-command SORT only takes up to six arguments.");
+    status.SetError("sub-command SORT only takes up to six arguments.");
     return false;
   }
 
@@ -1191,7 +1248,7 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args)
       if (sortCompare != cmStringSorter::Compare::UNINITIALIZED) {
         std::string error = cmStrCat(messageHint, "option \"", option,
                                      "\" has been specified multiple times.");
-        this->SetError(error);
+        status.SetError(error);
         return false;
       }
       if (argumentIndex < args.size()) {
@@ -1204,19 +1261,19 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args)
           std::string error =
             cmStrCat(messageHint, "value \"", argument, "\" for option \"",
                      option, "\" is invalid.");
-          this->SetError(error);
+          status.SetError(error);
           return false;
         }
       } else {
-        this->SetError(cmStrCat(messageHint, "missing argument for option \"",
-                                option, "\"."));
+        status.SetError(cmStrCat(messageHint, "missing argument for option \"",
+                                 option, "\"."));
         return false;
       }
     } else if (option == "CASE") {
       if (sortCaseSensitivity !=
           cmStringSorter::CaseSensitivity::UNINITIALIZED) {
-        this->SetError(cmStrCat(messageHint, "option \"", option,
-                                "\" has been specified multiple times."));
+        status.SetError(cmStrCat(messageHint, "option \"", option,
+                                 "\" has been specified multiple times."));
         return false;
       }
       if (argumentIndex < args.size()) {
@@ -1226,21 +1283,21 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args)
         } else if (argument == "INSENSITIVE") {
           sortCaseSensitivity = cmStringSorter::CaseSensitivity::INSENSITIVE;
         } else {
-          this->SetError(cmStrCat(messageHint, "value \"", argument,
-                                  "\" for option \"", option,
-                                  "\" is invalid."));
+          status.SetError(cmStrCat(messageHint, "value \"", argument,
+                                   "\" for option \"", option,
+                                   "\" is invalid."));
           return false;
         }
       } else {
-        this->SetError(cmStrCat(messageHint, "missing argument for option \"",
-                                option, "\"."));
+        status.SetError(cmStrCat(messageHint, "missing argument for option \"",
+                                 option, "\"."));
         return false;
       }
     } else if (option == "ORDER") {
 
       if (sortOrder != cmStringSorter::Order::UNINITIALIZED) {
-        this->SetError(cmStrCat(messageHint, "option \"", option,
-                                "\" has been specified multiple times."));
+        status.SetError(cmStrCat(messageHint, "option \"", option,
+                                 "\" has been specified multiple times."));
         return false;
       }
       if (argumentIndex < args.size()) {
@@ -1250,18 +1307,18 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args)
         } else if (argument == "DESCENDING") {
           sortOrder = cmStringSorter::Order::DESCENDING;
         } else {
-          this->SetError(cmStrCat(messageHint, "value \"", argument,
-                                  "\" for option \"", option,
-                                  "\" is invalid."));
+          status.SetError(cmStrCat(messageHint, "value \"", argument,
+                                   "\" for option \"", option,
+                                   "\" is invalid."));
           return false;
         }
       } else {
-        this->SetError(cmStrCat(messageHint, "missing argument for option \"",
-                                option, "\"."));
+        status.SetError(cmStrCat(messageHint, "missing argument for option \"",
+                                 option, "\"."));
         return false;
       }
     } else {
-      this->SetError(
+      status.SetError(
         cmStrCat(messageHint, "option \"", option, "\" is unknown."));
       return false;
     }
@@ -1280,7 +1337,7 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args)
   const std::string& listName = args[1];
   // expand the variable
   std::vector<std::string> varArgsExpanded;
-  if (!this->GetList(varArgsExpanded, listName)) {
+  if (!GetList(varArgsExpanded, listName, status.GetMakefile())) {
     return true;
   }
 
@@ -1294,17 +1351,18 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args)
   }
 
   std::string value = cmJoin(varArgsExpanded, ";");
-  this->Makefile->AddDefinition(listName, value);
+  status.GetMakefile().AddDefinition(listName, value);
   return true;
 }
 
-bool cmListCommand::HandleSublistCommand(std::vector<std::string> const& args)
+bool HandleSublistCommand(std::vector<std::string> const& args,
+                          cmExecutionStatus& status)
 {
   if (args.size() != 5) {
     std::ostringstream error;
     error << "sub-command SUBLIST requires four arguments (" << args.size() - 1
           << " found).";
-    this->SetError(error.str());
+    status.SetError(error.str());
     return false;
   }
 
@@ -1313,8 +1371,9 @@ bool cmListCommand::HandleSublistCommand(std::vector<std::string> const& args)
 
   // expand the variable
   std::vector<std::string> varArgsExpanded;
-  if (!this->GetList(varArgsExpanded, listName) || varArgsExpanded.empty()) {
-    this->Makefile->AddDefinition(variableName, "");
+  if (!GetList(varArgsExpanded, listName, status.GetMakefile()) ||
+      varArgsExpanded.empty()) {
+    status.GetMakefile().AddDefinition(variableName, "");
     return true;
   }
 
@@ -1327,13 +1386,13 @@ bool cmListCommand::HandleSublistCommand(std::vector<std::string> const& args)
     std::ostringstream error;
     error << "begin index: " << start << " is out of range 0 - "
           << varArgsExpanded.size() - 1;
-    this->SetError(error.str());
+    status.SetError(error.str());
     return false;
   }
   if (length < -1) {
     std::ostringstream error;
     error << "length: " << length << " should be -1 or greater";
-    this->SetError(error.str());
+    status.SetError(error.str());
     return false;
   }
 
@@ -1343,22 +1402,24 @@ bool cmListCommand::HandleSublistCommand(std::vector<std::string> const& args)
     : size_type(start + length);
   std::vector<std::string> sublist(varArgsExpanded.begin() + start,
                                    varArgsExpanded.begin() + end);
-  this->Makefile->AddDefinition(variableName, cmJoin(sublist, ";"));
+  status.GetMakefile().AddDefinition(variableName, cmJoin(sublist, ";"));
   return true;
 }
 
-bool cmListCommand::HandleRemoveAtCommand(std::vector<std::string> const& args)
+bool HandleRemoveAtCommand(std::vector<std::string> const& args,
+                           cmExecutionStatus& status)
 {
   if (args.size() < 3) {
-    this->SetError("sub-command REMOVE_AT requires at least "
-                   "two arguments.");
+    status.SetError("sub-command REMOVE_AT requires at least "
+                    "two arguments.");
     return false;
   }
 
   const std::string& listName = args[1];
   // expand the variable
   std::vector<std::string> varArgsExpanded;
-  if (!this->GetList(varArgsExpanded, listName) || varArgsExpanded.empty()) {
+  if (!GetList(varArgsExpanded, listName, status.GetMakefile()) ||
+      varArgsExpanded.empty()) {
     std::ostringstream str;
     str << "index: ";
     for (size_t i = 1; i < args.size(); ++i) {
@@ -1368,7 +1429,7 @@ bool cmListCommand::HandleRemoveAtCommand(std::vector<std::string> const& args)
       }
     }
     str << " out of range (0, 0)";
-    this->SetError(str.str());
+    status.SetError(str.str());
     return false;
   }
 
@@ -1384,7 +1445,7 @@ bool cmListCommand::HandleRemoveAtCommand(std::vector<std::string> const& args)
       std::ostringstream str;
       str << "index: " << item << " out of range (-" << nitem << ", "
           << nitem - 1 << ")";
-      this->SetError(str.str());
+      status.SetError(str.str());
       return false;
     }
     removed.push_back(static_cast<size_t>(item));
@@ -1400,24 +1461,26 @@ bool cmListCommand::HandleRemoveAtCommand(std::vector<std::string> const& args)
   std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin();
   std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";");
 
-  this->Makefile->AddDefinition(listName, value);
+  status.GetMakefile().AddDefinition(listName, value);
   return true;
 }
 
-bool cmListCommand::HandleFilterCommand(std::vector<std::string> const& args)
+bool HandleFilterCommand(std::vector<std::string> const& args,
+                         cmExecutionStatus& status)
 {
   if (args.size() < 2) {
-    this->SetError("sub-command FILTER requires a list to be specified.");
+    status.SetError("sub-command FILTER requires a list to be specified.");
     return false;
   }
 
   if (args.size() < 3) {
-    this->SetError("sub-command FILTER requires an operator to be specified.");
+    status.SetError(
+      "sub-command FILTER requires an operator to be specified.");
     return false;
   }
 
   if (args.size() < 4) {
-    this->SetError("sub-command FILTER requires a mode to be specified.");
+    status.SetError("sub-command FILTER requires a mode to be specified.");
     return false;
   }
 
@@ -1428,28 +1491,29 @@ bool cmListCommand::HandleFilterCommand(std::vector<std::string> const& args)
   } else if (op == "EXCLUDE") {
     includeMatches = false;
   } else {
-    this->SetError("sub-command FILTER does not recognize operator " + op);
+    status.SetError("sub-command FILTER does not recognize operator " + op);
     return false;
   }
 
   const std::string& listName = args[1];
   // expand the variable
   std::vector<std::string> varArgsExpanded;
-  if (!this->GetList(varArgsExpanded, listName)) {
+  if (!GetList(varArgsExpanded, listName, status.GetMakefile())) {
     return true;
   }
 
   const std::string& mode = args[3];
   if (mode == "REGEX") {
     if (args.size() != 5) {
-      this->SetError("sub-command FILTER, mode REGEX "
-                     "requires five arguments.");
+      status.SetError("sub-command FILTER, mode REGEX "
+                      "requires five arguments.");
       return false;
     }
-    return this->FilterRegex(args, includeMatches, listName, varArgsExpanded);
+    return FilterRegex(args, includeMatches, listName, varArgsExpanded,
+                       status);
   }
 
-  this->SetError("sub-command FILTER does not recognize mode " + mode);
+  status.SetError("sub-command FILTER does not recognize mode " + mode);
   return false;
 }
 
@@ -1472,10 +1536,10 @@ private:
   const bool includeMatches;
 };
 
-bool cmListCommand::FilterRegex(std::vector<std::string> const& args,
-                                bool includeMatches,
-                                std::string const& listName,
-                                std::vector<std::string>& varArgsExpanded)
+bool FilterRegex(std::vector<std::string> const& args, bool includeMatches,
+                 std::string const& listName,
+                 std::vector<std::string>& varArgsExpanded,
+                 cmExecutionStatus& status)
 {
   const std::string& pattern = args[4];
   cmsys::RegularExpression regex(pattern);
@@ -1484,7 +1548,7 @@ bool cmListCommand::FilterRegex(std::vector<std::string> const& args,
     error += "failed to compile regex \"";
     error += pattern;
     error += "\".";
-    this->SetError(error);
+    status.SetError(error);
     return false;
   }
 
@@ -1494,6 +1558,7 @@ bool cmListCommand::FilterRegex(std::vector<std::string> const& args,
     std::remove_if(argsBegin, argsEnd, MatchesRegex(regex, includeMatches));
 
   std::string value = cmJoin(cmMakeRange(argsBegin, newArgsEnd), ";");
-  this->Makefile->AddDefinition(listName, value);
+  status.GetMakefile().AddDefinition(listName, value);
   return true;
 }
+}
diff --git a/Source/cmListCommand.h b/Source/cmListCommand.h
index 70c7f4e..274d9fd 100644
--- a/Source/cmListCommand.h
+++ b/Source/cmListCommand.h
@@ -8,58 +8,13 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmListCommand
+/**
  * \brief Common list operations
  *
  */
-class cmListCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmListCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-
-protected:
-  bool HandleLengthCommand(std::vector<std::string> const& args);
-  bool HandleGetCommand(std::vector<std::string> const& args);
-  bool HandleAppendCommand(std::vector<std::string> const& args);
-  bool HandlePrependCommand(std::vector<std::string> const& args);
-  bool HandlePopBackCommand(std::vector<std::string> const& args);
-  bool HandlePopFrontCommand(std::vector<std::string> const& args);
-  bool HandleFindCommand(std::vector<std::string> const& args);
-  bool HandleInsertCommand(std::vector<std::string> const& args);
-  bool HandleJoinCommand(std::vector<std::string> const& args);
-  bool HandleRemoveAtCommand(std::vector<std::string> const& args);
-  bool HandleRemoveItemCommand(std::vector<std::string> const& args);
-  bool HandleRemoveDuplicatesCommand(std::vector<std::string> const& args);
-  bool HandleTransformCommand(std::vector<std::string> const& args);
-  bool HandleSortCommand(std::vector<std::string> const& args);
-  bool HandleSublistCommand(std::vector<std::string> const& args);
-  bool HandleReverseCommand(std::vector<std::string> const& args);
-  bool HandleFilterCommand(std::vector<std::string> const& args);
-  bool FilterRegex(std::vector<std::string> const& args, bool includeMatches,
-                   std::string const& listName,
-                   std::vector<std::string>& varArgsExpanded);
-
-  bool GetList(std::vector<std::string>& list, const std::string& var);
-  bool GetListString(std::string& listString, const std::string& var);
-};
+bool cmListCommand(std::vector<std::string> const& args,
+                   cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From 5b40a872dd2d50e2c72c76df79ce087403daa37d Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Sun, 4 Aug 2019 17:13:14 +0200
Subject: cmCommand refactor: cmMakeDirectoryCommand

---
 Source/cmCommands.cxx             |  3 +--
 Source/cmMakeDirectoryCommand.cxx | 13 ++++++-------
 Source/cmMakeDirectoryCommand.h   | 26 +++-----------------------
 3 files changed, 10 insertions(+), 32 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 285c48e..e50f1a0 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -146,8 +146,7 @@ void GetScriptingCommands(cmState* state)
   state->AddBuiltinCommand("include_guard", cmIncludeGuardCommand);
   state->AddBuiltinCommand("list", cmListCommand);
   state->AddBuiltinCommand("macro", cmMacroCommand);
-  state->AddBuiltinCommand("make_directory",
-                           cm::make_unique<cmMakeDirectoryCommand>());
+  state->AddBuiltinCommand("make_directory", cmMakeDirectoryCommand);
   state->AddBuiltinCommand("mark_as_advanced",
                            cm::make_unique<cmMarkAsAdvancedCommand>());
   state->AddBuiltinCommand("math", cm::make_unique<cmMathCommand>());
diff --git a/Source/cmMakeDirectoryCommand.cxx b/Source/cmMakeDirectoryCommand.cxx
index aff4ca6..cdde6f9 100644
--- a/Source/cmMakeDirectoryCommand.cxx
+++ b/Source/cmMakeDirectoryCommand.cxx
@@ -2,23 +2,22 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmMakeDirectoryCommand.h"
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmSystemTools.h"
 
-class cmExecutionStatus;
-
 // cmMakeDirectoryCommand
-bool cmMakeDirectoryCommand::InitialPass(std::vector<std::string> const& args,
-                                         cmExecutionStatus&)
+bool cmMakeDirectoryCommand(std::vector<std::string> const& args,
+                            cmExecutionStatus& status)
 {
   if (args.size() != 1) {
-    this->SetError("called with incorrect number of arguments");
+    status.SetError("called with incorrect number of arguments");
     return false;
   }
-  if (!this->Makefile->CanIWriteThisFile(args[0])) {
+  if (!status.GetMakefile().CanIWriteThisFile(args[0])) {
     std::string e = "attempted to create a directory: " + args[0] +
       " into a source directory.";
-    this->SetError(e);
+    status.SetError(e);
     cmSystemTools::SetFatalErrorOccured();
     return false;
   }
diff --git a/Source/cmMakeDirectoryCommand.h b/Source/cmMakeDirectoryCommand.h
index b1fb49b..2474383 100644
--- a/Source/cmMakeDirectoryCommand.h
+++ b/Source/cmMakeDirectoryCommand.h
@@ -8,13 +8,9 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmMakeDirectoryCommand
+/**
  * \brief Specify auxiliary source code directories.
  *
  * cmMakeDirectoryCommand specifies source code directories
@@ -23,23 +19,7 @@ class cmExecutionStatus;
  * A side effect of this command is to create a subdirectory in the build
  * directory structure.
  */
-class cmMakeDirectoryCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmMakeDirectoryCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-};
+bool cmMakeDirectoryCommand(std::vector<std::string> const& args,
+                            cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From 2b58ae75773ff826bb1c3e6c5a3bad31c5292f00 Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Sun, 4 Aug 2019 18:31:29 +0200
Subject: cmCommand refactor: cmMarkAsAdvancedCommand

---
 Source/cmCommands.cxx              |  3 +--
 Source/cmMarkAsAdvancedCommand.cxx | 13 ++++++-------
 Source/cmMarkAsAdvancedCommand.h   | 26 +++-----------------------
 3 files changed, 10 insertions(+), 32 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index e50f1a0..6dd3e92 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -147,8 +147,7 @@ void GetScriptingCommands(cmState* state)
   state->AddBuiltinCommand("list", cmListCommand);
   state->AddBuiltinCommand("macro", cmMacroCommand);
   state->AddBuiltinCommand("make_directory", cmMakeDirectoryCommand);
-  state->AddBuiltinCommand("mark_as_advanced",
-                           cm::make_unique<cmMarkAsAdvancedCommand>());
+  state->AddBuiltinCommand("mark_as_advanced", cmMarkAsAdvancedCommand);
   state->AddBuiltinCommand("math", cm::make_unique<cmMathCommand>());
   state->AddBuiltinCommand("message", cm::make_unique<cmMessageCommand>());
   state->AddBuiltinCommand("option", cm::make_unique<cmOptionCommand>());
diff --git a/Source/cmMarkAsAdvancedCommand.cxx b/Source/cmMarkAsAdvancedCommand.cxx
index 45c59b9..ca46e14 100644
--- a/Source/cmMarkAsAdvancedCommand.cxx
+++ b/Source/cmMarkAsAdvancedCommand.cxx
@@ -2,20 +2,19 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmMarkAsAdvancedCommand.h"
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmState.h"
 #include "cmStateTypes.h"
 #include "cmSystemTools.h"
 #include "cmake.h"
 
-class cmExecutionStatus;
-
 // cmMarkAsAdvancedCommand
-bool cmMarkAsAdvancedCommand::InitialPass(std::vector<std::string> const& args,
-                                          cmExecutionStatus&)
+bool cmMarkAsAdvancedCommand(std::vector<std::string> const& args,
+                             cmExecutionStatus& status)
 {
   if (args.empty()) {
-    this->SetError("called with incorrect number of arguments");
+    status.SetError("called with incorrect number of arguments");
     return false;
   }
 
@@ -31,9 +30,9 @@ bool cmMarkAsAdvancedCommand::InitialPass(std::vector<std::string> const& args,
   }
   for (; i < args.size(); ++i) {
     std::string const& variable = args[i];
-    cmState* state = this->Makefile->GetState();
+    cmState* state = status.GetMakefile().GetState();
     if (!state->GetCacheEntryValue(variable)) {
-      this->Makefile->GetCMakeInstance()->AddCacheEntry(
+      status.GetMakefile().GetCMakeInstance()->AddCacheEntry(
         variable, nullptr, nullptr, cmStateEnums::UNINITIALIZED);
       overwrite = true;
     }
diff --git a/Source/cmMarkAsAdvancedCommand.h b/Source/cmMarkAsAdvancedCommand.h
index e367c46..de7bf08 100644
--- a/Source/cmMarkAsAdvancedCommand.h
+++ b/Source/cmMarkAsAdvancedCommand.h
@@ -8,34 +8,14 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmMarkAsAdvancedCommand
+/**
  * \brief mark_as_advanced command
  *
  * cmMarkAsAdvancedCommand implements the mark_as_advanced CMake command
  */
-class cmMarkAsAdvancedCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmMarkAsAdvancedCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-};
+bool cmMarkAsAdvancedCommand(std::vector<std::string> const& args,
+                             cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From 71724633a24fccfdf3d56a19176d8afe637be843 Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Sun, 4 Aug 2019 18:35:43 +0200
Subject: cmCommand refactor: cmMathCommand

---
 Source/cmCommands.cxx    |  2 +-
 Source/cmMathCommand.cxx | 37 ++++++++++++++++++++++---------------
 Source/cmMathCommand.h   | 27 ++-------------------------
 3 files changed, 25 insertions(+), 41 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 6dd3e92..68122af 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -148,7 +148,7 @@ void GetScriptingCommands(cmState* state)
   state->AddBuiltinCommand("macro", cmMacroCommand);
   state->AddBuiltinCommand("make_directory", cmMakeDirectoryCommand);
   state->AddBuiltinCommand("mark_as_advanced", cmMarkAsAdvancedCommand);
-  state->AddBuiltinCommand("math", cm::make_unique<cmMathCommand>());
+  state->AddBuiltinCommand("math", cmMathCommand);
   state->AddBuiltinCommand("message", cm::make_unique<cmMessageCommand>());
   state->AddBuiltinCommand("option", cm::make_unique<cmOptionCommand>());
   state->AddBuiltinCommand("cmake_parse_arguments",
diff --git a/Source/cmMathCommand.cxx b/Source/cmMathCommand.cxx
index 48b9a27..83c22aa 100644
--- a/Source/cmMathCommand.cxx
+++ b/Source/cmMathCommand.cxx
@@ -2,6 +2,7 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmMathCommand.h"
 
+#include "cmExecutionStatus.h"
 #include "cmExprParserHelper.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
@@ -9,28 +10,33 @@
 
 #include <stdio.h>
 
-class cmExecutionStatus;
+namespace {
+bool HandleExprCommand(std::vector<std::string> const& args,
+                       cmExecutionStatus& status);
+}
 
-bool cmMathCommand::InitialPass(std::vector<std::string> const& args,
-                                cmExecutionStatus&)
+bool cmMathCommand(std::vector<std::string> const& args,
+                   cmExecutionStatus& status)
 {
   if (args.empty()) {
-    this->SetError("must be called with at least one argument.");
+    status.SetError("must be called with at least one argument.");
     return false;
   }
   const std::string& subCommand = args[0];
   if (subCommand == "EXPR") {
-    return this->HandleExprCommand(args);
+    return HandleExprCommand(args, status);
   }
   std::string e = "does not recognize sub-command " + subCommand;
-  this->SetError(e);
+  status.SetError(e);
   return false;
 }
 
-bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args)
+namespace {
+bool HandleExprCommand(std::vector<std::string> const& args,
+                       cmExecutionStatus& status)
 {
   if ((args.size() != 3) && (args.size() != 5)) {
-    this->SetError("EXPR called with incorrect arguments.");
+    status.SetError("EXPR called with incorrect arguments.");
     return false;
   }
 
@@ -46,7 +52,7 @@ bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args)
   size_t argumentIndex = 3;
   NumericFormat outputFormat = NumericFormat::UNINITIALIZED;
 
-  this->Makefile->AddDefinition(outputVariable, "ERROR");
+  status.GetMakefile().AddDefinition(outputVariable, "ERROR");
 
   if (argumentIndex < args.size()) {
     const std::string messageHint = "sub-command EXPR ";
@@ -61,19 +67,19 @@ bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args)
         } else {
           std::string error = messageHint + "value \"" + argument +
             "\" for option \"" + option + "\" is invalid.";
-          this->SetError(error);
+          status.SetError(error);
           return false;
         }
       } else {
         std::string error =
           messageHint + "missing argument for option \"" + option + "\".";
-        this->SetError(error);
+        status.SetError(error);
         return false;
       }
     } else {
       std::string error =
         messageHint + "option \"" + option + "\" is unknown.";
-      this->SetError(error);
+      status.SetError(error);
       return false;
     }
   }
@@ -84,7 +90,7 @@ bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args)
 
   cmExprParserHelper helper;
   if (!helper.ParseString(expression.c_str(), 0)) {
-    this->SetError(helper.GetError());
+    status.SetError(helper.GetError());
     return false;
   }
 
@@ -104,9 +110,10 @@ bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args)
 
   std::string const& w = helper.GetWarning();
   if (!w.empty()) {
-    this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w);
+    status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, w);
   }
 
-  this->Makefile->AddDefinition(outputVariable, buffer);
+  status.GetMakefile().AddDefinition(outputVariable, buffer);
   return true;
 }
+}
diff --git a/Source/cmMathCommand.h b/Source/cmMathCommand.h
index 23633d3..ac1957c 100644
--- a/Source/cmMathCommand.h
+++ b/Source/cmMathCommand.h
@@ -8,33 +8,10 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
 /// Mathematical expressions: math(EXPR ...) command.
-class cmMathCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmMathCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-
-protected:
-  bool HandleExprCommand(std::vector<std::string> const& args);
-};
+bool cmMathCommand(std::vector<std::string> const& args,
+                   cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From cfc7854ef07369d6fb614a4483543afaf72a5208 Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Sun, 4 Aug 2019 18:39:45 +0200
Subject: cmCommand refactor: CmMessageCommand

---
 Source/cmCommands.cxx       |  2 +-
 Source/cmMessageCommand.cxx | 32 ++++++++++++++++----------------
 Source/cmMessageCommand.h   | 26 +++-----------------------
 3 files changed, 20 insertions(+), 40 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 68122af..c9a192a 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -149,7 +149,7 @@ void GetScriptingCommands(cmState* state)
   state->AddBuiltinCommand("make_directory", cmMakeDirectoryCommand);
   state->AddBuiltinCommand("mark_as_advanced", cmMarkAsAdvancedCommand);
   state->AddBuiltinCommand("math", cmMathCommand);
-  state->AddBuiltinCommand("message", cm::make_unique<cmMessageCommand>());
+  state->AddBuiltinCommand("message", cmMessageCommand);
   state->AddBuiltinCommand("option", cm::make_unique<cmOptionCommand>());
   state->AddBuiltinCommand("cmake_parse_arguments",
                            cm::make_unique<cmParseArgumentsCommand>());
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index dec32fa..3f33312 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -2,6 +2,7 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmMessageCommand.h"
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmMessenger.h"
@@ -12,14 +13,12 @@
 
 #include <cassert>
 
-class cmExecutionStatus;
-
 // cmLibraryCommand
-bool cmMessageCommand::InitialPass(std::vector<std::string> const& args,
-                                   cmExecutionStatus&)
+bool cmMessageCommand(std::vector<std::string> const& args,
+                      cmExecutionStatus& status)
 {
   if (args.empty()) {
-    this->SetError("called with incorrect number of arguments");
+    status.SetError("called with incorrect number of arguments");
     return false;
   }
   auto i = args.cbegin();
@@ -41,12 +40,13 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args,
     level = cmake::LogLevel::LOG_WARNING;
     ++i;
   } else if (*i == "AUTHOR_WARNING") {
-    if (this->Makefile->IsSet("CMAKE_SUPPRESS_DEVELOPER_ERRORS") &&
-        !this->Makefile->IsOn("CMAKE_SUPPRESS_DEVELOPER_ERRORS")) {
+    if (status.GetMakefile().IsSet("CMAKE_SUPPRESS_DEVELOPER_ERRORS") &&
+        !status.GetMakefile().IsOn("CMAKE_SUPPRESS_DEVELOPER_ERRORS")) {
       fatal = true;
       type = MessageType::AUTHOR_ERROR;
       level = cmake::LogLevel::LOG_ERROR;
-    } else if (!this->Makefile->IsOn("CMAKE_SUPPRESS_DEVELOPER_WARNINGS")) {
+    } else if (!status.GetMakefile().IsOn(
+                 "CMAKE_SUPPRESS_DEVELOPER_WARNINGS")) {
       type = MessageType::AUTHOR_WARNING;
       level = cmake::LogLevel::LOG_WARNING;
     } else {
@@ -66,12 +66,12 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args,
     level = cmake::LogLevel::LOG_TRACE;
     ++i;
   } else if (*i == "DEPRECATION") {
-    if (this->Makefile->IsOn("CMAKE_ERROR_DEPRECATED")) {
+    if (status.GetMakefile().IsOn("CMAKE_ERROR_DEPRECATED")) {
       fatal = true;
       type = MessageType::DEPRECATION_ERROR;
       level = cmake::LogLevel::LOG_ERROR;
-    } else if ((!this->Makefile->IsSet("CMAKE_WARN_DEPRECATED") ||
-                this->Makefile->IsOn("CMAKE_WARN_DEPRECATED"))) {
+    } else if ((!status.GetMakefile().IsSet("CMAKE_WARN_DEPRECATED") ||
+                status.GetMakefile().IsOn("CMAKE_WARN_DEPRECATED"))) {
       type = MessageType::DEPRECATION_WARNING;
       level = cmake::LogLevel::LOG_WARNING;
     } else {
@@ -89,7 +89,7 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args,
   assert("Message log level expected to be set" &&
          level != cmake::LogLevel::LOG_UNDEFINED);
 
-  auto desiredLevel = this->Makefile->GetCMakeInstance()->GetLogLevel();
+  auto desiredLevel = status.GetMakefile().GetCMakeInstance()->GetLogLevel();
   assert("Expected a valid log level here" &&
          desiredLevel != cmake::LogLevel::LOG_UNDEFINED);
 
@@ -104,7 +104,7 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args,
     // Check if any indentation has requested:
     // `CMAKE_MESSAGE_INDENT` is a list of "padding" pieces
     // to be joined and prepended to the message lines.
-    auto indent = cmJoin(cmExpandedList(this->Makefile->GetSafeDefinition(
+    auto indent = cmJoin(cmExpandedList(status.GetMakefile().GetSafeDefinition(
                            "CMAKE_MESSAGE_INDENT")),
                          "");
     // Make every line of the `message` indented
@@ -118,8 +118,8 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args,
     case cmake::LogLevel::LOG_ERROR:
     case cmake::LogLevel::LOG_WARNING:
       // we've overridden the message type, above, so display it directly
-      this->Makefile->GetMessenger()->DisplayMessage(
-        type, message, this->Makefile->GetBacktrace());
+      status.GetMakefile().GetMessenger()->DisplayMessage(
+        type, message, status.GetMakefile().GetBacktrace());
       break;
 
     case cmake::LogLevel::LOG_NOTICE:
@@ -130,7 +130,7 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args,
     case cmake::LogLevel::LOG_VERBOSE:
     case cmake::LogLevel::LOG_DEBUG:
     case cmake::LogLevel::LOG_TRACE:
-      this->Makefile->DisplayStatus(message, -1);
+      status.GetMakefile().DisplayStatus(message, -1);
       break;
 
     default:
diff --git a/Source/cmMessageCommand.h b/Source/cmMessageCommand.h
index ef89d59..7d544c4 100644
--- a/Source/cmMessageCommand.h
+++ b/Source/cmMessageCommand.h
@@ -8,33 +8,13 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmMessageCommand
+/**
  * \brief Displays a message to the user
  *
  */
-class cmMessageCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmMessageCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-};
+bool cmMessageCommand(std::vector<std::string> const& args,
+                      cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From 4fa9630b7ef645850da31a895ebaceb3bc583859 Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Sun, 4 Aug 2019 18:58:39 +0200
Subject: cmCommand refactor: cmOptionCommand

---
 Source/cmCommands.cxx      |  2 +-
 Source/cmOptionCommand.cxx | 26 +++++++++++++-------------
 Source/cmOptionCommand.h   | 27 +++------------------------
 3 files changed, 17 insertions(+), 38 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index c9a192a..5aff42d 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -150,7 +150,7 @@ void GetScriptingCommands(cmState* state)
   state->AddBuiltinCommand("mark_as_advanced", cmMarkAsAdvancedCommand);
   state->AddBuiltinCommand("math", cmMathCommand);
   state->AddBuiltinCommand("message", cmMessageCommand);
-  state->AddBuiltinCommand("option", cm::make_unique<cmOptionCommand>());
+  state->AddBuiltinCommand("option", cmOptionCommand);
   state->AddBuiltinCommand("cmake_parse_arguments",
                            cm::make_unique<cmParseArgumentsCommand>());
   state->AddBuiltinCommand("return", cmReturnCommand);
diff --git a/Source/cmOptionCommand.cxx b/Source/cmOptionCommand.cxx
index a30f487..21841c8 100644
--- a/Source/cmOptionCommand.cxx
+++ b/Source/cmOptionCommand.cxx
@@ -4,6 +4,7 @@
 
 #include <sstream>
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmPolicies.h"
@@ -12,27 +13,26 @@
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 
-class cmExecutionStatus;
-
 // cmOptionCommand
-bool cmOptionCommand::InitialPass(std::vector<std::string> const& args,
-                                  cmExecutionStatus&)
+bool cmOptionCommand(std::vector<std::string> const& args,
+                     cmExecutionStatus& status)
 {
   const bool argError = (args.size() < 2) || (args.size() > 3);
   if (argError) {
     std::string m = "called with incorrect number of arguments: ";
     m += cmJoin(args, " ");
-    this->SetError(m);
+    status.SetError(m);
     return false;
   }
 
   // Determine the state of the option policy
   bool checkAndWarn = false;
   {
-    auto status = this->Makefile->GetPolicyStatus(cmPolicies::CMP0077);
+    auto policyStatus =
+      status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0077);
     const auto* existsBeforeSet =
-      this->Makefile->GetStateSnapshot().GetDefinition(args[0]);
-    switch (status) {
+      status.GetMakefile().GetStateSnapshot().GetDefinition(args[0]);
+    switch (policyStatus) {
       case cmPolicies::WARN:
         checkAndWarn = (existsBeforeSet != nullptr);
         break;
@@ -53,7 +53,7 @@ bool cmOptionCommand::InitialPass(std::vector<std::string> const& args,
 
   // See if a cache variable with this name already exists
   // If so just make sure the doc state is correct
-  cmState* state = this->Makefile->GetState();
+  cmState* state = status.GetMakefile().GetState();
   const char* existingValue = state->GetCacheEntryValue(args[0]);
   if (existingValue &&
       (state->GetCacheEntryType(args[0]) != cmStateEnums::UNINITIALIZED)) {
@@ -67,12 +67,12 @@ bool cmOptionCommand::InitialPass(std::vector<std::string> const& args,
     initialValue = args[2];
   }
   bool init = cmIsOn(initialValue);
-  this->Makefile->AddCacheDefinition(args[0], init ? "ON" : "OFF",
-                                     args[1].c_str(), cmStateEnums::BOOL);
+  status.GetMakefile().AddCacheDefinition(args[0], init ? "ON" : "OFF",
+                                          args[1].c_str(), cmStateEnums::BOOL);
 
   if (checkAndWarn) {
     const auto* existsAfterSet =
-      this->Makefile->GetStateSnapshot().GetDefinition(args[0]);
+      status.GetMakefile().GetStateSnapshot().GetDefinition(args[0]);
     if (!existsAfterSet) {
       std::ostringstream w;
       w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0077)
@@ -80,7 +80,7 @@ bool cmOptionCommand::InitialPass(std::vector<std::string> const& args,
            "For compatibility with older versions of CMake, option "
            "is clearing the normal variable '"
         << args[0] << "'.";
-      this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
+      status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, w.str());
     }
   }
   return true;
diff --git a/Source/cmOptionCommand.h b/Source/cmOptionCommand.h
index eddab03..cbd1cb8 100644
--- a/Source/cmOptionCommand.h
+++ b/Source/cmOptionCommand.h
@@ -8,34 +8,13 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmOptionCommand
+/**
  * \brief Provide an option to the user
  *
  * cmOptionCommand provides an option for the user to select
  */
-class cmOptionCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmOptionCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-};
-
+bool cmOptionCommand(std::vector<std::string> const& args,
+                     cmExecutionStatus& status);
 #endif
-- 
cgit v0.12


From d780822da61afb5fd3014f7e15c68eb2eb0754c3 Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Sun, 4 Aug 2019 19:03:09 +0200
Subject: cmCommand refactor: cmParseArgumentsCommand

---
 Source/cmCommands.cxx              |  3 +--
 Source/cmParseArgumentsCommand.cxx | 41 +++++++++++++++++++-------------------
 Source/cmParseArgumentsCommand.h   | 27 ++-----------------------
 3 files changed, 24 insertions(+), 47 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 5aff42d..406954a 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -151,8 +151,7 @@ void GetScriptingCommands(cmState* state)
   state->AddBuiltinCommand("math", cmMathCommand);
   state->AddBuiltinCommand("message", cmMessageCommand);
   state->AddBuiltinCommand("option", cmOptionCommand);
-  state->AddBuiltinCommand("cmake_parse_arguments",
-                           cm::make_unique<cmParseArgumentsCommand>());
+  state->AddBuiltinCommand("cmake_parse_arguments", cmParseArgumentsCommand);
   state->AddBuiltinCommand("return", cmReturnCommand);
   state->AddBuiltinCommand("separate_arguments",
                            cm::make_unique<cmSeparateArgumentsCommand>());
diff --git a/Source/cmParseArgumentsCommand.cxx b/Source/cmParseArgumentsCommand.cxx
index 5e7e2f3..7560765 100644
--- a/Source/cmParseArgumentsCommand.cxx
+++ b/Source/cmParseArgumentsCommand.cxx
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "cmArgumentParser.h"
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmRange.h"
@@ -15,8 +16,6 @@
 #include "cmSystemTools.h"
 #include "cm_string_view.hxx"
 
-class cmExecutionStatus;
-
 static std::string EscapeArg(const std::string& arg)
 {
   // replace ";" with "\;" so output argument lists will split correctly
@@ -105,15 +104,15 @@ static void PassParsedArguments(
   }
 }
 
-bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
-                                          cmExecutionStatus&)
+bool cmParseArgumentsCommand(std::vector<std::string> const& args,
+                             cmExecutionStatus& status)
 {
   // cmake_parse_arguments(prefix options single multi <ARGN>)
   //                         1       2      3      4
   // or
   // cmake_parse_arguments(PARSE_ARGV N prefix options single multi)
   if (args.size() < 4) {
-    this->SetError("must be called with at least 4 arguments.");
+    status.SetError("must be called with at least 4 arguments.");
     return false;
   }
 
@@ -123,7 +122,7 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
   unsigned long argvStart = 0;
   if (*argIter == "PARSE_ARGV") {
     if (args.size() != 6) {
-      this->Makefile->IssueMessage(
+      status.GetMakefile().IssueMessage(
         MessageType::FATAL_ERROR,
         "PARSE_ARGV must be called with exactly 6 arguments.");
       cmSystemTools::SetFatalErrorOccured();
@@ -132,9 +131,9 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
     parseFromArgV = true;
     argIter++; // move past PARSE_ARGV
     if (!cmStrToULong(*argIter, &argvStart)) {
-      this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
-                                   "PARSE_ARGV index '" + *argIter +
-                                     "' is not an unsigned integer");
+      status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR,
+                                        "PARSE_ARGV index '" + *argIter +
+                                          "' is not an unsigned integer");
       cmSystemTools::SetFatalErrorOccured();
       return true;
     }
@@ -154,8 +153,8 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
   // anything else is put into a vector of unparsed strings
   std::vector<std::string> unparsed;
 
-  auto const duplicateKey = [this](std::string const& key) {
-    this->GetMakefile()->IssueMessage(
+  auto const duplicateKey = [&status](std::string const& key) {
+    status.GetMakefile().IssueMessage(
       MessageType::WARNING, "keyword defined more than once: " + key);
   };
 
@@ -183,23 +182,24 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
     }
   } else {
     // in the PARSE_ARGV move read the arguments from ARGC and ARGV#
-    std::string argc = this->Makefile->GetSafeDefinition("ARGC");
+    std::string argc = status.GetMakefile().GetSafeDefinition("ARGC");
     unsigned long count;
     if (!cmStrToULong(argc, &count)) {
-      this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
-                                   "PARSE_ARGV called with ARGC='" + argc +
-                                     "' that is not an unsigned integer");
+      status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR,
+                                        "PARSE_ARGV called with ARGC='" +
+                                          argc +
+                                          "' that is not an unsigned integer");
       cmSystemTools::SetFatalErrorOccured();
       return true;
     }
     for (unsigned long i = argvStart; i < count; ++i) {
       std::ostringstream argName;
       argName << "ARGV" << i;
-      const char* arg = this->Makefile->GetDefinition(argName.str());
+      const char* arg = status.GetMakefile().GetDefinition(argName.str());
       if (!arg) {
-        this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
-                                     "PARSE_ARGV called with " +
-                                       argName.str() + " not set");
+        status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR,
+                                          "PARSE_ARGV called with " +
+                                            argName.str() + " not set");
         cmSystemTools::SetFatalErrorOccured();
         return true;
       }
@@ -212,7 +212,8 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
   parser.Parse(list, &unparsed, &keywordsMissingValues);
 
   PassParsedArguments(
-    prefix, *this->Makefile, options, singleValArgs, multiValArgs, unparsed,
+    prefix, status.GetMakefile(), options, singleValArgs, multiValArgs,
+    unparsed,
     options_set(keywordsMissingValues.begin(), keywordsMissingValues.end()),
     parseFromArgV);
 
diff --git a/Source/cmParseArgumentsCommand.h b/Source/cmParseArgumentsCommand.h
index 692ea64..b2e436d 100644
--- a/Source/cmParseArgumentsCommand.h
+++ b/Source/cmParseArgumentsCommand.h
@@ -8,32 +8,9 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmParseArgumentsCommand
- *
- */
-class cmParseArgumentsCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmParseArgumentsCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-};
+bool cmParseArgumentsCommand(std::vector<std::string> const& args,
+                             cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From 2a9299782ece0e2c5f990fcab2162d141aedb833 Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Sun, 4 Aug 2019 19:05:36 +0200
Subject: cmCommand refactor: cmSeparateArgumentsCommand

---
 Source/cmCommands.cxx                 |  3 +--
 Source/cmSeparateArgumentsCommand.cxx | 17 ++++++++---------
 Source/cmSeparateArgumentsCommand.h   | 26 +++-----------------------
 3 files changed, 12 insertions(+), 34 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 406954a..c23a9ca 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -153,8 +153,7 @@ void GetScriptingCommands(cmState* state)
   state->AddBuiltinCommand("option", cmOptionCommand);
   state->AddBuiltinCommand("cmake_parse_arguments", cmParseArgumentsCommand);
   state->AddBuiltinCommand("return", cmReturnCommand);
-  state->AddBuiltinCommand("separate_arguments",
-                           cm::make_unique<cmSeparateArgumentsCommand>());
+  state->AddBuiltinCommand("separate_arguments", cmSeparateArgumentsCommand);
   state->AddBuiltinCommand("set", cm::make_unique<cmSetCommand>());
   state->AddBuiltinCommand("set_directory_properties",
                            cm::make_unique<cmSetDirectoryPropertiesCommand>());
diff --git a/Source/cmSeparateArgumentsCommand.cxx b/Source/cmSeparateArgumentsCommand.cxx
index ab4a0c7..27f45a8 100644
--- a/Source/cmSeparateArgumentsCommand.cxx
+++ b/Source/cmSeparateArgumentsCommand.cxx
@@ -5,17 +5,16 @@
 #include <algorithm>
 #include <sstream>
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmSystemTools.h"
 
-class cmExecutionStatus;
-
 // cmSeparateArgumentsCommand
-bool cmSeparateArgumentsCommand::InitialPass(
-  std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmSeparateArgumentsCommand(std::vector<std::string> const& args,
+                                cmExecutionStatus& status)
 {
   if (args.empty()) {
-    this->SetError("must be given at least one argument.");
+    status.SetError("must be given at least one argument.");
     return false;
   }
 
@@ -59,17 +58,17 @@ bool cmSeparateArgumentsCommand::InitialPass(
     } else {
       std::ostringstream e;
       e << "given unknown argument " << arg;
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
   }
 
   if (mode == ModeOld) {
     // Original space-replacement version of command.
-    if (const char* def = this->Makefile->GetDefinition(var)) {
+    if (const char* def = status.GetMakefile().GetDefinition(var)) {
       std::string value = def;
       std::replace(value.begin(), value.end(), ' ', ';');
-      this->Makefile->AddDefinition(var, value);
+      status.GetMakefile().AddDefinition(var, value);
     }
   } else {
     // Parse the command line.
@@ -97,7 +96,7 @@ bool cmSeparateArgumentsCommand::InitialPass(
         value += si;
       }
     }
-    this->Makefile->AddDefinition(var, value);
+    status.GetMakefile().AddDefinition(var, value);
   }
 
   return true;
diff --git a/Source/cmSeparateArgumentsCommand.h b/Source/cmSeparateArgumentsCommand.h
index 76e2002..e000c51 100644
--- a/Source/cmSeparateArgumentsCommand.h
+++ b/Source/cmSeparateArgumentsCommand.h
@@ -8,34 +8,14 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmSeparateArgumentsCommand
+/**
  * \brief separate_arguments command
  *
  * cmSeparateArgumentsCommand implements the separate_arguments CMake command
  */
-class cmSeparateArgumentsCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmSeparateArgumentsCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-};
+bool cmSeparateArgumentsCommand(std::vector<std::string> const& args,
+                                cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From b3aa789630c6411300080ec05d58e6cd9dcb7a2b Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Sun, 4 Aug 2019 19:08:05 +0200
Subject: cmCommand refactor: cmSetCommand

---
 Source/cmCommands.cxx   |  2 +-
 Source/cmSetCommand.cxx | 29 ++++++++++++++---------------
 Source/cmSetCommand.h   | 26 +++-----------------------
 3 files changed, 18 insertions(+), 39 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index c23a9ca..da266c3 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -154,7 +154,7 @@ void GetScriptingCommands(cmState* state)
   state->AddBuiltinCommand("cmake_parse_arguments", cmParseArgumentsCommand);
   state->AddBuiltinCommand("return", cmReturnCommand);
   state->AddBuiltinCommand("separate_arguments", cmSeparateArgumentsCommand);
-  state->AddBuiltinCommand("set", cm::make_unique<cmSetCommand>());
+  state->AddBuiltinCommand("set", cmSetCommand);
   state->AddBuiltinCommand("set_directory_properties",
                            cm::make_unique<cmSetDirectoryPropertiesCommand>());
   state->AddBuiltinCommand("set_property",
diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx
index 1a12785..8c3a4cb 100644
--- a/Source/cmSetCommand.cxx
+++ b/Source/cmSetCommand.cxx
@@ -2,6 +2,7 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmSetCommand.h"
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmRange.h"
@@ -10,14 +11,12 @@
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 
-class cmExecutionStatus;
-
 // cmSetCommand
-bool cmSetCommand::InitialPass(std::vector<std::string> const& args,
-                               cmExecutionStatus&)
+bool cmSetCommand(std::vector<std::string> const& args,
+                  cmExecutionStatus& status)
 {
   if (args.empty()) {
-    this->SetError("called with incorrect number of arguments");
+    status.SetError("called with incorrect number of arguments");
     return false;
   }
 
@@ -45,7 +44,7 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args,
         std::string m = "Only the first value argument is used when setting "
                         "an environment variable.  Argument '" +
           args[2] + "' and later are unused.";
-        this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, m);
+        status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, m);
       }
       return true;
     }
@@ -59,13 +58,13 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args,
 
   // SET (VAR) // Removes the definition of VAR.
   if (args.size() == 1) {
-    this->Makefile->RemoveDefinition(variable);
+    status.GetMakefile().RemoveDefinition(variable);
     return true;
   }
   // SET (VAR PARENT_SCOPE) // Removes the definition of VAR
   // in the parent scope.
   if (args.size() == 2 && args.back() == "PARENT_SCOPE") {
-    this->Makefile->RaiseScope(variable, nullptr);
+    status.GetMakefile().RaiseScope(variable, nullptr);
     return true;
   }
 
@@ -106,7 +105,7 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args,
   value = cmJoin(cmMakeRange(args).advance(1).retreat(ignoreLastArgs), ";");
 
   if (parentScope) {
-    this->Makefile->RaiseScope(variable, value.c_str());
+    status.GetMakefile().RaiseScope(variable, value.c_str());
     return true;
   }
 
@@ -116,7 +115,7 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args,
   if ((args.back() == "CACHE") ||
       (args.size() > 1 && args[args.size() - 2] == "CACHE") ||
       (force && !cache)) {
-    this->SetError("given invalid arguments for CACHE mode.");
+    status.SetError("given invalid arguments for CACHE mode.");
     return false;
   }
 
@@ -125,7 +124,7 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args,
     if (!cmState::StringToCacheEntryType(args[cacheStart + 1].c_str(), type)) {
       std::string m = "implicitly converting '" + args[cacheStart + 1] +
         "' to 'STRING' type.";
-      this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, m);
+      status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, m);
       // Setting this may not be required, since it's
       // initialized as a string. Keeping this here to
       // ensure that the type is actually converting to a string.
@@ -135,7 +134,7 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args,
   }
 
   // see if this is already in the cache
-  cmState* state = this->Makefile->GetState();
+  cmState* state = status.GetMakefile().GetState();
   const char* existingValue = state->GetCacheEntryValue(variable);
   if (existingValue &&
       (state->GetCacheEntryType(variable) != cmStateEnums::UNINITIALIZED)) {
@@ -150,11 +149,11 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args,
 
   // if it is meant to be in the cache then define it in the cache
   if (cache) {
-    this->Makefile->AddCacheDefinition(variable, value.c_str(), docstring,
-                                       type, force);
+    status.GetMakefile().AddCacheDefinition(variable, value.c_str(), docstring,
+                                            type, force);
   } else {
     // add the definition
-    this->Makefile->AddDefinition(variable, value);
+    status.GetMakefile().AddDefinition(variable, value);
   }
   return true;
 }
diff --git a/Source/cmSetCommand.h b/Source/cmSetCommand.h
index 1c5a435..0973d33 100644
--- a/Source/cmSetCommand.h
+++ b/Source/cmSetCommand.h
@@ -8,34 +8,14 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmSetCommand
+/**
  * \brief Set a CMAKE variable
  *
  * cmSetCommand sets a variable to a value with expansion.
  */
-class cmSetCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmSetCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-};
+bool cmSetCommand(std::vector<std::string> const& args,
+                  cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From b316d0d417761dc16d6d7b6ae41ac56b4509b949 Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Sun, 4 Aug 2019 19:11:41 +0200
Subject: cmCommand refactor: cmSiteNameCommand

---
 Source/cmCommands.cxx        |  2 +-
 Source/cmSiteNameCommand.cxx | 15 +++++++--------
 Source/cmSiteNameCommand.h   | 26 +++-----------------------
 3 files changed, 11 insertions(+), 32 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index da266c3..560c4cc 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -159,7 +159,7 @@ void GetScriptingCommands(cmState* state)
                            cm::make_unique<cmSetDirectoryPropertiesCommand>());
   state->AddBuiltinCommand("set_property",
                            cm::make_unique<cmSetPropertyCommand>());
-  state->AddBuiltinCommand("site_name", cm::make_unique<cmSiteNameCommand>());
+  state->AddBuiltinCommand("site_name", cmSiteNameCommand);
   state->AddBuiltinCommand("string", cm::make_unique<cmStringCommand>());
   state->AddBuiltinCommand("unset", cm::make_unique<cmUnsetCommand>());
   state->AddBuiltinCommand("while", cmWhileCommand);
diff --git a/Source/cmSiteNameCommand.cxx b/Source/cmSiteNameCommand.cxx
index 61ede29..d47f121 100644
--- a/Source/cmSiteNameCommand.cxx
+++ b/Source/cmSiteNameCommand.cxx
@@ -4,19 +4,18 @@
 
 #include "cmsys/RegularExpression.hxx"
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 
-class cmExecutionStatus;
-
 // cmSiteNameCommand
-bool cmSiteNameCommand::InitialPass(std::vector<std::string> const& args,
-                                    cmExecutionStatus&)
+bool cmSiteNameCommand(std::vector<std::string> const& args,
+                       cmExecutionStatus& status)
 {
   if (args.size() != 1) {
-    this->SetError("called with incorrect number of arguments");
+    status.SetError("called with incorrect number of arguments");
     return false;
   }
   std::vector<std::string> paths;
@@ -27,12 +26,12 @@ bool cmSiteNameCommand::InitialPass(std::vector<std::string> const& args,
   paths.emplace_back("/sbin");
   paths.emplace_back("/usr/local/bin");
 
-  const char* cacheValue = this->Makefile->GetDefinition(args[0]);
+  const char* cacheValue = status.GetMakefile().GetDefinition(args[0]);
   if (cacheValue) {
     return true;
   }
 
-  const char* temp = this->Makefile->GetDefinition("HOSTNAME");
+  const char* temp = status.GetMakefile().GetDefinition("HOSTNAME");
   std::string hostname_cmd;
   if (temp) {
     hostname_cmd = temp;
@@ -72,7 +71,7 @@ bool cmSiteNameCommand::InitialPass(std::vector<std::string> const& args,
     }
   }
 #endif
-  this->Makefile->AddCacheDefinition(
+  status.GetMakefile().AddCacheDefinition(
     args[0], siteName.c_str(),
     "Name of the computer/site where compile is being run",
     cmStateEnums::STRING);
diff --git a/Source/cmSiteNameCommand.h b/Source/cmSiteNameCommand.h
index 0190abb..e8fc608 100644
--- a/Source/cmSiteNameCommand.h
+++ b/Source/cmSiteNameCommand.h
@@ -8,34 +8,14 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmSiteNameCommand
+/**
  * \brief site_name command
  *
  * cmSiteNameCommand implements the site_name CMake command
  */
-class cmSiteNameCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmSiteNameCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-};
+bool cmSiteNameCommand(std::vector<std::string> const& args,
+                       cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From c33c52bb327d448868cff6aff6d83c786bc81e7e Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Fri, 9 Aug 2019 11:38:18 +0200
Subject: cmCommand refactor: cmUnsetCommand

---
 Source/cmCommands.cxx     |  2 +-
 Source/cmUnsetCommand.cxx | 17 ++++++++---------
 Source/cmUnsetCommand.h   | 26 +++-----------------------
 3 files changed, 12 insertions(+), 33 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 560c4cc..6b0af79 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -161,7 +161,7 @@ void GetScriptingCommands(cmState* state)
                            cm::make_unique<cmSetPropertyCommand>());
   state->AddBuiltinCommand("site_name", cmSiteNameCommand);
   state->AddBuiltinCommand("string", cm::make_unique<cmStringCommand>());
-  state->AddBuiltinCommand("unset", cm::make_unique<cmUnsetCommand>());
+  state->AddBuiltinCommand("unset", cmUnsetCommand);
   state->AddBuiltinCommand("while", cmWhileCommand);
 
   state->AddUnexpectedCommand(
diff --git a/Source/cmUnsetCommand.cxx b/Source/cmUnsetCommand.cxx
index 3eb293a..3ba95e9 100644
--- a/Source/cmUnsetCommand.cxx
+++ b/Source/cmUnsetCommand.cxx
@@ -2,18 +2,17 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmUnsetCommand.h"
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 
-class cmExecutionStatus;
-
 // cmUnsetCommand
-bool cmUnsetCommand::InitialPass(std::vector<std::string> const& args,
-                                 cmExecutionStatus&)
+bool cmUnsetCommand(std::vector<std::string> const& args,
+                    cmExecutionStatus& status)
 {
   if (args.empty() || args.size() > 2) {
-    this->SetError("called with incorrect number of arguments");
+    status.SetError("called with incorrect number of arguments");
     return false;
   }
 
@@ -31,20 +30,20 @@ bool cmUnsetCommand::InitialPass(std::vector<std::string> const& args,
   }
   // unset(VAR)
   if (args.size() == 1) {
-    this->Makefile->RemoveDefinition(variable);
+    status.GetMakefile().RemoveDefinition(variable);
     return true;
   }
   // unset(VAR CACHE)
   if ((args.size() == 2) && (args[1] == "CACHE")) {
-    this->Makefile->RemoveCacheDefinition(variable);
+    status.GetMakefile().RemoveCacheDefinition(variable);
     return true;
   }
   // unset(VAR PARENT_SCOPE)
   if ((args.size() == 2) && (args[1] == "PARENT_SCOPE")) {
-    this->Makefile->RaiseScope(variable, nullptr);
+    status.GetMakefile().RaiseScope(variable, nullptr);
     return true;
   }
   // ERROR: second argument isn't CACHE or PARENT_SCOPE
-  this->SetError("called with an invalid second argument");
+  status.SetError("called with an invalid second argument");
   return false;
 }
diff --git a/Source/cmUnsetCommand.h b/Source/cmUnsetCommand.h
index 9b78d44..be4c166 100644
--- a/Source/cmUnsetCommand.h
+++ b/Source/cmUnsetCommand.h
@@ -8,34 +8,14 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmUnsetCommand
+/**
  * \brief Unset a CMAKE variable
  *
  * cmUnsetCommand unsets or removes a variable.
  */
-class cmUnsetCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmUnsetCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-};
+bool cmUnsetCommand(std::vector<std::string> const& args,
+                    cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From 413a960391291678f216fe3d2bbfbd3fdca84168 Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Fri, 9 Aug 2019 11:48:01 +0200
Subject: cmCommand refactor: cmCMakeHostSystemInformationCommand

---
 Source/cmCMakeHostSystemInformationCommand.cxx | 96 ++++++++++++++------------
 Source/cmCMakeHostSystemInformationCommand.h   | 38 +---------
 Source/cmCommands.cxx                          |  5 +-
 3 files changed, 57 insertions(+), 82 deletions(-)

diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx
index b4cd2a5..1669853 100644
--- a/Source/cmCMakeHostSystemInformationCommand.cxx
+++ b/Source/cmCMakeHostSystemInformationCommand.cxx
@@ -3,7 +3,9 @@
 #include "cmCMakeHostSystemInformationCommand.h"
 
 #include <sstream>
+#include <stddef.h>
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmsys/SystemInformation.hxx"
 
@@ -16,16 +18,22 @@
 #  define HAVE_VS_SETUP_HELPER
 #endif
 
-class cmExecutionStatus;
+namespace {
+bool GetValue(cmExecutionStatus& status, cmsys::SystemInformation& info,
+              std::string const& key, std::string& value);
+std::string ValueToString(size_t value);
+std::string ValueToString(const char* value);
+std::string ValueToString(std::string const& value);
+}
 
 // cmCMakeHostSystemInformation
-bool cmCMakeHostSystemInformationCommand::InitialPass(
-  std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmCMakeHostSystemInformationCommand(std::vector<std::string> const& args,
+                                         cmExecutionStatus& status)
 {
   size_t current_index = 0;
 
   if (args.size() < (current_index + 2) || args[current_index] != "RESULT") {
-    this->SetError("missing RESULT specification.");
+    status.SetError("missing RESULT specification.");
     return false;
   }
 
@@ -33,7 +41,7 @@ bool cmCMakeHostSystemInformationCommand::InitialPass(
   current_index += 2;
 
   if (args.size() < (current_index + 2) || args[current_index] != "QUERY") {
-    this->SetError("missing QUERY specification");
+    status.SetError("missing QUERY specification");
     return false;
   }
 
@@ -49,89 +57,91 @@ bool cmCMakeHostSystemInformationCommand::InitialPass(
       result_list += ";";
     }
     std::string value;
-    if (!this->GetValue(info, key, value)) {
+    if (!GetValue(status, info, key, value)) {
       return false;
     }
     result_list += value;
   }
 
-  this->Makefile->AddDefinition(variable, result_list);
+  status.GetMakefile().AddDefinition(variable, result_list);
 
   return true;
 }
 
-bool cmCMakeHostSystemInformationCommand::GetValue(
-  cmsys::SystemInformation& info, std::string const& key, std::string& value)
+namespace {
+
+bool GetValue(cmExecutionStatus& status, cmsys::SystemInformation& info,
+              std::string const& key, std::string& value)
 {
   if (key == "NUMBER_OF_LOGICAL_CORES") {
-    value = this->ValueToString(info.GetNumberOfLogicalCPU());
+    value = ValueToString(info.GetNumberOfLogicalCPU());
   } else if (key == "NUMBER_OF_PHYSICAL_CORES") {
-    value = this->ValueToString(info.GetNumberOfPhysicalCPU());
+    value = ValueToString(info.GetNumberOfPhysicalCPU());
   } else if (key == "HOSTNAME") {
-    value = this->ValueToString(info.GetHostname());
+    value = ValueToString(info.GetHostname());
   } else if (key == "FQDN") {
-    value = this->ValueToString(info.GetFullyQualifiedDomainName());
+    value = ValueToString(info.GetFullyQualifiedDomainName());
   } else if (key == "TOTAL_VIRTUAL_MEMORY") {
-    value = this->ValueToString(info.GetTotalVirtualMemory());
+    value = ValueToString(info.GetTotalVirtualMemory());
   } else if (key == "AVAILABLE_VIRTUAL_MEMORY") {
-    value = this->ValueToString(info.GetAvailableVirtualMemory());
+    value = ValueToString(info.GetAvailableVirtualMemory());
   } else if (key == "TOTAL_PHYSICAL_MEMORY") {
-    value = this->ValueToString(info.GetTotalPhysicalMemory());
+    value = ValueToString(info.GetTotalPhysicalMemory());
   } else if (key == "AVAILABLE_PHYSICAL_MEMORY") {
-    value = this->ValueToString(info.GetAvailablePhysicalMemory());
+    value = ValueToString(info.GetAvailablePhysicalMemory());
   } else if (key == "IS_64BIT") {
-    value = this->ValueToString(info.Is64Bits());
+    value = ValueToString(info.Is64Bits());
   } else if (key == "HAS_FPU") {
-    value = this->ValueToString(
+    value = ValueToString(
       info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_FPU));
   } else if (key == "HAS_MMX") {
-    value = this->ValueToString(
+    value = ValueToString(
       info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_MMX));
   } else if (key == "HAS_MMX_PLUS") {
-    value = this->ValueToString(info.DoesCPUSupportFeature(
+    value = ValueToString(info.DoesCPUSupportFeature(
       cmsys::SystemInformation::CPU_FEATURE_MMX_PLUS));
   } else if (key == "HAS_SSE") {
-    value = this->ValueToString(
+    value = ValueToString(
       info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_SSE));
   } else if (key == "HAS_SSE2") {
-    value = this->ValueToString(
+    value = ValueToString(
       info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_SSE2));
   } else if (key == "HAS_SSE_FP") {
-    value = this->ValueToString(info.DoesCPUSupportFeature(
+    value = ValueToString(info.DoesCPUSupportFeature(
       cmsys::SystemInformation::CPU_FEATURE_SSE_FP));
   } else if (key == "HAS_SSE_MMX") {
-    value = this->ValueToString(info.DoesCPUSupportFeature(
+    value = ValueToString(info.DoesCPUSupportFeature(
       cmsys::SystemInformation::CPU_FEATURE_SSE_MMX));
   } else if (key == "HAS_AMD_3DNOW") {
-    value = this->ValueToString(info.DoesCPUSupportFeature(
+    value = ValueToString(info.DoesCPUSupportFeature(
       cmsys::SystemInformation::CPU_FEATURE_AMD_3DNOW));
   } else if (key == "HAS_AMD_3DNOW_PLUS") {
-    value = this->ValueToString(info.DoesCPUSupportFeature(
+    value = ValueToString(info.DoesCPUSupportFeature(
       cmsys::SystemInformation::CPU_FEATURE_AMD_3DNOW_PLUS));
   } else if (key == "HAS_IA64") {
-    value = this->ValueToString(
+    value = ValueToString(
       info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_IA64));
   } else if (key == "HAS_SERIAL_NUMBER") {
-    value = this->ValueToString(info.DoesCPUSupportFeature(
+    value = ValueToString(info.DoesCPUSupportFeature(
       cmsys::SystemInformation::CPU_FEATURE_SERIALNUMBER));
   } else if (key == "PROCESSOR_NAME") {
-    value = this->ValueToString(info.GetExtendedProcessorName());
+    value = ValueToString(info.GetExtendedProcessorName());
   } else if (key == "PROCESSOR_DESCRIPTION") {
     value = info.GetCPUDescription();
   } else if (key == "PROCESSOR_SERIAL_NUMBER") {
-    value = this->ValueToString(info.GetProcessorSerialNumber());
+    value = ValueToString(info.GetProcessorSerialNumber());
   } else if (key == "OS_NAME") {
-    value = this->ValueToString(info.GetOSName());
+    value = ValueToString(info.GetOSName());
   } else if (key == "OS_RELEASE") {
-    value = this->ValueToString(info.GetOSRelease());
+    value = ValueToString(info.GetOSRelease());
   } else if (key == "OS_VERSION") {
-    value = this->ValueToString(info.GetOSVersion());
+    value = ValueToString(info.GetOSVersion());
   } else if (key == "OS_PLATFORM") {
-    value = this->ValueToString(info.GetOSPlatform());
+    value = ValueToString(info.GetOSPlatform());
 #ifdef HAVE_VS_SETUP_HELPER
   } else if (key == "VS_15_DIR") {
     // If generating for the VS 15 IDE, use the same instance.
-    cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
+    cmGlobalGenerator* gg = status.GetMakefile().GetGlobalGenerator();
     if (cmHasLiteralPrefix(gg->GetName(), "Visual Studio 15 ")) {
       cmGlobalVisualStudioVersionedGenerator* vs15gen =
         static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg);
@@ -147,7 +157,7 @@ bool cmCMakeHostSystemInformationCommand::GetValue(
     }
   } else if (key == "VS_16_DIR") {
     // If generating for the VS 16 IDE, use the same instance.
-    cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
+    cmGlobalGenerator* gg = status.GetMakefile().GetGlobalGenerator();
     if (cmHasLiteralPrefix(gg->GetName(), "Visual Studio 16 ")) {
       cmGlobalVisualStudioVersionedGenerator* vs16gen =
         static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg);
@@ -164,30 +174,28 @@ bool cmCMakeHostSystemInformationCommand::GetValue(
 #endif
   } else {
     std::string e = "does not recognize <key> " + key;
-    this->SetError(e);
+    status.SetError(e);
     return false;
   }
 
   return true;
 }
 
-std::string cmCMakeHostSystemInformationCommand::ValueToString(
-  size_t value) const
+std::string ValueToString(size_t value)
 {
   std::ostringstream tmp;
   tmp << value;
   return tmp.str();
 }
 
-std::string cmCMakeHostSystemInformationCommand::ValueToString(
-  const char* value) const
+std::string ValueToString(const char* value)
 {
   std::string safe_string = value ? value : "";
   return safe_string;
 }
 
-std::string cmCMakeHostSystemInformationCommand::ValueToString(
-  std::string const& value) const
+std::string ValueToString(std::string const& value)
 {
   return value;
 }
+}
diff --git a/Source/cmCMakeHostSystemInformationCommand.h b/Source/cmCMakeHostSystemInformationCommand.h
index 8ea2d55..79e3f27 100644
--- a/Source/cmCMakeHostSystemInformationCommand.h
+++ b/Source/cmCMakeHostSystemInformationCommand.h
@@ -5,50 +5,18 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
-#include <stddef.h>
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
-namespace cmsys {
-class SystemInformation;
-} // namespace cmsys
 
-/** \class cmCMakeHostSystemInformationCommand
+/**
  * \brief Query host system specific information
  *
  * cmCMakeHostSystemInformationCommand queries system information of
  * the system on which CMake runs.
  */
-class cmCMakeHostSystemInformationCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmCMakeHostSystemInformationCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-
-private:
-  bool GetValue(cmsys::SystemInformation& info, std::string const& key,
-                std::string& value);
-
-  std::string ValueToString(size_t value) const;
-  std::string ValueToString(const char* value) const;
-  std::string ValueToString(std::string const& value) const;
-};
+bool cmCMakeHostSystemInformationCommand(std::vector<std::string> const& args,
+                                         cmExecutionStatus& status);
 
 #endif
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 6b0af79..ff21df8 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -200,9 +200,8 @@ void GetScriptingCommands(cmState* state)
     "match the opening WHILE command.");
 
 #if !defined(CMAKE_BOOTSTRAP)
-  state->AddBuiltinCommand(
-    "cmake_host_system_information",
-    cm::make_unique<cmCMakeHostSystemInformationCommand>());
+  state->AddBuiltinCommand("cmake_host_system_information",
+                           cmCMakeHostSystemInformationCommand);
   state->AddBuiltinCommand("remove", cm::make_unique<cmRemoveCommand>());
   state->AddBuiltinCommand("variable_watch",
                            cm::make_unique<cmVariableWatchCommand>());
-- 
cgit v0.12


From b1acc711f4cdf62a850c09a85256482db2e2af2e Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Fri, 9 Aug 2019 11:51:17 +0200
Subject: cmCommand refactor: cmRemoveCommand

---
 Source/cmCommands.cxx      |  2 +-
 Source/cmRemoveCommand.cxx | 11 +++++------
 Source/cmRemoveCommand.h   | 26 +++-----------------------
 3 files changed, 9 insertions(+), 30 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index ff21df8..6a3af27 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -202,7 +202,7 @@ void GetScriptingCommands(cmState* state)
 #if !defined(CMAKE_BOOTSTRAP)
   state->AddBuiltinCommand("cmake_host_system_information",
                            cmCMakeHostSystemInformationCommand);
-  state->AddBuiltinCommand("remove", cm::make_unique<cmRemoveCommand>());
+  state->AddBuiltinCommand("remove", cmRemoveCommand);
   state->AddBuiltinCommand("variable_watch",
                            cm::make_unique<cmVariableWatchCommand>());
   state->AddBuiltinCommand("write_file",
diff --git a/Source/cmRemoveCommand.cxx b/Source/cmRemoveCommand.cxx
index 4ba21fa..457b708 100644
--- a/Source/cmRemoveCommand.cxx
+++ b/Source/cmRemoveCommand.cxx
@@ -2,14 +2,13 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmRemoveCommand.h"
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmStringAlgorithms.h"
 
-class cmExecutionStatus;
-
 // cmRemoveCommand
-bool cmRemoveCommand::InitialPass(std::vector<std::string> const& args,
-                                  cmExecutionStatus&)
+bool cmRemoveCommand(std::vector<std::string> const& args,
+                     cmExecutionStatus& status)
 {
   if (args.empty()) {
     return true;
@@ -17,7 +16,7 @@ bool cmRemoveCommand::InitialPass(std::vector<std::string> const& args,
 
   std::string const& variable = args[0]; // VAR is always first
   // get the old value
-  const char* cacheValue = this->Makefile->GetDefinition(variable);
+  const char* cacheValue = status.GetMakefile().GetDefinition(variable);
 
   // if there is no old value then return
   if (!cacheValue) {
@@ -51,7 +50,7 @@ bool cmRemoveCommand::InitialPass(std::vector<std::string> const& args,
   }
 
   // add the definition
-  this->Makefile->AddDefinition(variable, value);
+  status.GetMakefile().AddDefinition(variable, value);
 
   return true;
 }
diff --git a/Source/cmRemoveCommand.h b/Source/cmRemoveCommand.h
index 088d8ad..fb72ab5 100644
--- a/Source/cmRemoveCommand.h
+++ b/Source/cmRemoveCommand.h
@@ -8,34 +8,14 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmRemoveCommand
+/**
  * \brief remove command
  *
  * cmRemoveCommand implements the remove CMake command
  */
-class cmRemoveCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmRemoveCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-};
+bool cmRemoveCommand(std::vector<std::string> const& args,
+                     cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From ca3b9186bb0830b26765bd764d5d9d69cf93e33d Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Fri, 9 Aug 2019 11:54:15 +0200
Subject: cmCommand refactor: cmVariableWatchCommand

---
 Source/cmCommands.cxx             |  3 +--
 Source/cmVariableWatchCommand.cxx | 14 ++++++++------
 Source/cmVariableWatchCommand.h   | 26 +++-----------------------
 3 files changed, 12 insertions(+), 31 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 6a3af27..0fa2529 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -203,8 +203,7 @@ void GetScriptingCommands(cmState* state)
   state->AddBuiltinCommand("cmake_host_system_information",
                            cmCMakeHostSystemInformationCommand);
   state->AddBuiltinCommand("remove", cmRemoveCommand);
-  state->AddBuiltinCommand("variable_watch",
-                           cm::make_unique<cmVariableWatchCommand>());
+  state->AddBuiltinCommand("variable_watch", cmVariableWatchCommand);
   state->AddBuiltinCommand("write_file",
                            cm::make_unique<cmWriteFileCommand>());
 
diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx
index 83a774d..db23efd 100644
--- a/Source/cmVariableWatchCommand.cxx
+++ b/Source/cmVariableWatchCommand.cxx
@@ -2,6 +2,7 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmVariableWatchCommand.h"
 
+#include <memory>
 #include <sstream>
 #include <utility>
 
@@ -119,11 +120,11 @@ private:
   std::shared_ptr<Impl const> Action;
 };
 
-bool cmVariableWatchCommand::InitialPass(std::vector<std::string> const& args,
-                                         cmExecutionStatus&)
+bool cmVariableWatchCommand(std::vector<std::string> const& args,
+                            cmExecutionStatus& status)
 {
   if (args.empty()) {
-    this->SetError("must be called with at least one argument.");
+    status.SetError("must be called with at least one argument.");
     return false;
   }
   std::string const& variable = args[0];
@@ -134,7 +135,7 @@ bool cmVariableWatchCommand::InitialPass(std::vector<std::string> const& args,
   if (variable == "CMAKE_CURRENT_LIST_FILE") {
     std::ostringstream ostr;
     ostr << "cannot be set on the variable: " << variable;
-    this->SetError(ostr.str());
+    status.SetError(ostr.str());
     return false;
   }
 
@@ -143,13 +144,14 @@ bool cmVariableWatchCommand::InitialPass(std::vector<std::string> const& args,
   data->InCallback = false;
   data->Command = command;
 
-  if (!this->Makefile->GetCMakeInstance()->GetVariableWatch()->AddWatch(
+  if (!status.GetMakefile().GetCMakeInstance()->GetVariableWatch()->AddWatch(
         variable, cmVariableWatchCommandVariableAccessed, data,
         deleteVariableWatchCallbackData)) {
     deleteVariableWatchCallbackData(data);
     return false;
   }
 
-  this->Makefile->AddFinalAction(FinalAction(this->Makefile, variable));
+  status.GetMakefile().AddFinalAction(
+    FinalAction(&status.GetMakefile(), variable));
   return true;
 }
diff --git a/Source/cmVariableWatchCommand.h b/Source/cmVariableWatchCommand.h
index 221269f..3f9f244 100644
--- a/Source/cmVariableWatchCommand.h
+++ b/Source/cmVariableWatchCommand.h
@@ -8,33 +8,13 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmVariableWatchCommand
+/**
  * \brief Watch when the variable changes and invoke command
  *
  */
-class cmVariableWatchCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmVariableWatchCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-};
+bool cmVariableWatchCommand(std::vector<std::string> const& args,
+                            cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From 07ea93de5447e0bc20b4632fa61d965c02876cc8 Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Fri, 9 Aug 2019 11:56:34 +0200
Subject: cmCommand refactor: cmWriteFileCommand

---
 Source/cmCommands.cxx         |  3 +--
 Source/cmWriteFileCommand.cxx | 15 +++++++--------
 Source/cmWriteFileCommand.h   | 26 +++-----------------------
 3 files changed, 11 insertions(+), 33 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 0fa2529..6f6ca50 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -204,8 +204,7 @@ void GetScriptingCommands(cmState* state)
                            cmCMakeHostSystemInformationCommand);
   state->AddBuiltinCommand("remove", cmRemoveCommand);
   state->AddBuiltinCommand("variable_watch", cmVariableWatchCommand);
-  state->AddBuiltinCommand("write_file",
-                           cm::make_unique<cmWriteFileCommand>());
+  state->AddBuiltinCommand("write_file", cmWriteFileCommand);
 
   state->AddDisallowedCommand(
     "build_name", cm::make_unique<cmBuildNameCommand>(), cmPolicies::CMP0036,
diff --git a/Source/cmWriteFileCommand.cxx b/Source/cmWriteFileCommand.cxx
index 49dbf1a..63af65d 100644
--- a/Source/cmWriteFileCommand.cxx
+++ b/Source/cmWriteFileCommand.cxx
@@ -4,18 +4,17 @@
 
 #include "cmsys/FStream.hxx"
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmSystemTools.h"
 #include "cm_sys_stat.h"
 
-class cmExecutionStatus;
-
 // cmLibraryCommand
-bool cmWriteFileCommand::InitialPass(std::vector<std::string> const& args,
-                                     cmExecutionStatus&)
+bool cmWriteFileCommand(std::vector<std::string> const& args,
+                        cmExecutionStatus& status)
 {
   if (args.size() < 2) {
-    this->SetError("called with incorrect number of arguments");
+    status.SetError("called with incorrect number of arguments");
     return false;
   }
   std::string message;
@@ -33,10 +32,10 @@ bool cmWriteFileCommand::InitialPass(std::vector<std::string> const& args,
     }
   }
 
-  if (!this->Makefile->CanIWriteThisFile(fileName)) {
+  if (!status.GetMakefile().CanIWriteThisFile(fileName)) {
     std::string e =
       "attempted to write a file: " + fileName + " into a source directory.";
-    this->SetError(e);
+    status.SetError(e);
     cmSystemTools::SetFatalErrorOccured();
     return false;
   }
@@ -68,7 +67,7 @@ bool cmWriteFileCommand::InitialPass(std::vector<std::string> const& args,
     std::string error = "Internal CMake error when trying to open file: ";
     error += fileName;
     error += " for writing.";
-    this->SetError(error);
+    status.SetError(error);
     return false;
   }
   file << message << std::endl;
diff --git a/Source/cmWriteFileCommand.h b/Source/cmWriteFileCommand.h
index 3961898..3e0e043 100644
--- a/Source/cmWriteFileCommand.h
+++ b/Source/cmWriteFileCommand.h
@@ -8,33 +8,13 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmWriteFileCommand
+/**
  * \brief Writes a message to a file
  *
  */
-class cmWriteFileCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmWriteFileCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-};
+bool cmWriteFileCommand(std::vector<std::string> const& args,
+                        cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From 9413952c42d83fb10a70ee96e91a20c55c5f2edc Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Fri, 9 Aug 2019 12:09:39 +0200
Subject: cmCommand refactor: cmCMakePolicyCommand

---
 Source/cmCMakePolicyCommand.cxx | 105 +++++++++++++++++++++++-----------------
 Source/cmCMakePolicyCommand.h   |  32 ++----------
 Source/cmCommands.cxx           |   3 +-
 Source/cmMakefile.h             |   3 +-
 4 files changed, 66 insertions(+), 77 deletions(-)

diff --git a/Source/cmCMakePolicyCommand.cxx b/Source/cmCMakePolicyCommand.cxx
index ce046fc..9b1aea9 100644
--- a/Source/cmCMakePolicyCommand.cxx
+++ b/Source/cmCMakePolicyCommand.cxx
@@ -4,88 +4,101 @@
 
 #include <sstream>
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmPolicies.h"
 #include "cmState.h"
 #include "cmStateTypes.h"
 
-class cmExecutionStatus;
+namespace {
+bool HandleSetMode(std::vector<std::string> const& args,
+                   cmExecutionStatus& status);
+bool HandleGetMode(std::vector<std::string> const& args,
+                   cmExecutionStatus& status);
+bool HandleVersionMode(std::vector<std::string> const& args,
+                       cmExecutionStatus& status);
+bool HandleGetWarningMode(std::vector<std::string> const& args,
+                          cmExecutionStatus& status);
+}
 
 // cmCMakePolicyCommand
-bool cmCMakePolicyCommand::InitialPass(std::vector<std::string> const& args,
-                                       cmExecutionStatus&)
+bool cmCMakePolicyCommand(std::vector<std::string> const& args,
+                          cmExecutionStatus& status)
 {
   if (args.empty()) {
-    this->SetError("requires at least one argument.");
+    status.SetError("requires at least one argument.");
     return false;
   }
 
   if (args[0] == "SET") {
-    return this->HandleSetMode(args);
+    return HandleSetMode(args, status);
   }
   if (args[0] == "GET") {
-    return this->HandleGetMode(args);
+    return HandleGetMode(args, status);
   }
   if (args[0] == "PUSH") {
     if (args.size() > 1) {
-      this->SetError("PUSH may not be given additional arguments.");
+      status.SetError("PUSH may not be given additional arguments.");
       return false;
     }
-    this->Makefile->PushPolicy();
+    status.GetMakefile().PushPolicy();
     return true;
   }
   if (args[0] == "POP") {
     if (args.size() > 1) {
-      this->SetError("POP may not be given additional arguments.");
+      status.SetError("POP may not be given additional arguments.");
       return false;
     }
-    this->Makefile->PopPolicy();
+    status.GetMakefile().PopPolicy();
     return true;
   }
   if (args[0] == "VERSION") {
-    return this->HandleVersionMode(args);
+    return HandleVersionMode(args, status);
   }
   if (args[0] == "GET_WARNING") {
-    return this->HandleGetWarningMode(args);
+    return HandleGetWarningMode(args, status);
   }
 
   std::ostringstream e;
   e << "given unknown first argument \"" << args[0] << "\"";
-  this->SetError(e.str());
+  status.SetError(e.str());
   return false;
 }
 
-bool cmCMakePolicyCommand::HandleSetMode(std::vector<std::string> const& args)
+namespace {
+
+bool HandleSetMode(std::vector<std::string> const& args,
+                   cmExecutionStatus& status)
 {
   if (args.size() != 3) {
-    this->SetError("SET must be given exactly 2 additional arguments.");
+    status.SetError("SET must be given exactly 2 additional arguments.");
     return false;
   }
 
-  cmPolicies::PolicyStatus status;
+  cmPolicies::PolicyStatus policyStatus;
   if (args[2] == "OLD") {
-    status = cmPolicies::OLD;
+    policyStatus = cmPolicies::OLD;
   } else if (args[2] == "NEW") {
-    status = cmPolicies::NEW;
+    policyStatus = cmPolicies::NEW;
   } else {
     std::ostringstream e;
     e << "SET given unrecognized policy status \"" << args[2] << "\"";
-    this->SetError(e.str());
+    status.SetError(e.str());
     return false;
   }
 
-  if (!this->Makefile->SetPolicy(args[1].c_str(), status)) {
-    this->SetError("SET failed to set policy.");
+  if (!status.GetMakefile().SetPolicy(args[1].c_str(), policyStatus)) {
+    status.SetError("SET failed to set policy.");
     return false;
   }
   if (args[1] == "CMP0001" &&
-      (status == cmPolicies::WARN || status == cmPolicies::OLD)) {
-    if (!(this->Makefile->GetState()->GetInitializedCacheValue(
+      (policyStatus == cmPolicies::WARN || policyStatus == cmPolicies::OLD)) {
+    if (!(status.GetMakefile().GetState()->GetInitializedCacheValue(
           "CMAKE_BACKWARDS_COMPATIBILITY"))) {
       // Set it to 2.4 because that is the last version where the
       // variable had meaning.
-      this->Makefile->AddCacheDefinition(
+      status.GetMakefile().AddCacheDefinition(
         "CMAKE_BACKWARDS_COMPATIBILITY", "2.4",
         "For backwards compatibility, what version of CMake "
         "commands and "
@@ -96,14 +109,15 @@ bool cmCMakePolicyCommand::HandleSetMode(std::vector<std::string> const& args)
   return true;
 }
 
-bool cmCMakePolicyCommand::HandleGetMode(std::vector<std::string> const& args)
+bool HandleGetMode(std::vector<std::string> const& args,
+                   cmExecutionStatus& status)
 {
   bool parent_scope = false;
   if (args.size() == 4 && args[3] == "PARENT_SCOPE") {
     // Undocumented PARENT_SCOPE option for use within CMake.
     parent_scope = true;
   } else if (args.size() != 3) {
-    this->SetError("GET must be given exactly 2 additional arguments.");
+    status.SetError("GET must be given exactly 2 additional arguments.");
     return false;
   }
 
@@ -117,25 +131,25 @@ bool cmCMakePolicyCommand::HandleGetMode(std::vector<std::string> const& args)
     std::ostringstream e;
     e << "GET given policy \"" << id << "\" which is not known to this "
       << "version of CMake.";
-    this->SetError(e.str());
+    status.SetError(e.str());
     return false;
   }
 
   // Lookup the policy setting.
-  cmPolicies::PolicyStatus status =
-    this->Makefile->GetPolicyStatus(pid, parent_scope);
-  switch (status) {
+  cmPolicies::PolicyStatus policyStatus =
+    status.GetMakefile().GetPolicyStatus(pid, parent_scope);
+  switch (policyStatus) {
     case cmPolicies::OLD:
       // Report that the policy is set to OLD.
-      this->Makefile->AddDefinition(var, "OLD");
+      status.GetMakefile().AddDefinition(var, "OLD");
       break;
     case cmPolicies::WARN:
       // Report that the policy is not set.
-      this->Makefile->AddDefinition(var, "");
+      status.GetMakefile().AddDefinition(var, "");
       break;
     case cmPolicies::NEW:
       // Report that the policy is set to NEW.
-      this->Makefile->AddDefinition(var, "NEW");
+      status.GetMakefile().AddDefinition(var, "NEW");
       break;
     case cmPolicies::REQUIRED_IF_USED:
     case cmPolicies::REQUIRED_ALWAYS:
@@ -146,22 +160,22 @@ bool cmCMakePolicyCommand::HandleGetMode(std::vector<std::string> const& args)
           << "The call to cmake_policy(GET " << id << " ...) at which this "
           << "error appears requests the policy, and this version of CMake "
           << "requires that the policy be set to NEW before it is checked.";
-        this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+        status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str());
       }
   }
 
   return true;
 }
 
-bool cmCMakePolicyCommand::HandleVersionMode(
-  std::vector<std::string> const& args)
+bool HandleVersionMode(std::vector<std::string> const& args,
+                       cmExecutionStatus& status)
 {
   if (args.size() <= 1) {
-    this->SetError("VERSION not given an argument");
+    status.SetError("VERSION not given an argument");
     return false;
   }
   if (args.size() >= 3) {
-    this->SetError("VERSION given too many arguments");
+    status.SetError("VERSION given too many arguments");
     return false;
   }
   std::string const& version_string = args[1];
@@ -177,19 +191,19 @@ bool cmCMakePolicyCommand::HandleVersionMode(
     std::ostringstream e;
     e << "VERSION \"" << version_string
       << R"(" does not have a version on both sides of "...".)";
-    this->SetError(e.str());
+    status.SetError(e.str());
     return false;
   }
 
-  this->Makefile->SetPolicyVersion(version_min, version_max);
+  status.GetMakefile().SetPolicyVersion(version_min, version_max);
   return true;
 }
 
-bool cmCMakePolicyCommand::HandleGetWarningMode(
-  std::vector<std::string> const& args)
+bool HandleGetWarningMode(std::vector<std::string> const& args,
+                          cmExecutionStatus& status)
 {
   if (args.size() != 3) {
-    this->SetError(
+    status.SetError(
       "GET_WARNING must be given exactly 2 additional arguments.");
     return false;
   }
@@ -204,12 +218,13 @@ bool cmCMakePolicyCommand::HandleGetWarningMode(
     std::ostringstream e;
     e << "GET_WARNING given policy \"" << id
       << "\" which is not known to this version of CMake.";
-    this->SetError(e.str());
+    status.SetError(e.str());
     return false;
   }
 
   // Lookup the policy warning.
-  this->Makefile->AddDefinition(var, cmPolicies::GetPolicyWarning(pid));
+  status.GetMakefile().AddDefinition(var, cmPolicies::GetPolicyWarning(pid));
 
   return true;
 }
+}
diff --git a/Source/cmCMakePolicyCommand.h b/Source/cmCMakePolicyCommand.h
index 919402c..ba9397d 100644
--- a/Source/cmCMakePolicyCommand.h
+++ b/Source/cmCMakePolicyCommand.h
@@ -8,41 +8,15 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmCMakePolicyCommand
+/**
  * \brief Set how CMake should handle policies
  *
  * cmCMakePolicyCommand sets how CMake should deal with backwards
  * compatibility policies.
  */
-class cmCMakePolicyCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmCMakePolicyCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-
-private:
-  bool HandleSetMode(std::vector<std::string> const& args);
-  bool HandleGetMode(std::vector<std::string> const& args);
-  bool HandleVersionMode(std::vector<std::string> const& args);
-  bool HandleGetWarningMode(std::vector<std::string> const& args);
-};
+bool cmCMakePolicyCommand(std::vector<std::string> const& args,
+                          cmExecutionStatus& status);
 
 #endif
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 6f6ca50..df61b4e 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -118,8 +118,7 @@ void GetScriptingCommands(cmState* state)
 {
   state->AddBuiltinCommand("break", cmBreakCommand);
   state->AddBuiltinCommand("cmake_minimum_required", cmCMakeMinimumRequired);
-  state->AddBuiltinCommand("cmake_policy",
-                           cm::make_unique<cmCMakePolicyCommand>());
+  state->AddBuiltinCommand("cmake_policy", cmCMakePolicyCommand);
   state->AddBuiltinCommand("configure_file", cmConfigureFileCommand);
   state->AddBuiltinCommand("continue", cmContinueCommand);
   state->AddBuiltinCommand("exec_program", cmExecProgramCommand);
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index a6d1757..dcc4e77 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -1002,7 +1002,8 @@ private:
                   cmPolicies::PolicyMap const& pm = cmPolicies::PolicyMap());
   void PopPolicy();
   void PopSnapshot(bool reportError = true);
-  friend class cmCMakePolicyCommand;
+  friend bool cmCMakePolicyCommand(std::vector<std::string> const& args,
+                                   cmExecutionStatus& status);
   class IncludeScope;
 
   friend class IncludeScope;
-- 
cgit v0.12


From 7c83c192056536defb35df36acf753701a2e78a2 Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Fri, 9 Aug 2019 14:24:17 +0200
Subject: cmCommand refactor: cmSetDirectoryPropertiesCommand

---
 Source/cmCommands.cxx                      |  2 +-
 Source/cmSetDirectoryPropertiesCommand.cxx | 29 ++++++++++++++++++-----------
 Source/cmSetDirectoryPropertiesCommand.h   | 30 ++----------------------------
 3 files changed, 21 insertions(+), 40 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index df61b4e..6a66c7b 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -155,7 +155,7 @@ void GetScriptingCommands(cmState* state)
   state->AddBuiltinCommand("separate_arguments", cmSeparateArgumentsCommand);
   state->AddBuiltinCommand("set", cmSetCommand);
   state->AddBuiltinCommand("set_directory_properties",
-                           cm::make_unique<cmSetDirectoryPropertiesCommand>());
+                           cmSetDirectoryPropertiesCommand);
   state->AddBuiltinCommand("set_property",
                            cm::make_unique<cmSetPropertyCommand>());
   state->AddBuiltinCommand("site_name", cmSiteNameCommand);
diff --git a/Source/cmSetDirectoryPropertiesCommand.cxx b/Source/cmSetDirectoryPropertiesCommand.cxx
index 8d3961a..35daca6 100644
--- a/Source/cmSetDirectoryPropertiesCommand.cxx
+++ b/Source/cmSetDirectoryPropertiesCommand.cxx
@@ -2,31 +2,37 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmSetDirectoryPropertiesCommand.h"
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 
-class cmExecutionStatus;
+namespace {
+bool RunCommand(cmMakefile& mf, std::vector<std::string>::const_iterator ait,
+                std::vector<std::string>::const_iterator aitend,
+                std::string& errors);
+}
 
 // cmSetDirectoryPropertiesCommand
-bool cmSetDirectoryPropertiesCommand::InitialPass(
-  std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmSetDirectoryPropertiesCommand(std::vector<std::string> const& args,
+                                     cmExecutionStatus& status)
 {
   if (args.empty()) {
-    this->SetError("called with incorrect number of arguments");
+    status.SetError("called with incorrect number of arguments");
     return false;
   }
 
   std::string errors;
-  bool ret = cmSetDirectoryPropertiesCommand::RunCommand(
-    this->Makefile, args.begin() + 1, args.end(), errors);
+  bool ret =
+    RunCommand(status.GetMakefile(), args.begin() + 1, args.end(), errors);
   if (!ret) {
-    this->SetError(errors);
+    status.SetError(errors);
   }
   return ret;
 }
 
-bool cmSetDirectoryPropertiesCommand::RunCommand(
-  cmMakefile* mf, std::vector<std::string>::const_iterator ait,
-  std::vector<std::string>::const_iterator aitend, std::string& errors)
+namespace {
+bool RunCommand(cmMakefile& mf, std::vector<std::string>::const_iterator ait,
+                std::vector<std::string>::const_iterator aitend,
+                std::string& errors)
 {
   for (; ait != aitend; ait += 2) {
     if (ait + 1 == aitend) {
@@ -43,8 +49,9 @@ bool cmSetDirectoryPropertiesCommand::RunCommand(
       errors = "Commands and macros cannot be set using SET_CMAKE_PROPERTIES";
       return false;
     }
-    mf->SetProperty(prop, value.c_str());
+    mf.SetProperty(prop, value.c_str());
   }
 
   return true;
 }
+}
diff --git a/Source/cmSetDirectoryPropertiesCommand.h b/Source/cmSetDirectoryPropertiesCommand.h
index 5416127..c243dd7 100644
--- a/Source/cmSetDirectoryPropertiesCommand.h
+++ b/Source/cmSetDirectoryPropertiesCommand.h
@@ -8,35 +8,9 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
-class cmMakefile;
-
-class cmSetDirectoryPropertiesCommand : public cmCommand
-{
-public:
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmSetDirectoryPropertiesCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the input file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
 
-  /**
-   * Static entry point for use by other commands
-   */
-  static bool RunCommand(cmMakefile* mf,
-                         std::vector<std::string>::const_iterator ait,
-                         std::vector<std::string>::const_iterator aitend,
-                         std::string& errors);
-};
+bool cmSetDirectoryPropertiesCommand(std::vector<std::string> const& args,
+                                     cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From 36f32d360410562efe5a986d1966c7fc80c596f8 Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Fri, 9 Aug 2019 15:07:45 +0200
Subject: cmCommand refactor: cmSetPropertyCommand

---
 Source/cmCommands.cxx           |   3 +-
 Source/cmSetPropertyCommand.cxx | 401 +++++++++++++++++++++++++---------------
 Source/cmSetPropertyCommand.h   |  50 +----
 3 files changed, 256 insertions(+), 198 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 6a66c7b..c0263d6 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -156,8 +156,7 @@ void GetScriptingCommands(cmState* state)
   state->AddBuiltinCommand("set", cmSetCommand);
   state->AddBuiltinCommand("set_directory_properties",
                            cmSetDirectoryPropertiesCommand);
-  state->AddBuiltinCommand("set_property",
-                           cm::make_unique<cmSetPropertyCommand>());
+  state->AddBuiltinCommand("set_property", cmSetPropertyCommand);
   state->AddBuiltinCommand("site_name", cmSiteNameCommand);
   state->AddBuiltinCommand("string", cm::make_unique<cmStringCommand>());
   state->AddBuiltinCommand("unset", cmUnsetCommand);
diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx
index 9192c11..72291dc 100644
--- a/Source/cmSetPropertyCommand.cxx
+++ b/Source/cmSetPropertyCommand.cxx
@@ -2,8 +2,10 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmSetPropertyCommand.h"
 
+#include <set>
 #include <sstream>
 
+#include "cmExecutionStatus.h"
 #include "cmGlobalGenerator.h"
 #include "cmInstalledFile.h"
 #include "cmMakefile.h"
@@ -17,20 +19,66 @@
 #include "cmTest.h"
 #include "cmake.h"
 
-class cmExecutionStatus;
-
-cmSetPropertyCommand::cmSetPropertyCommand()
-{
-  this->AppendMode = false;
-  this->AppendAsString = false;
-  this->Remove = true;
+namespace {
+bool HandleGlobalMode(cmExecutionStatus& status,
+                      const std::set<std::string>& names,
+                      const std::string& propertyName,
+                      const std::string& propertyValue, bool appendAsString,
+                      bool appendMode, bool remove);
+bool HandleDirectoryMode(cmExecutionStatus& status,
+                         const std::set<std::string>& names,
+                         const std::string& propertyName,
+                         const std::string& propertyValue, bool appendAsString,
+                         bool appendMode, bool remove);
+bool HandleTargetMode(cmExecutionStatus& status,
+                      const std::set<std::string>& names,
+                      const std::string& propertyName,
+                      const std::string& propertyValue, bool appendAsString,
+                      bool appendMode, bool remove);
+bool HandleTarget(cmTarget* target, cmMakefile& makefile,
+                  const std::string& propertyName,
+                  const std::string& propertyValue, bool appendAsString,
+                  bool appendMode, bool remove);
+bool HandleSourceMode(cmExecutionStatus& status,
+                      const std::set<std::string>& names,
+                      const std::string& propertyName,
+                      const std::string& propertyValue, bool appendAsString,
+                      bool appendMode, bool remove);
+bool HandleSource(cmSourceFile* sf, const std::string& propertyName,
+                  const std::string& propertyValue, bool appendAsString,
+                  bool appendMode, bool remove);
+bool HandleTestMode(cmExecutionStatus& status, std::set<std::string>& names,
+                    const std::string& propertyName,
+                    const std::string& propertyValue, bool appendAsString,
+                    bool appendMode, bool remove);
+bool HandleTest(cmTest* test, const std::string& propertyName,
+                const std::string& propertyValue, bool appendAsString,
+                bool appendMode, bool remove);
+bool HandleCacheMode(cmExecutionStatus& status,
+                     const std::set<std::string>& names,
+                     const std::string& propertyName,
+                     const std::string& propertyValue, bool appendAsString,
+                     bool appendMode, bool remove);
+bool HandleCacheEntry(std::string const& cacheKey, const cmMakefile& makefile,
+                      const std::string& propertyName,
+                      const std::string& propertyValue, bool appendAsString,
+                      bool appendMode, bool remove);
+bool HandleInstallMode(cmExecutionStatus& status,
+                       const std::set<std::string>& names,
+                       const std::string& propertyName,
+                       const std::string& propertyValue, bool appendAsString,
+                       bool appendMode, bool remove);
+bool HandleInstall(cmInstalledFile* file, cmMakefile& makefile,
+                   const std::string& propertyName,
+                   const std::string& propertyValue, bool appendAsString,
+                   bool appendMode, bool remove);
 }
 
-bool cmSetPropertyCommand::InitialPass(std::vector<std::string> const& args,
-                                       cmExecutionStatus&)
+bool cmSetPropertyCommand(std::vector<std::string> const& args,
+                          cmExecutionStatus& status)
 {
   if (args.size() < 2) {
-    this->SetError("called with incorrect number of arguments");
+    status.SetError("called with incorrect number of arguments");
     return false;
   }
 
@@ -56,10 +104,17 @@ bool cmSetPropertyCommand::InitialPass(std::vector<std::string> const& args,
     e << "given invalid scope " << scopeName << ".  "
       << "Valid scopes are GLOBAL, DIRECTORY, "
          "TARGET, SOURCE, TEST, CACHE, INSTALL.";
-    this->SetError(e.str());
+    status.SetError(e.str());
     return false;
   }
 
+  bool appendAsString = false;
+  bool appendMode = false;
+  bool remove = true;
+  std::set<std::string> names;
+  std::string propertyName;
+  std::string propertyValue;
+
   // Parse the rest of the arguments up to the values.
   enum Doing
   {
@@ -75,54 +130,61 @@ bool cmSetPropertyCommand::InitialPass(std::vector<std::string> const& args,
       doing = DoingProperty;
     } else if (arg == "APPEND") {
       doing = DoingNone;
-      this->AppendMode = true;
-      this->Remove = false;
-      this->AppendAsString = false;
+      appendMode = true;
+      remove = false;
+      appendAsString = false;
     } else if (arg == "APPEND_STRING") {
       doing = DoingNone;
-      this->AppendMode = true;
-      this->Remove = false;
-      this->AppendAsString = true;
+      appendMode = true;
+      remove = false;
+      appendAsString = true;
     } else if (doing == DoingNames) {
-      this->Names.insert(arg);
+      names.insert(arg);
     } else if (doing == DoingProperty) {
-      this->PropertyName = arg;
+      propertyName = arg;
       doing = DoingValues;
     } else if (doing == DoingValues) {
-      this->PropertyValue += sep;
+      propertyValue += sep;
       sep = ";";
-      this->PropertyValue += arg;
-      this->Remove = false;
+      propertyValue += arg;
+      remove = false;
     } else {
       std::ostringstream e;
       e << "given invalid argument \"" << arg << "\".";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
   }
 
   // Make sure a property name was found.
-  if (this->PropertyName.empty()) {
-    this->SetError("not given a PROPERTY <name> argument.");
+  if (propertyName.empty()) {
+    status.SetError("not given a PROPERTY <name> argument.");
     return false;
   }
 
   // Dispatch property setting.
   switch (scope) {
     case cmProperty::GLOBAL:
-      return this->HandleGlobalMode();
+      return HandleGlobalMode(status, names, propertyName, propertyValue,
+                              appendAsString, appendMode, remove);
     case cmProperty::DIRECTORY:
-      return this->HandleDirectoryMode();
+      return HandleDirectoryMode(status, names, propertyName, propertyValue,
+                                 appendAsString, appendMode, remove);
     case cmProperty::TARGET:
-      return this->HandleTargetMode();
+      return HandleTargetMode(status, names, propertyName, propertyValue,
+                              appendAsString, appendMode, remove);
     case cmProperty::SOURCE_FILE:
-      return this->HandleSourceMode();
+      return HandleSourceMode(status, names, propertyName, propertyValue,
+                              appendAsString, appendMode, remove);
     case cmProperty::TEST:
-      return this->HandleTestMode();
+      return HandleTestMode(status, names, propertyName, propertyValue,
+                            appendAsString, appendMode, remove);
     case cmProperty::CACHE:
-      return this->HandleCacheMode();
+      return HandleCacheMode(status, names, propertyName, propertyValue,
+                             appendAsString, appendMode, remove);
     case cmProperty::INSTALL:
-      return this->HandleInstallMode();
+      return HandleInstallMode(status, names, propertyName, propertyValue,
+                               appendAsString, appendMode, remove);
 
     case cmProperty::VARIABLE:
     case cmProperty::CACHED_VARIABLE:
@@ -131,57 +193,67 @@ bool cmSetPropertyCommand::InitialPass(std::vector<std::string> const& args,
   return true;
 }
 
-bool cmSetPropertyCommand::HandleGlobalMode()
+namespace {
+bool HandleGlobalMode(cmExecutionStatus& status,
+                      const std::set<std::string>& names,
+                      const std::string& propertyName,
+                      const std::string& propertyValue,
+                      const bool appendAsString, const bool appendMode,
+                      const bool remove)
 {
-  if (!this->Names.empty()) {
-    this->SetError("given names for GLOBAL scope.");
+  if (!names.empty()) {
+    status.SetError("given names for GLOBAL scope.");
     return false;
   }
 
   // Set or append the property.
-  cmake* cm = this->Makefile->GetCMakeInstance();
-  std::string const& name = this->PropertyName;
-  const char* value = this->PropertyValue.c_str();
-  if (this->Remove) {
+  cmake* cm = status.GetMakefile().GetCMakeInstance();
+  const char* value = propertyValue.c_str();
+  if (remove) {
     value = nullptr;
   }
-  if (this->AppendMode) {
-    cm->AppendProperty(name, value ? value : "", this->AppendAsString);
+  if (appendMode) {
+    cm->AppendProperty(propertyName, value ? value : "", appendAsString);
   } else {
-    cm->SetProperty(name, value);
+    cm->SetProperty(propertyName, value);
   }
 
   return true;
 }
 
-bool cmSetPropertyCommand::HandleDirectoryMode()
+bool HandleDirectoryMode(cmExecutionStatus& status,
+                         const std::set<std::string>& names,
+                         const std::string& propertyName,
+                         const std::string& propertyValue,
+                         const bool appendAsString, const bool appendMode,
+                         const bool remove)
 {
-  if (this->Names.size() > 1) {
-    this->SetError("allows at most one name for DIRECTORY scope.");
+  if (names.size() > 1) {
+    status.SetError("allows at most one name for DIRECTORY scope.");
     return false;
   }
 
   // Default to the current directory.
-  cmMakefile* mf = this->Makefile;
+  cmMakefile* mf = &status.GetMakefile();
 
   // Lookup the directory if given.
-  if (!this->Names.empty()) {
+  if (!names.empty()) {
     // Construct the directory name.  Interpret relative paths with
     // respect to the current directory.
-    std::string dir = *this->Names.begin();
+    std::string dir = *names.begin();
     if (!cmSystemTools::FileIsFullPath(dir)) {
-      dir = this->Makefile->GetCurrentSourceDirectory();
+      dir = status.GetMakefile().GetCurrentSourceDirectory();
       dir += "/";
-      dir += *this->Names.begin();
+      dir += *names.begin();
     }
 
     // The local generators are associated with collapsed paths.
     dir = cmSystemTools::CollapseFullPath(dir);
 
-    mf = this->Makefile->GetGlobalGenerator()->FindMakefile(dir);
+    mf = status.GetMakefile().GetGlobalGenerator()->FindMakefile(dir);
     if (!mf) {
       // Could not find the directory.
-      this->SetError(
+      status.SetError(
         "DIRECTORY scope provided but requested directory was not found. "
         "This could be because the directory argument was invalid or, "
         "it is valid but has not been processed yet.");
@@ -190,109 +262,128 @@ bool cmSetPropertyCommand::HandleDirectoryMode()
   }
 
   // Set or append the property.
-  std::string const& name = this->PropertyName;
-  const char* value = this->PropertyValue.c_str();
-  if (this->Remove) {
+  const char* value = propertyValue.c_str();
+  if (remove) {
     value = nullptr;
   }
-  if (this->AppendMode) {
-    mf->AppendProperty(name, value ? value : "", this->AppendAsString);
+  if (appendMode) {
+    mf->AppendProperty(propertyName, value ? value : "", appendAsString);
   } else {
-    mf->SetProperty(name, value);
+    mf->SetProperty(propertyName, value);
   }
 
   return true;
 }
 
-bool cmSetPropertyCommand::HandleTargetMode()
+bool HandleTargetMode(cmExecutionStatus& status,
+                      const std::set<std::string>& names,
+                      const std::string& propertyName,
+                      const std::string& propertyValue,
+                      const bool appendAsString, const bool appendMode,
+                      const bool remove)
 {
-  for (std::string const& name : this->Names) {
-    if (this->Makefile->IsAlias(name)) {
-      this->SetError("can not be used on an ALIAS target.");
+  for (std::string const& name : names) {
+    if (status.GetMakefile().IsAlias(name)) {
+      status.SetError("can not be used on an ALIAS target.");
       return false;
     }
-    if (cmTarget* target = this->Makefile->FindTargetToUse(name)) {
+    if (cmTarget* target = status.GetMakefile().FindTargetToUse(name)) {
       // Handle the current target.
-      if (!this->HandleTarget(target)) {
+      if (!HandleTarget(target, status.GetMakefile(), propertyName,
+                        propertyValue, appendAsString, appendMode, remove)) {
         return false;
       }
     } else {
       std::ostringstream e;
       e << "could not find TARGET " << name
         << ".  Perhaps it has not yet been created.";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
   }
   return true;
 }
 
-bool cmSetPropertyCommand::HandleTarget(cmTarget* target)
+bool HandleTarget(cmTarget* target, cmMakefile& makefile,
+                  const std::string& propertyName,
+                  const std::string& propertyValue, const bool appendAsString,
+                  const bool appendMode, const bool remove)
 {
   // Set or append the property.
-  std::string const& name = this->PropertyName;
-  const char* value = this->PropertyValue.c_str();
-  if (this->Remove) {
+  const char* value = propertyValue.c_str();
+  if (remove) {
     value = nullptr;
   }
-  if (this->AppendMode) {
-    target->AppendProperty(name, value, this->AppendAsString);
+  if (appendMode) {
+    target->AppendProperty(propertyName, value, appendAsString);
   } else {
-    target->SetProperty(name, value);
+    target->SetProperty(propertyName, value);
   }
 
   // Check the resulting value.
-  target->CheckProperty(name, this->Makefile);
+  target->CheckProperty(propertyName, &makefile);
 
   return true;
 }
 
-bool cmSetPropertyCommand::HandleSourceMode()
+bool HandleSourceMode(cmExecutionStatus& status,
+                      const std::set<std::string>& names,
+                      const std::string& propertyName,
+                      const std::string& propertyValue,
+                      const bool appendAsString, const bool appendMode,
+                      const bool remove)
 {
-  for (std::string const& name : this->Names) {
+  for (std::string const& name : names) {
     // Get the source file.
-    if (cmSourceFile* sf = this->Makefile->GetOrCreateSource(name)) {
-      if (!this->HandleSource(sf)) {
+    if (cmSourceFile* sf = status.GetMakefile().GetOrCreateSource(name)) {
+      if (!HandleSource(sf, propertyName, propertyValue, appendAsString,
+                        appendMode, remove)) {
         return false;
       }
     } else {
       std::ostringstream e;
       e << "given SOURCE name that could not be found or created: " << name;
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
   }
   return true;
 }
 
-bool cmSetPropertyCommand::HandleSource(cmSourceFile* sf)
+bool HandleSource(cmSourceFile* sf, const std::string& propertyName,
+                  const std::string& propertyValue, const bool appendAsString,
+                  const bool appendMode, const bool remove)
 {
   // Set or append the property.
-  std::string const& name = this->PropertyName;
-  const char* value = this->PropertyValue.c_str();
-  if (this->Remove) {
+  const char* value = propertyValue.c_str();
+  if (remove) {
     value = nullptr;
   }
 
-  if (this->AppendMode) {
-    sf->AppendProperty(name, value, this->AppendAsString);
+  if (appendMode) {
+    sf->AppendProperty(propertyName, value, appendAsString);
   } else {
-    sf->SetProperty(name, value);
+    sf->SetProperty(propertyName, value);
   }
   return true;
 }
 
-bool cmSetPropertyCommand::HandleTestMode()
+bool HandleTestMode(cmExecutionStatus& status, std::set<std::string>& names,
+                    const std::string& propertyName,
+                    const std::string& propertyValue,
+                    const bool appendAsString, const bool appendMode,
+                    const bool remove)
 {
   // Look for tests with all names given.
   std::set<std::string>::iterator next;
-  for (std::set<std::string>::iterator ni = this->Names.begin();
-       ni != this->Names.end(); ni = next) {
+  for (std::set<std::string>::iterator ni = names.begin(); ni != names.end();
+       ni = next) {
     next = ni;
     ++next;
-    if (cmTest* test = this->Makefile->GetTest(*ni)) {
-      if (this->HandleTest(test)) {
-        this->Names.erase(ni);
+    if (cmTest* test = status.GetMakefile().GetTest(*ni)) {
+      if (HandleTest(test, propertyName, propertyValue, appendAsString,
+                     appendMode, remove)) {
+        names.erase(ni);
       } else {
         return false;
       }
@@ -300,137 +391,151 @@ bool cmSetPropertyCommand::HandleTestMode()
   }
 
   // Names that are still left were not found.
-  if (!this->Names.empty()) {
+  if (!names.empty()) {
     std::ostringstream e;
     e << "given TEST names that do not exist:\n";
-    for (std::string const& name : this->Names) {
+    for (std::string const& name : names) {
       e << "  " << name << "\n";
     }
-    this->SetError(e.str());
+    status.SetError(e.str());
     return false;
   }
   return true;
 }
 
-bool cmSetPropertyCommand::HandleTest(cmTest* test)
+bool HandleTest(cmTest* test, const std::string& propertyName,
+                const std::string& propertyValue, const bool appendAsString,
+                const bool appendMode, const bool remove)
 {
   // Set or append the property.
-  std::string const& name = this->PropertyName;
-  const char* value = this->PropertyValue.c_str();
-  if (this->Remove) {
+  const char* value = propertyValue.c_str();
+  if (remove) {
     value = nullptr;
   }
-  if (this->AppendMode) {
-    test->AppendProperty(name, value, this->AppendAsString);
+  if (appendMode) {
+    test->AppendProperty(propertyName, value, appendAsString);
   } else {
-    test->SetProperty(name, value);
+    test->SetProperty(propertyName, value);
   }
 
   return true;
 }
 
-bool cmSetPropertyCommand::HandleCacheMode()
+bool HandleCacheMode(cmExecutionStatus& status,
+                     const std::set<std::string>& names,
+                     const std::string& propertyName,
+                     const std::string& propertyValue,
+                     const bool appendAsString, const bool appendMode,
+                     const bool remove)
 {
-  if (this->PropertyName == "ADVANCED") {
-    if (!this->Remove && !cmIsOn(this->PropertyValue) &&
-        !cmIsOff(this->PropertyValue)) {
+  if (propertyName == "ADVANCED") {
+    if (!remove && !cmIsOn(propertyValue) && !cmIsOff(propertyValue)) {
       std::ostringstream e;
-      e << "given non-boolean value \"" << this->PropertyValue
+      e << "given non-boolean value \"" << propertyValue
         << R"(" for CACHE property "ADVANCED".  )";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
-  } else if (this->PropertyName == "TYPE") {
-    if (!cmState::IsCacheEntryType(this->PropertyValue)) {
+  } else if (propertyName == "TYPE") {
+    if (!cmState::IsCacheEntryType(propertyValue)) {
       std::ostringstream e;
-      e << "given invalid CACHE entry TYPE \"" << this->PropertyValue << "\"";
-      this->SetError(e.str());
+      e << "given invalid CACHE entry TYPE \"" << propertyValue << "\"";
+      status.SetError(e.str());
       return false;
     }
-  } else if (this->PropertyName != "HELPSTRING" &&
-             this->PropertyName != "STRINGS" &&
-             this->PropertyName != "VALUE") {
+  } else if (propertyName != "HELPSTRING" && propertyName != "STRINGS" &&
+             propertyName != "VALUE") {
     std::ostringstream e;
-    e << "given invalid CACHE property " << this->PropertyName << ".  "
+    e << "given invalid CACHE property " << propertyName << ".  "
       << "Settable CACHE properties are: "
       << "ADVANCED, HELPSTRING, STRINGS, TYPE, and VALUE.";
-    this->SetError(e.str());
+    status.SetError(e.str());
     return false;
   }
 
-  for (std::string const& name : this->Names) {
+  for (std::string const& name : names) {
     // Get the source file.
-    cmMakefile* mf = this->GetMakefile();
-    cmake* cm = mf->GetCMakeInstance();
+    cmake* cm = status.GetMakefile().GetCMakeInstance();
     const char* existingValue = cm->GetState()->GetCacheEntryValue(name);
     if (existingValue) {
-      if (!this->HandleCacheEntry(name)) {
+      if (!HandleCacheEntry(name, status.GetMakefile(), propertyName,
+                            propertyValue, appendAsString, appendMode,
+                            remove)) {
         return false;
       }
     } else {
       std::ostringstream e;
       e << "could not find CACHE variable " << name
         << ".  Perhaps it has not yet been created.";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
   }
   return true;
 }
 
-bool cmSetPropertyCommand::HandleCacheEntry(std::string const& cacheKey)
+bool HandleCacheEntry(std::string const& cacheKey, const cmMakefile& makefile,
+                      const std::string& propertyName,
+                      const std::string& propertyValue,
+                      const bool appendAsString, const bool appendMode,
+                      const bool remove)
 {
   // Set or append the property.
-  std::string const& name = this->PropertyName;
-  const char* value = this->PropertyValue.c_str();
-  cmState* state = this->Makefile->GetState();
-  if (this->Remove) {
-    state->RemoveCacheEntryProperty(cacheKey, name);
+  const char* value = propertyValue.c_str();
+  cmState* state = makefile.GetState();
+  if (remove) {
+    state->RemoveCacheEntryProperty(cacheKey, propertyName);
   }
-  if (this->AppendMode) {
-    state->AppendCacheEntryProperty(cacheKey, name, value,
-                                    this->AppendAsString);
+  if (appendMode) {
+    state->AppendCacheEntryProperty(cacheKey, propertyName, value,
+                                    appendAsString);
   } else {
-    state->SetCacheEntryProperty(cacheKey, name, value);
+    state->SetCacheEntryProperty(cacheKey, propertyName, value);
   }
 
   return true;
 }
 
-bool cmSetPropertyCommand::HandleInstallMode()
+bool HandleInstallMode(cmExecutionStatus& status,
+                       const std::set<std::string>& names,
+                       const std::string& propertyName,
+                       const std::string& propertyValue,
+                       const bool appendAsString, const bool appendMode,
+                       const bool remove)
 {
-  cmake* cm = this->Makefile->GetCMakeInstance();
+  cmake* cm = status.GetMakefile().GetCMakeInstance();
 
-  for (std::string const& name : this->Names) {
+  for (std::string const& name : names) {
     if (cmInstalledFile* file =
-          cm->GetOrCreateInstalledFile(this->Makefile, name)) {
-      if (!this->HandleInstall(file)) {
+          cm->GetOrCreateInstalledFile(&status.GetMakefile(), name)) {
+      if (!HandleInstall(file, status.GetMakefile(), propertyName,
+                         propertyValue, appendAsString, appendMode, remove)) {
         return false;
       }
     } else {
       std::ostringstream e;
       e << "given INSTALL name that could not be found or created: " << name;
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
   }
   return true;
 }
 
-bool cmSetPropertyCommand::HandleInstall(cmInstalledFile* file)
+bool HandleInstall(cmInstalledFile* file, cmMakefile& makefile,
+                   const std::string& propertyName,
+                   const std::string& propertyValue, const bool appendAsString,
+                   const bool appendMode, const bool remove)
 {
   // Set or append the property.
-  std::string const& name = this->PropertyName;
-
-  cmMakefile* mf = this->Makefile;
-
-  const char* value = this->PropertyValue.c_str();
-  if (this->Remove) {
-    file->RemoveProperty(name);
-  } else if (this->AppendMode) {
-    file->AppendProperty(mf, name, value, this->AppendAsString);
+  const char* value = propertyValue.c_str();
+  if (remove) {
+    file->RemoveProperty(propertyName);
+  } else if (appendMode) {
+    file->AppendProperty(&makefile, propertyName, value, appendAsString);
   } else {
-    file->SetProperty(mf, name, value);
+    file->SetProperty(&makefile, propertyName, value);
   }
   return true;
 }
+}
diff --git a/Source/cmSetPropertyCommand.h b/Source/cmSetPropertyCommand.h
index 4051e48..ec36f84 100644
--- a/Source/cmSetPropertyCommand.h
+++ b/Source/cmSetPropertyCommand.h
@@ -5,58 +5,12 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
-#include <set>
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
-class cmInstalledFile;
-class cmSourceFile;
-class cmTarget;
-class cmTest;
-
-class cmSetPropertyCommand : public cmCommand
-{
-public:
-  cmSetPropertyCommand();
-
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmSetPropertyCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the input file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-
-private:
-  std::set<std::string> Names;
-  std::string PropertyName;
-  std::string PropertyValue;
-  bool Remove;
-  bool AppendMode;
-  bool AppendAsString;
 
-  // Implementation of each property type.
-  bool HandleGlobalMode();
-  bool HandleDirectoryMode();
-  bool HandleTargetMode();
-  bool HandleTarget(cmTarget* target);
-  bool HandleSourceMode();
-  bool HandleSource(cmSourceFile* sf);
-  bool HandleTestMode();
-  bool HandleTest(cmTest* test);
-  bool HandleCacheMode();
-  bool HandleCacheEntry(std::string const&);
-  bool HandleInstallMode();
-  bool HandleInstall(cmInstalledFile* file);
-};
+bool cmSetPropertyCommand(std::vector<std::string> const& args,
+                          cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12


From 6ab28b9413ade87cf9fbaad439f8cb4c27ecc97f Mon Sep 17 00:00:00 2001
From: Gabor Bencze <b.gabor98@gmail.com>
Date: Fri, 9 Aug 2019 15:24:14 +0200
Subject: cmCommand refactor: cmStringCommand

---
 Source/cmCommands.cxx      |   2 +-
 Source/cmStringCommand.cxx | 403 ++++++++++++++++++++++++++-------------------
 Source/cmStringCommand.h   |  57 +------
 3 files changed, 241 insertions(+), 221 deletions(-)

diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index c0263d6..dd9b9a1 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -158,7 +158,7 @@ void GetScriptingCommands(cmState* state)
                            cmSetDirectoryPropertiesCommand);
   state->AddBuiltinCommand("set_property", cmSetPropertyCommand);
   state->AddBuiltinCommand("site_name", cmSiteNameCommand);
-  state->AddBuiltinCommand("string", cm::make_unique<cmStringCommand>());
+  state->AddBuiltinCommand("string", cmStringCommand);
   state->AddBuiltinCommand("unset", cmUnsetCommand);
   state->AddBuiltinCommand("while", cmWhileCommand);
 
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index 5bff0e5..0f1adb3 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -8,12 +8,14 @@
 #include <algorithm>
 #include <ctype.h>
 #include <iterator>
+#include <memory>
 #include <sstream>
 #include <stdio.h>
 #include <stdlib.h>
 
 #include "cmAlgorithms.h"
 #include "cmCryptoHash.h"
+#include "cmExecutionStatus.h"
 #include "cmGeneratorExpression.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
@@ -24,123 +26,177 @@
 #include "cmTimestamp.h"
 #include "cmUuid.h"
 
-class cmExecutionStatus;
+namespace {
+bool HandleConfigureCommand(std::vector<std::string> const& args,
+                            cmExecutionStatus& status);
+bool HandleAsciiCommand(std::vector<std::string> const& args,
+                        cmExecutionStatus& status);
+bool HandleRegexCommand(std::vector<std::string> const& args,
+                        cmExecutionStatus& status);
+bool RegexMatch(std::vector<std::string> const& args,
+                cmExecutionStatus& status);
+bool RegexMatchAll(std::vector<std::string> const& args,
+                   cmExecutionStatus& status);
+bool RegexReplace(std::vector<std::string> const& args,
+                  cmExecutionStatus& status);
+bool HandleHashCommand(std::vector<std::string> const& args,
+                       cmExecutionStatus& status);
+bool HandleToUpperLowerCommand(std::vector<std::string> const& args,
+                               bool toUpper, cmExecutionStatus& status);
+bool HandleCompareCommand(std::vector<std::string> const& args,
+                          cmExecutionStatus& status);
+bool HandleReplaceCommand(std::vector<std::string> const& args,
+                          cmExecutionStatus& status);
+bool HandleLengthCommand(std::vector<std::string> const& args,
+                         cmExecutionStatus& status);
+bool HandleSubstringCommand(std::vector<std::string> const& args,
+                            cmExecutionStatus& status);
+bool HandleAppendCommand(std::vector<std::string> const& args,
+                         cmExecutionStatus& status);
+bool HandlePrependCommand(std::vector<std::string> const& args,
+                          cmExecutionStatus& status);
+bool HandleConcatCommand(std::vector<std::string> const& args,
+                         cmExecutionStatus& status);
+bool HandleJoinCommand(std::vector<std::string> const& args,
+                       cmExecutionStatus& status);
+bool HandleStripCommand(std::vector<std::string> const& args,
+                        cmExecutionStatus& status);
+bool HandleRepeatCommand(std::vector<std::string> const& args,
+                         cmMakefile& makefile);
+bool HandleRandomCommand(std::vector<std::string> const& args,
+                         cmExecutionStatus& status);
+bool HandleFindCommand(std::vector<std::string> const& args,
+                       cmExecutionStatus& status);
+bool HandleTimestampCommand(std::vector<std::string> const& args,
+                            cmExecutionStatus& status);
+bool HandleMakeCIdentifierCommand(std::vector<std::string> const& args,
+                                  cmExecutionStatus& status);
+bool HandleGenexStripCommand(std::vector<std::string> const& args,
+                             cmExecutionStatus& status);
+bool HandleUuidCommand(std::vector<std::string> const& args,
+                       cmExecutionStatus& status);
+
+bool joinImpl(std::vector<std::string> const& args, std::string const& glue,
+              size_t varIdx, cmMakefile& makefile);
+}
 
-bool cmStringCommand::InitialPass(std::vector<std::string> const& args,
-                                  cmExecutionStatus&)
+bool cmStringCommand(std::vector<std::string> const& args,
+                     cmExecutionStatus& status)
 {
   if (args.empty()) {
-    this->SetError("must be called with at least one argument.");
+    status.SetError("must be called with at least one argument.");
     return false;
   }
 
   const std::string& subCommand = args[0];
   if (subCommand == "REGEX") {
-    return this->HandleRegexCommand(args);
+    return HandleRegexCommand(args, status);
   }
   if (subCommand == "REPLACE") {
-    return this->HandleReplaceCommand(args);
+    return HandleReplaceCommand(args, status);
   }
   if (subCommand == "MD5" || subCommand == "SHA1" || subCommand == "SHA224" ||
       subCommand == "SHA256" || subCommand == "SHA384" ||
       subCommand == "SHA512" || subCommand == "SHA3_224" ||
       subCommand == "SHA3_256" || subCommand == "SHA3_384" ||
       subCommand == "SHA3_512") {
-    return this->HandleHashCommand(args);
+    return HandleHashCommand(args, status);
   }
   if (subCommand == "TOLOWER") {
-    return this->HandleToUpperLowerCommand(args, false);
+    return HandleToUpperLowerCommand(args, false, status);
   }
   if (subCommand == "TOUPPER") {
-    return this->HandleToUpperLowerCommand(args, true);
+    return HandleToUpperLowerCommand(args, true, status);
   }
   if (subCommand == "COMPARE") {
-    return this->HandleCompareCommand(args);
+    return HandleCompareCommand(args, status);
   }
   if (subCommand == "ASCII") {
-    return this->HandleAsciiCommand(args);
+    return HandleAsciiCommand(args, status);
   }
   if (subCommand == "CONFIGURE") {
-    return this->HandleConfigureCommand(args);
+    return HandleConfigureCommand(args, status);
   }
   if (subCommand == "LENGTH") {
-    return this->HandleLengthCommand(args);
+    return HandleLengthCommand(args, status);
   }
   if (subCommand == "APPEND") {
-    return this->HandleAppendCommand(args);
+    return HandleAppendCommand(args, status);
   }
   if (subCommand == "PREPEND") {
-    return this->HandlePrependCommand(args);
+    return HandlePrependCommand(args, status);
   }
   if (subCommand == "CONCAT") {
-    return this->HandleConcatCommand(args);
+    return HandleConcatCommand(args, status);
   }
   if (subCommand == "JOIN") {
-    return this->HandleJoinCommand(args);
+    return HandleJoinCommand(args, status);
   }
   if (subCommand == "SUBSTRING") {
-    return this->HandleSubstringCommand(args);
+    return HandleSubstringCommand(args, status);
   }
   if (subCommand == "STRIP") {
-    return this->HandleStripCommand(args);
+    return HandleStripCommand(args, status);
   }
   if (subCommand == "REPEAT") {
-    return this->HandleRepeatCommand(args);
+    return HandleRepeatCommand(args, status.GetMakefile());
   }
   if (subCommand == "RANDOM") {
-    return this->HandleRandomCommand(args);
+    return HandleRandomCommand(args, status);
   }
   if (subCommand == "FIND") {
-    return this->HandleFindCommand(args);
+    return HandleFindCommand(args, status);
   }
   if (subCommand == "TIMESTAMP") {
-    return this->HandleTimestampCommand(args);
+    return HandleTimestampCommand(args, status);
   }
   if (subCommand == "MAKE_C_IDENTIFIER") {
-    return this->HandleMakeCIdentifierCommand(args);
+    return HandleMakeCIdentifierCommand(args, status);
   }
   if (subCommand == "GENEX_STRIP") {
-    return this->HandleGenexStripCommand(args);
+    return HandleGenexStripCommand(args, status);
   }
   if (subCommand == "UUID") {
-    return this->HandleUuidCommand(args);
+    return HandleUuidCommand(args, status);
   }
 
   std::string e = "does not recognize sub-command " + subCommand;
-  this->SetError(e);
+  status.SetError(e);
   return false;
 }
 
-bool cmStringCommand::HandleHashCommand(std::vector<std::string> const& args)
+namespace {
+bool HandleHashCommand(std::vector<std::string> const& args,
+                       cmExecutionStatus& status)
 {
 #if !defined(CMAKE_BOOTSTRAP)
   if (args.size() != 3) {
     std::ostringstream e;
     e << args[0] << " requires an output variable and an input string";
-    this->SetError(e.str());
+    status.SetError(e.str());
     return false;
   }
 
   std::unique_ptr<cmCryptoHash> hash(cmCryptoHash::New(args[0]));
   if (hash) {
     std::string out = hash->HashString(args[2]);
-    this->Makefile->AddDefinition(args[1], out);
+    status.GetMakefile().AddDefinition(args[1], out);
     return true;
   }
   return false;
 #else
   std::ostringstream e;
   e << args[0] << " not available during bootstrap";
-  this->SetError(e.str().c_str());
+  status.SetError(e.str().c_str());
   return false;
 #endif
 }
 
-bool cmStringCommand::HandleToUpperLowerCommand(
-  std::vector<std::string> const& args, bool toUpper)
+bool HandleToUpperLowerCommand(std::vector<std::string> const& args,
+                               bool toUpper, cmExecutionStatus& status)
 {
   if (args.size() < 3) {
-    this->SetError("no output variable specified");
+    status.SetError("no output variable specified");
     return false;
   }
 
@@ -154,14 +210,15 @@ bool cmStringCommand::HandleToUpperLowerCommand(
   }
 
   // Store the output in the provided variable.
-  this->Makefile->AddDefinition(outvar, output);
+  status.GetMakefile().AddDefinition(outvar, output);
   return true;
 }
 
-bool cmStringCommand::HandleAsciiCommand(std::vector<std::string> const& args)
+bool HandleAsciiCommand(std::vector<std::string> const& args,
+                        cmExecutionStatus& status)
 {
   if (args.size() < 3) {
-    this->SetError("No output variable specified");
+    status.SetError("No output variable specified");
     return false;
   }
   std::string::size_type cc;
@@ -175,24 +232,24 @@ bool cmStringCommand::HandleAsciiCommand(std::vector<std::string> const& args)
       std::string error = "Character with code ";
       error += args[cc];
       error += " does not exist.";
-      this->SetError(error);
+      status.SetError(error);
       return false;
     }
   }
   // Store the output in the provided variable.
-  this->Makefile->AddDefinition(outvar, output);
+  status.GetMakefile().AddDefinition(outvar, output);
   return true;
 }
 
-bool cmStringCommand::HandleConfigureCommand(
-  std::vector<std::string> const& args)
+bool HandleConfigureCommand(std::vector<std::string> const& args,
+                            cmExecutionStatus& status)
 {
   if (args.size() < 2) {
-    this->SetError("No input string specified.");
+    status.SetError("No input string specified.");
     return false;
   }
   if (args.size() < 3) {
-    this->SetError("No output variable specified.");
+    status.SetError("No output variable specified.");
     return false;
   }
 
@@ -207,73 +264,75 @@ bool cmStringCommand::HandleConfigureCommand(
     } else {
       std::ostringstream err;
       err << "Unrecognized argument \"" << args[i] << "\"";
-      this->SetError(err.str());
+      status.SetError(err.str());
       return false;
     }
   }
 
   // Configure the string.
   std::string output;
-  this->Makefile->ConfigureString(args[1], output, atOnly, escapeQuotes);
+  status.GetMakefile().ConfigureString(args[1], output, atOnly, escapeQuotes);
 
   // Store the output in the provided variable.
-  this->Makefile->AddDefinition(args[2], output);
+  status.GetMakefile().AddDefinition(args[2], output);
 
   return true;
 }
 
-bool cmStringCommand::HandleRegexCommand(std::vector<std::string> const& args)
+bool HandleRegexCommand(std::vector<std::string> const& args,
+                        cmExecutionStatus& status)
 {
   if (args.size() < 2) {
-    this->SetError("sub-command REGEX requires a mode to be specified.");
+    status.SetError("sub-command REGEX requires a mode to be specified.");
     return false;
   }
   std::string const& mode = args[1];
   if (mode == "MATCH") {
     if (args.size() < 5) {
-      this->SetError("sub-command REGEX, mode MATCH needs "
-                     "at least 5 arguments total to command.");
+      status.SetError("sub-command REGEX, mode MATCH needs "
+                      "at least 5 arguments total to command.");
       return false;
     }
-    return this->RegexMatch(args);
+    return RegexMatch(args, status);
   }
   if (mode == "MATCHALL") {
     if (args.size() < 5) {
-      this->SetError("sub-command REGEX, mode MATCHALL needs "
-                     "at least 5 arguments total to command.");
+      status.SetError("sub-command REGEX, mode MATCHALL needs "
+                      "at least 5 arguments total to command.");
       return false;
     }
-    return this->RegexMatchAll(args);
+    return RegexMatchAll(args, status);
   }
   if (mode == "REPLACE") {
     if (args.size() < 6) {
-      this->SetError("sub-command REGEX, mode REPLACE needs "
-                     "at least 6 arguments total to command.");
+      status.SetError("sub-command REGEX, mode REPLACE needs "
+                      "at least 6 arguments total to command.");
       return false;
     }
-    return this->RegexReplace(args);
+    return RegexReplace(args, status);
   }
 
   std::string e = "sub-command REGEX does not recognize mode " + mode;
-  this->SetError(e);
+  status.SetError(e);
   return false;
 }
 
-bool cmStringCommand::RegexMatch(std::vector<std::string> const& args)
+bool RegexMatch(std::vector<std::string> const& args,
+                cmExecutionStatus& status)
 {
   //"STRING(REGEX MATCH <regular_expression> <output variable>
   // <input> [<input>...])\n";
   std::string const& regex = args[2];
   std::string const& outvar = args[3];
 
-  this->Makefile->ClearMatches();
+  status.GetMakefile().ClearMatches();
   // Compile the regular expression.
   cmsys::RegularExpression re;
   if (!re.compile(regex.c_str())) {
     std::string e =
       "sub-command REGEX, mode MATCH failed to compile regex \"" + regex +
       "\".";
-    this->SetError(e);
+    status.SetError(e);
     return false;
   }
 
@@ -283,38 +342,39 @@ bool cmStringCommand::RegexMatch(std::vector<std::string> const& args)
   // Scan through the input for all matches.
   std::string output;
   if (re.find(input)) {
-    this->Makefile->StoreMatches(re);
+    status.GetMakefile().StoreMatches(re);
     std::string::size_type l = re.start();
     std::string::size_type r = re.end();
     if (r - l == 0) {
       std::string e = "sub-command REGEX, mode MATCH regex \"" + regex +
         "\" matched an empty string.";
-      this->SetError(e);
+      status.SetError(e);
       return false;
     }
     output = input.substr(l, r - l);
   }
 
   // Store the output in the provided variable.
-  this->Makefile->AddDefinition(outvar, output);
+  status.GetMakefile().AddDefinition(outvar, output);
   return true;
 }
 
-bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args)
+bool RegexMatchAll(std::vector<std::string> const& args,
+                   cmExecutionStatus& status)
 {
   //"STRING(REGEX MATCHALL <regular_expression> <output variable> <input>
   // [<input>...])\n";
   std::string const& regex = args[2];
   std::string const& outvar = args[3];
 
-  this->Makefile->ClearMatches();
+  status.GetMakefile().ClearMatches();
   // Compile the regular expression.
   cmsys::RegularExpression re;
   if (!re.compile(regex.c_str())) {
     std::string e =
       "sub-command REGEX, mode MATCHALL failed to compile regex \"" + regex +
       "\".";
-    this->SetError(e);
+    status.SetError(e);
     return false;
   }
 
@@ -325,14 +385,14 @@ bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args)
   std::string output;
   const char* p = input.c_str();
   while (re.find(p)) {
-    this->Makefile->ClearMatches();
-    this->Makefile->StoreMatches(re);
+    status.GetMakefile().ClearMatches();
+    status.GetMakefile().StoreMatches(re);
     std::string::size_type l = re.start();
     std::string::size_type r = re.end();
     if (r - l == 0) {
       std::string e = "sub-command REGEX, mode MATCHALL regex \"" + regex +
         "\" matched an empty string.";
-      this->SetError(e);
+      status.SetError(e);
       return false;
     }
     if (!output.empty()) {
@@ -343,32 +403,33 @@ bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args)
   }
 
   // Store the output in the provided variable.
-  this->Makefile->AddDefinition(outvar, output);
+  status.GetMakefile().AddDefinition(outvar, output);
   return true;
 }
 
-bool cmStringCommand::RegexReplace(std::vector<std::string> const& args)
+bool RegexReplace(std::vector<std::string> const& args,
+                  cmExecutionStatus& status)
 {
   //"STRING(REGEX REPLACE <regular_expression> <replace_expression>
   // <output variable> <input> [<input>...])\n"
   std::string const& regex = args[2];
   std::string const& replace = args[3];
   std::string const& outvar = args[4];
-  cmStringReplaceHelper replaceHelper(regex, replace, this->Makefile);
+  cmStringReplaceHelper replaceHelper(regex, replace, &status.GetMakefile());
 
   if (!replaceHelper.IsReplaceExpressionValid()) {
-    this->SetError(
+    status.SetError(
       "sub-command REGEX, mode REPLACE: " + replaceHelper.GetError() + ".");
     return false;
   }
 
-  this->Makefile->ClearMatches();
+  status.GetMakefile().ClearMatches();
 
   if (!replaceHelper.IsRegularExpressionValid()) {
     std::string e =
       "sub-command REGEX, mode REPLACE failed to compile regex \"" + regex +
       "\".";
-    this->SetError(e);
+    status.SetError(e);
     return false;
   }
 
@@ -378,21 +439,22 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args)
   std::string output;
 
   if (!replaceHelper.Replace(input, output)) {
-    this->SetError(
+    status.SetError(
       "sub-command REGEX, mode REPLACE: " + replaceHelper.GetError() + ".");
     return false;
   }
 
   // Store the output in the provided variable.
-  this->Makefile->AddDefinition(outvar, output);
+  status.GetMakefile().AddDefinition(outvar, output);
   return true;
 }
 
-bool cmStringCommand::HandleFindCommand(std::vector<std::string> const& args)
+bool HandleFindCommand(std::vector<std::string> const& args,
+                       cmExecutionStatus& status)
 {
   // check if all required parameters were passed
   if (args.size() < 4 || args.size() > 5) {
-    this->SetError("sub-command FIND requires 3 or 4 parameters.");
+    status.SetError("sub-command FIND requires 3 or 4 parameters.");
     return false;
   }
 
@@ -404,7 +466,7 @@ bool cmStringCommand::HandleFindCommand(std::vector<std::string> const& args)
 
   // if we have 5 arguments the last one must be REVERSE
   if (args.size() == 5 && args[4] != "REVERSE") {
-    this->SetError("sub-command FIND: unknown last parameter");
+    status.SetError("sub-command FIND: unknown last parameter");
     return false;
   }
 
@@ -415,9 +477,9 @@ bool cmStringCommand::HandleFindCommand(std::vector<std::string> const& args)
 
   // ensure that the user cannot accidentally specify REVERSE as a variable
   if (outvar == "REVERSE") {
-    this->SetError("sub-command FIND does not allow one to select REVERSE as "
-                   "the output variable.  "
-                   "Maybe you missed the actual output variable?");
+    status.SetError("sub-command FIND does not allow one to select REVERSE as "
+                    "the output variable.  "
+                    "Maybe you missed the actual output variable?");
     return false;
   }
 
@@ -431,20 +493,20 @@ bool cmStringCommand::HandleFindCommand(std::vector<std::string> const& args)
   if (std::string::npos != pos) {
     std::ostringstream s;
     s << pos;
-    this->Makefile->AddDefinition(outvar, s.str());
+    status.GetMakefile().AddDefinition(outvar, s.str());
     return true;
   }
 
   // the character was not found, but this is not really an error
-  this->Makefile->AddDefinition(outvar, "-1");
+  status.GetMakefile().AddDefinition(outvar, "-1");
   return true;
 }
 
-bool cmStringCommand::HandleCompareCommand(
-  std::vector<std::string> const& args)
+bool HandleCompareCommand(std::vector<std::string> const& args,
+                          cmExecutionStatus& status)
 {
   if (args.size() < 2) {
-    this->SetError("sub-command COMPARE requires a mode to be specified.");
+    status.SetError("sub-command COMPARE requires a mode to be specified.");
     return false;
   }
   std::string const& mode = args[1];
@@ -455,7 +517,7 @@ bool cmStringCommand::HandleCompareCommand(
       std::string e = "sub-command COMPARE, mode ";
       e += mode;
       e += " needs at least 5 arguments total to command.";
-      this->SetError(e);
+      status.SetError(e);
       return false;
     }
 
@@ -478,22 +540,22 @@ bool cmStringCommand::HandleCompareCommand(
       result = !(left == right);
     }
     if (result) {
-      this->Makefile->AddDefinition(outvar, "1");
+      status.GetMakefile().AddDefinition(outvar, "1");
     } else {
-      this->Makefile->AddDefinition(outvar, "0");
+      status.GetMakefile().AddDefinition(outvar, "0");
     }
     return true;
   }
   std::string e = "sub-command COMPARE does not recognize mode " + mode;
-  this->SetError(e);
+  status.SetError(e);
   return false;
 }
 
-bool cmStringCommand::HandleReplaceCommand(
-  std::vector<std::string> const& args)
+bool HandleReplaceCommand(std::vector<std::string> const& args,
+                          cmExecutionStatus& status)
 {
   if (args.size() < 5) {
-    this->SetError("sub-command REPLACE requires at least four arguments.");
+    status.SetError("sub-command REPLACE requires at least four arguments.");
     return false;
   }
 
@@ -506,15 +568,15 @@ bool cmStringCommand::HandleReplaceCommand(
   cmsys::SystemTools::ReplaceString(input, matchExpression.c_str(),
                                     replaceExpression.c_str());
 
-  this->Makefile->AddDefinition(variableName, input);
+  status.GetMakefile().AddDefinition(variableName, input);
   return true;
 }
 
-bool cmStringCommand::HandleSubstringCommand(
-  std::vector<std::string> const& args)
+bool HandleSubstringCommand(std::vector<std::string> const& args,
+                            cmExecutionStatus& status)
 {
   if (args.size() != 5) {
-    this->SetError("sub-command SUBSTRING requires four arguments.");
+    status.SetError("sub-command SUBSTRING requires four arguments.");
     return false;
   }
 
@@ -529,24 +591,26 @@ bool cmStringCommand::HandleSubstringCommand(
     std::ostringstream ostr;
     ostr << "begin index: " << begin << " is out of range 0 - "
          << stringLength;
-    this->SetError(ostr.str());
+    status.SetError(ostr.str());
     return false;
   }
   if (end < -1) {
     std::ostringstream ostr;
     ostr << "end index: " << end << " should be -1 or greater";
-    this->SetError(ostr.str());
+    status.SetError(ostr.str());
     return false;
   }
 
-  this->Makefile->AddDefinition(variableName, stringValue.substr(begin, end));
+  status.GetMakefile().AddDefinition(variableName,
+                                     stringValue.substr(begin, end));
   return true;
 }
 
-bool cmStringCommand::HandleLengthCommand(std::vector<std::string> const& args)
+bool HandleLengthCommand(std::vector<std::string> const& args,
+                         cmExecutionStatus& status)
 {
   if (args.size() != 3) {
-    this->SetError("sub-command LENGTH requires two arguments.");
+    status.SetError("sub-command LENGTH requires two arguments.");
     return false;
   }
 
@@ -557,14 +621,15 @@ bool cmStringCommand::HandleLengthCommand(std::vector<std::string> const& args)
   char buffer[1024];
   sprintf(buffer, "%d", static_cast<int>(length));
 
-  this->Makefile->AddDefinition(variableName, buffer);
+  status.GetMakefile().AddDefinition(variableName, buffer);
   return true;
 }
 
-bool cmStringCommand::HandleAppendCommand(std::vector<std::string> const& args)
+bool HandleAppendCommand(std::vector<std::string> const& args,
+                         cmExecutionStatus& status)
 {
   if (args.size() < 2) {
-    this->SetError("sub-command APPEND requires at least one argument.");
+    status.SetError("sub-command APPEND requires at least one argument.");
     return false;
   }
 
@@ -576,20 +641,20 @@ bool cmStringCommand::HandleAppendCommand(std::vector<std::string> const& args)
   const std::string& variable = args[1];
 
   std::string value;
-  const char* oldValue = this->Makefile->GetDefinition(variable);
+  const char* oldValue = status.GetMakefile().GetDefinition(variable);
   if (oldValue) {
     value = oldValue;
   }
   value += cmJoin(cmMakeRange(args).advance(2), std::string());
-  this->Makefile->AddDefinition(variable, value);
+  status.GetMakefile().AddDefinition(variable, value);
   return true;
 }
 
-bool cmStringCommand::HandlePrependCommand(
-  std::vector<std::string> const& args)
+bool HandlePrependCommand(std::vector<std::string> const& args,
+                          cmExecutionStatus& status)
 {
   if (args.size() < 2) {
-    this->SetError("sub-command PREPEND requires at least one argument.");
+    status.SetError("sub-command PREPEND requires at least one argument.");
     return false;
   }
 
@@ -601,67 +666,69 @@ bool cmStringCommand::HandlePrependCommand(
   const std::string& variable = args[1];
 
   std::string value = cmJoin(cmMakeRange(args).advance(2), std::string());
-  const char* oldValue = this->Makefile->GetDefinition(variable);
+  const char* oldValue = status.GetMakefile().GetDefinition(variable);
   if (oldValue) {
     value += oldValue;
   }
-  this->Makefile->AddDefinition(variable, value);
+  status.GetMakefile().AddDefinition(variable, value);
   return true;
 }
 
-bool cmStringCommand::HandleConcatCommand(std::vector<std::string> const& args)
+bool HandleConcatCommand(std::vector<std::string> const& args,
+                         cmExecutionStatus& status)
 {
   if (args.size() < 2) {
-    this->SetError("sub-command CONCAT requires at least one argument.");
+    status.SetError("sub-command CONCAT requires at least one argument.");
     return false;
   }
 
-  return this->joinImpl(args, std::string(), 1);
+  return joinImpl(args, std::string(), 1, status.GetMakefile());
 }
 
-bool cmStringCommand::HandleJoinCommand(std::vector<std::string> const& args)
+bool HandleJoinCommand(std::vector<std::string> const& args,
+                       cmExecutionStatus& status)
 {
   if (args.size() < 3) {
-    this->SetError("sub-command JOIN requires at least two arguments.");
+    status.SetError("sub-command JOIN requires at least two arguments.");
     return false;
   }
 
-  return this->joinImpl(args, args[1], 2);
+  return joinImpl(args, args[1], 2, status.GetMakefile());
 }
 
-bool cmStringCommand::joinImpl(std::vector<std::string> const& args,
-                               std::string const& glue, const size_t varIdx)
+bool joinImpl(std::vector<std::string> const& args, std::string const& glue,
+              const size_t varIdx, cmMakefile& makefile)
 {
   std::string const& variableName = args[varIdx];
   // NOTE Items to concat/join placed right after the variable for
   // both `CONCAT` and `JOIN` sub-commands.
   std::string value = cmJoin(cmMakeRange(args).advance(varIdx + 1), glue);
 
-  this->Makefile->AddDefinition(variableName, value);
+  makefile.AddDefinition(variableName, value);
   return true;
 }
 
-bool cmStringCommand::HandleMakeCIdentifierCommand(
-  std::vector<std::string> const& args)
+bool HandleMakeCIdentifierCommand(std::vector<std::string> const& args,
+                                  cmExecutionStatus& status)
 {
   if (args.size() != 3) {
-    this->SetError("sub-command MAKE_C_IDENTIFIER requires two arguments.");
+    status.SetError("sub-command MAKE_C_IDENTIFIER requires two arguments.");
     return false;
   }
 
   const std::string& input = args[1];
   const std::string& variableName = args[2];
 
-  this->Makefile->AddDefinition(variableName,
-                                cmSystemTools::MakeCidentifier(input));
+  status.GetMakefile().AddDefinition(variableName,
+                                     cmSystemTools::MakeCidentifier(input));
   return true;
 }
 
-bool cmStringCommand::HandleGenexStripCommand(
-  std::vector<std::string> const& args)
+bool HandleGenexStripCommand(std::vector<std::string> const& args,
+                             cmExecutionStatus& status)
 {
   if (args.size() != 3) {
-    this->SetError("sub-command GENEX_STRIP requires two arguments.");
+    status.SetError("sub-command GENEX_STRIP requires two arguments.");
     return false;
   }
 
@@ -672,14 +739,15 @@ bool cmStringCommand::HandleGenexStripCommand(
 
   const std::string& variableName = args[2];
 
-  this->Makefile->AddDefinition(variableName, result);
+  status.GetMakefile().AddDefinition(variableName, result);
   return true;
 }
 
-bool cmStringCommand::HandleStripCommand(std::vector<std::string> const& args)
+bool HandleStripCommand(std::vector<std::string> const& args,
+                        cmExecutionStatus& status)
 {
   if (args.size() != 3) {
-    this->SetError("sub-command STRIP requires two arguments.");
+    status.SetError("sub-command STRIP requires two arguments.");
     return false;
   }
 
@@ -711,12 +779,13 @@ bool cmStringCommand::HandleStripCommand(std::vector<std::string> const& args)
     outLength = endPos - startPos + 1;
   }
 
-  this->Makefile->AddDefinition(variableName,
-                                stringValue.substr(startPos, outLength));
+  status.GetMakefile().AddDefinition(variableName,
+                                     stringValue.substr(startPos, outLength));
   return true;
 }
 
-bool cmStringCommand::HandleRepeatCommand(std::vector<std::string> const& args)
+bool HandleRepeatCommand(std::vector<std::string> const& args,
+                         cmMakefile& makefile)
 {
   // `string(REPEAT "<str>" <times> OUTPUT_VARIABLE)`
   enum ArgPos : std::size_t
@@ -729,16 +798,15 @@ bool cmStringCommand::HandleRepeatCommand(std::vector<std::string> const& args)
   };
 
   if (args.size() != ArgPos::TOTAL_ARGS) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "sub-command REPEAT requires three arguments.");
+    makefile.IssueMessage(MessageType::FATAL_ERROR,
+                          "sub-command REPEAT requires three arguments.");
     return true;
   }
 
   unsigned long times;
   if (!cmStrToULong(args[ArgPos::TIMES], &times)) {
-    this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
-                                 "repeat count is not a positive number.");
+    makefile.IssueMessage(MessageType::FATAL_ERROR,
+                          "repeat count is not a positive number.");
     return true;
   }
 
@@ -765,14 +833,15 @@ bool cmStringCommand::HandleRepeatCommand(std::vector<std::string> const& args)
       break;
   }
 
-  this->Makefile->AddDefinition(variableName, result);
+  makefile.AddDefinition(variableName, result);
   return true;
 }
 
-bool cmStringCommand::HandleRandomCommand(std::vector<std::string> const& args)
+bool HandleRandomCommand(std::vector<std::string> const& args,
+                         cmExecutionStatus& status)
 {
   if (args.size() < 2 || args.size() == 3 || args.size() == 5) {
-    this->SetError("sub-command RANDOM requires at least one argument.");
+    status.SetError("sub-command RANDOM requires at least one argument.");
     return false;
   }
 
@@ -809,11 +878,11 @@ bool cmStringCommand::HandleRandomCommand(std::vector<std::string> const& args)
 
   double sizeofAlphabet = static_cast<double>(alphabet.size());
   if (sizeofAlphabet < 1) {
-    this->SetError("sub-command RANDOM invoked with bad alphabet.");
+    status.SetError("sub-command RANDOM invoked with bad alphabet.");
     return false;
   }
   if (length < 1) {
-    this->SetError("sub-command RANDOM invoked with bad length.");
+    status.SetError("sub-command RANDOM invoked with bad length.");
     return false;
   }
   const std::string& variableName = args.back();
@@ -832,19 +901,19 @@ bool cmStringCommand::HandleRandomCommand(std::vector<std::string> const& args)
   }
   result.push_back(0);
 
-  this->Makefile->AddDefinition(variableName, result.data());
+  status.GetMakefile().AddDefinition(variableName, result.data());
   return true;
 }
 
-bool cmStringCommand::HandleTimestampCommand(
-  std::vector<std::string> const& args)
+bool HandleTimestampCommand(std::vector<std::string> const& args,
+                            cmExecutionStatus& status)
 {
   if (args.size() < 2) {
-    this->SetError("sub-command TIMESTAMP requires at least one argument.");
+    status.SetError("sub-command TIMESTAMP requires at least one argument.");
     return false;
   }
   if (args.size() > 4) {
-    this->SetError("sub-command TIMESTAMP takes at most three arguments.");
+    status.SetError("sub-command TIMESTAMP takes at most three arguments.");
     return false;
   }
 
@@ -864,25 +933,26 @@ bool cmStringCommand::HandleTimestampCommand(
     } else {
       std::string e = " TIMESTAMP sub-command does not recognize option " +
         args[argsIndex] + ".";
-      this->SetError(e);
+      status.SetError(e);
       return false;
     }
   }
 
   cmTimestamp timestamp;
   std::string result = timestamp.CurrentTime(formatString, utcFlag);
-  this->Makefile->AddDefinition(outputVariable, result);
+  status.GetMakefile().AddDefinition(outputVariable, result);
 
   return true;
 }
 
-bool cmStringCommand::HandleUuidCommand(std::vector<std::string> const& args)
+bool HandleUuidCommand(std::vector<std::string> const& args,
+                       cmExecutionStatus& status)
 {
 #if !defined(CMAKE_BOOTSTRAP)
   unsigned int argsIndex = 1;
 
   if (args.size() < 2) {
-    this->SetError("UUID sub-command requires an output variable.");
+    status.SetError("UUID sub-command requires an output variable.");
     return false;
   }
 
@@ -897,21 +967,21 @@ bool cmStringCommand::HandleUuidCommand(std::vector<std::string> const& args)
     if (args[argsIndex] == "NAMESPACE") {
       ++argsIndex;
       if (argsIndex >= args.size()) {
-        this->SetError("UUID sub-command, NAMESPACE requires a value.");
+        status.SetError("UUID sub-command, NAMESPACE requires a value.");
         return false;
       }
       uuidNamespaceString = args[argsIndex++];
     } else if (args[argsIndex] == "NAME") {
       ++argsIndex;
       if (argsIndex >= args.size()) {
-        this->SetError("UUID sub-command, NAME requires a value.");
+        status.SetError("UUID sub-command, NAME requires a value.");
         return false;
       }
       uuidName = args[argsIndex++];
     } else if (args[argsIndex] == "TYPE") {
       ++argsIndex;
       if (argsIndex >= args.size()) {
-        this->SetError("UUID sub-command, TYPE requires a value.");
+        status.SetError("UUID sub-command, TYPE requires a value.");
         return false;
       }
       uuidType = args[argsIndex++];
@@ -921,7 +991,7 @@ bool cmStringCommand::HandleUuidCommand(std::vector<std::string> const& args)
     } else {
       std::string e =
         "UUID sub-command does not recognize option " + args[argsIndex] + ".";
-      this->SetError(e);
+      status.SetError(e);
       return false;
     }
   }
@@ -931,7 +1001,7 @@ bool cmStringCommand::HandleUuidCommand(std::vector<std::string> const& args)
 
   std::vector<unsigned char> uuidNamespace;
   if (!uuidGenerator.StringToBinary(uuidNamespaceString, uuidNamespace)) {
-    this->SetError("UUID sub-command, malformed NAMESPACE UUID.");
+    status.SetError("UUID sub-command, malformed NAMESPACE UUID.");
     return false;
   }
 
@@ -941,12 +1011,12 @@ bool cmStringCommand::HandleUuidCommand(std::vector<std::string> const& args)
     uuid = uuidGenerator.FromSha1(uuidNamespace, uuidName);
   } else {
     std::string e = "UUID sub-command, unknown TYPE '" + uuidType + "'.";
-    this->SetError(e);
+    status.SetError(e);
     return false;
   }
 
   if (uuid.empty()) {
-    this->SetError("UUID sub-command, generation failed.");
+    status.SetError("UUID sub-command, generation failed.");
     return false;
   }
 
@@ -954,12 +1024,13 @@ bool cmStringCommand::HandleUuidCommand(std::vector<std::string> const& args)
     uuid = cmSystemTools::UpperCase(uuid);
   }
 
-  this->Makefile->AddDefinition(outputVariable, uuid);
+  status.GetMakefile().AddDefinition(outputVariable, uuid);
   return true;
 #else
   std::ostringstream e;
   e << args[0] << " not available during bootstrap";
-  this->SetError(e.str().c_str());
+  status.SetError(e.str().c_str());
   return false;
 #endif
 }
+}
diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h
index f48ea17..bd71ba2 100644
--- a/Source/cmStringCommand.h
+++ b/Source/cmStringCommand.h
@@ -5,67 +5,16 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
-#include <cstddef>
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmStringCommand
+/**
  * \brief Common string operations
  *
  */
-class cmStringCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmStringCommand>();
-  }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-
-protected:
-  bool HandleConfigureCommand(std::vector<std::string> const& args);
-  bool HandleAsciiCommand(std::vector<std::string> const& args);
-  bool HandleRegexCommand(std::vector<std::string> const& args);
-  bool RegexMatch(std::vector<std::string> const& args);
-  bool RegexMatchAll(std::vector<std::string> const& args);
-  bool RegexReplace(std::vector<std::string> const& args);
-  bool HandleHashCommand(std::vector<std::string> const& args);
-  bool HandleToUpperLowerCommand(std::vector<std::string> const& args,
-                                 bool toUpper);
-  bool HandleCompareCommand(std::vector<std::string> const& args);
-  bool HandleReplaceCommand(std::vector<std::string> const& args);
-  bool HandleLengthCommand(std::vector<std::string> const& args);
-  bool HandleSubstringCommand(std::vector<std::string> const& args);
-  bool HandleAppendCommand(std::vector<std::string> const& args);
-  bool HandlePrependCommand(std::vector<std::string> const& args);
-  bool HandleConcatCommand(std::vector<std::string> const& args);
-  bool HandleJoinCommand(std::vector<std::string> const& args);
-  bool HandleStripCommand(std::vector<std::string> const& args);
-  bool HandleRepeatCommand(std::vector<std::string> const& args);
-  bool HandleRandomCommand(std::vector<std::string> const& args);
-  bool HandleFindCommand(std::vector<std::string> const& args);
-  bool HandleTimestampCommand(std::vector<std::string> const& args);
-  bool HandleMakeCIdentifierCommand(std::vector<std::string> const& args);
-  bool HandleGenexStripCommand(std::vector<std::string> const& args);
-  bool HandleUuidCommand(std::vector<std::string> const& args);
-
-  bool joinImpl(std::vector<std::string> const& args, std::string const& glue,
-                size_t varIdx);
-};
+bool cmStringCommand(std::vector<std::string> const& args,
+                     cmExecutionStatus& status);
 
 #endif
-- 
cgit v0.12