Browse Source

cmCommand_refactor: cmGetPropertyCommand

Gabor Bencze 6 years ago
parent
commit
fb57537a83
3 changed files with 187 additions and 162 deletions
  1. 1 2
      Source/cmCommands.cxx
  2. 184 112
      Source/cmGetPropertyCommand.cxx
  3. 2 48
      Source/cmGetPropertyCommand.h

+ 1 - 2
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",

+ 184 - 112
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;
 }
+}

+ 2 - 48
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