| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying | |
| file LICENSE.rst or https://cmake.org/licensing for details. */ | |
| #include "cmOptionCommand.h" | |
| #include <cmext/string_view> | |
| #include "cmExecutionStatus.h" | |
| #include "cmMakefile.h" | |
| #include "cmPolicies.h" | |
| #include "cmState.h" | |
| #include "cmStateSnapshot.h" | |
| #include "cmStateTypes.h" | |
| #include "cmStringAlgorithms.h" | |
| #include "cmValue.h" | |
| // cmOptionCommand | |
| bool cmOptionCommand(std::vector<std::string> const& args, | |
| cmExecutionStatus& status) | |
| { | |
| bool const argError = (args.size() < 2) || (args.size() > 3); | |
| if (argError) { | |
| std::string m = cmStrCat("called with incorrect number of arguments: ", | |
| cmJoin(args, " ")); | |
| status.SetError(m); | |
| return false; | |
| } | |
| // Determine the state of the option policy | |
| bool checkAndWarn = false; | |
| { | |
| auto policyStatus = | |
| status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0077); | |
| auto const& existsBeforeSet = | |
| status.GetMakefile().GetStateSnapshot().GetDefinition(args[0]); | |
| switch (policyStatus) { | |
| case cmPolicies::WARN: | |
| checkAndWarn = (existsBeforeSet != nullptr); | |
| CM_FALLTHROUGH; | |
| case cmPolicies::OLD: | |
| // OLD behavior does not warn. | |
| break; | |
| case cmPolicies::NEW: { | |
| // See if a local variable with this name already exists. | |
| // If so we ignore the option command. | |
| if (existsBeforeSet) { | |
| return true; | |
| } | |
| } break; | |
| } | |
| } | |
| // See if a cache variable with this name already exists | |
| // If so just make sure the doc state is correct | |
| cmState* state = status.GetMakefile().GetState(); | |
| cmValue existingValue = state->GetCacheEntryValue(args[0]); | |
| if (existingValue && | |
| (state->GetCacheEntryType(args[0]) != cmStateEnums::UNINITIALIZED)) { | |
| state->SetCacheEntryProperty(args[0], "HELPSTRING", args[1]); | |
| return true; | |
| } | |
| // Nothing in the cache so add it | |
| std::string initialValue = existingValue ? *existingValue : "Off"; | |
| if (args.size() == 3) { | |
| initialValue = args[2]; | |
| } | |
| bool init = cmIsOn(initialValue); | |
| status.GetMakefile().AddCacheDefinition(args[0], init ? "ON" : "OFF", | |
| args[1], cmStateEnums::BOOL); | |
| if (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0077) != | |
| cmPolicies::NEW && | |
| status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0126) == | |
| cmPolicies::NEW) { | |
| // if there was a definition then remove it | |
| status.GetMakefile().GetStateSnapshot().RemoveDefinition(args[0]); | |
| } | |
| if (checkAndWarn) { | |
| auto const& existsAfterSet = | |
| status.GetMakefile().GetStateSnapshot().GetDefinition(args[0]); | |
| if (!existsAfterSet) { | |
| status.GetMakefile().IssuePolicyWarning( | |
| cmPolicies::CMP0077, {}, | |
| cmStrCat("For compatibility with older versions of CMake, " | |
| "option is clearing the normal variable '"_s, | |
| args[0], "'."_s)); | |
| } | |
| } | |
| return true; | |
| } |