From 37fae65a700310a7b54db256cbcfeb62f7fc12a4 Mon Sep 17 00:00:00 2001 From: Marc Chevrier Date: Sun, 26 Apr 2026 15:25:08 +0200 Subject: [PATCH] Store command type To enable checks on command type (i.e. macro or function). --- Source/cmFunctionCommand.cxx | 3 +- Source/cmMacroCommand.cxx | 3 +- Source/cmState.cxx | 82 ++++++++++++++++++++++++++++++------ Source/cmState.h | 37 ++++++++++++++-- Source/cmStateTypes.h | 6 +++ 5 files changed, 113 insertions(+), 18 deletions(-) diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx index 60c3b90077..456cb72984 100644 --- a/Source/cmFunctionCommand.cxx +++ b/Source/cmFunctionCommand.cxx @@ -19,6 +19,7 @@ #include "cmPolicies.h" #include "cmRange.h" #include "cmState.h" +#include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -175,7 +176,7 @@ bool cmFunctionFunctionBlocker::Replay( mf.RecordPolicies(f.Policies); mf.RecordDiagnostics(f.Diagnostics); return mf.GetState()->AddScriptedCommand( - this->Args.front(), + this->Args.front(), cmStateEnums::CommandType::Function, BT(std::move(f), mf.GetBacktrace().Push(this->GetStartingContext())), mf); diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx index f193bce148..2c5d95ac02 100644 --- a/Source/cmMacroCommand.cxx +++ b/Source/cmMacroCommand.cxx @@ -19,6 +19,7 @@ #include "cmPolicies.h" #include "cmRange.h" #include "cmState.h" +#include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -179,7 +180,7 @@ bool cmMacroFunctionBlocker::Replay(std::vector functions, mf.RecordPolicies(f.Policies); mf.RecordDiagnostics(f.Diagnostics); return mf.GetState()->AddScriptedCommand( - this->Args[0], + this->Args[0], cmStateEnums::CommandType::Macro, BT(std::move(f), mf.GetBacktrace().Push(this->GetStartingContext())), mf); diff --git a/Source/cmState.cxx b/Source/cmState.cxx index e458b4cdc8..ecfc0a2a1a 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -414,7 +414,10 @@ void cmState::AddBuiltinCommand(std::string const& name, Command command) { assert(name == cmSystemTools::LowerCase(name)); assert(this->BuiltinCommands.find(name) == this->BuiltinCommands.end()); - this->BuiltinCommands.emplace(name, std::move(command)); + this->BuiltinCommands.emplace( + name, + CommandDescriptor{ cmStateEnums::CommandType::Function, + std::move(command) }); } static bool InvokeBuiltinCommand(cmState::BuiltinCommand command, @@ -522,8 +525,31 @@ void cmState::AddUnexpectedFlowControlCommand(std::string const& name, this->AddUnexpectedCommand(name, error); } -bool cmState::AddScriptedCommand(std::string const& name, BT command, - cmMakefile& mf) +cmState::CommandDescriptor::CommandDescriptor(CommandType type, + Command command) + : Type(type) + , Script(std::move(command)) +{ +} +cmState::CommandDescriptor::CommandDescriptor( + CommandDescriptor&& descriptor) noexcept + : Type(descriptor.Type) + , Script(std::move(descriptor.Script)) +{ +} + +cmState::CommandDescriptor& cmState::CommandDescriptor::operator=( + CommandDescriptor&& descriptor) noexcept +{ + this->Type = descriptor.Type; + this->Script = std::move(descriptor.Script); + + return *this; +} + +bool cmState::AddScriptedCommand(std::string const& name, + cmStateEnums::CommandType type, + BT command, cmMakefile& mf) { std::string sName = cmSystemTools::LowerCase(name); @@ -538,30 +564,60 @@ bool cmState::AddScriptedCommand(std::string const& name, BT command, } // if the command already exists, give a new name to the old command. - if (Command oldCmd = this->GetCommandByExactName(sName)) { - this->ScriptedCommands["_" + sName] = oldCmd; + if (CommandDescriptor const* oldCmd = + this->GetCommandDescriptorByExactName(sName)) { + this->ScriptedCommands["_" + sName] = *oldCmd; } - this->ScriptedCommands[sName] = std::move(command.Value); + this->ScriptedCommands[sName] = + CommandDescriptor{ type, std::move(command.Value) }; return true; } +cmState::CommandDescriptor const* cmState::GetCommandDescriptorByExactName( + std::string const& name) const +{ + auto pos = this->ScriptedCommands.find(name); + if (pos != this->ScriptedCommands.end()) { + return &pos->second; + } + pos = this->BuiltinCommands.find(name); + if (pos != this->BuiltinCommands.end()) { + return &pos->second; + } + return nullptr; +} + cmState::Command cmState::GetCommand(std::string const& name) const { return this->GetCommandByExactName(cmSystemTools::LowerCase(name)); } +cm::optional cmState::GetCommandType( + std::string const& name) const +{ + return this->GetCommandTypeByExactName(cmSystemTools::LowerCase(name)); +} cmState::Command cmState::GetCommandByExactName(std::string const& name) const { - auto pos = this->ScriptedCommands.find(name); - if (pos != this->ScriptedCommands.end()) { - return pos->second; + CommandDescriptor const* descriptor = + this->GetCommandDescriptorByExactName(name); + if (!descriptor) { + return nullptr; } - pos = this->BuiltinCommands.find(name); - if (pos != this->BuiltinCommands.end()) { - return pos->second; + + return descriptor->Script; +} +cm::optional cmState::GetCommandTypeByExactName( + std::string const& name) const +{ + CommandDescriptor const* descriptor = + this->GetCommandDescriptorByExactName(name); + if (!descriptor) { + return cm::nullopt; } - return nullptr; + + return descriptor->Type; } std::vector cmState::GetCommandNames() const diff --git a/Source/cmState.h b/Source/cmState.h index a25342f653..5d8a1e7c4a 100644 --- a/Source/cmState.h +++ b/Source/cmState.h @@ -172,8 +172,14 @@ public: // Returns a command from its name, case insensitive, or nullptr Command GetCommand(std::string const& name) const; + // Returns a command type from its name, case insensitive, or cm::nullopt + cm::optional GetCommandType( + std::string const& name) const; // Returns a command from its name, or nullptr Command GetCommandByExactName(std::string const& name) const; + // Returns a command type from its name, or cm::nullopt + cm::optional GetCommandTypeByExactName( + std::string const& name) const; void AddBuiltinCommand(std::string const& name, Command command); void AddBuiltinCommand(std::string const& name, BuiltinCommand command); @@ -186,7 +192,8 @@ public: void AddUnexpectedCommand(std::string const& name, char const* error); void AddUnexpectedFlowControlCommand(std::string const& name, char const* error); - bool AddScriptedCommand(std::string const& name, BT command, + bool AddScriptedCommand(std::string const& name, + cmStateEnums::CommandType type, BT command, cmMakefile& mf); void RemoveBuiltinCommand(std::string const& name); void RemoveUserDefinedCommands(); @@ -277,8 +284,32 @@ private: cmPropertyDefinitionMap PropertyDefinitions; std::vector EnabledLanguages; - std::unordered_map BuiltinCommands; - std::unordered_map ScriptedCommands; + + class CommandDescriptor + { + public: + using CommandType = cmStateEnums::CommandType; + + CommandDescriptor() + : Type(CommandType::Macro) + , Script(nullptr) + { + } + CommandDescriptor(CommandType type, Command command); + CommandDescriptor(CommandDescriptor&& descriptor) noexcept; + + CommandDescriptor& operator=(CommandDescriptor&& descriptor) noexcept; + CommandDescriptor& operator=(CommandDescriptor const& descriptor) = + default; + + CommandType Type; + Command Script; + }; + CommandDescriptor const* GetCommandDescriptorByExactName( + std::string const& name) const; + + std::unordered_map BuiltinCommands; + std::unordered_map ScriptedCommands; std::unordered_set FlowControlCommands; cmPropertyMap GlobalProperties; std::unique_ptr CacheManager; diff --git a/Source/cmStateTypes.h b/Source/cmStateTypes.h index 6e2d45665c..1b7043fe31 100644 --- a/Source/cmStateTypes.h +++ b/Source/cmStateTypes.h @@ -41,6 +41,12 @@ enum SnapshotUnwindState UNWINDING }; +enum class CommandType +{ + Macro, + Function +}; + // There are multiple overlapping ranges represented here. Be aware that adding // a value to this enumeration may cause failures in numerous places which // assume details about the ordering.