mirror of
https://github.com/Kitware/CMake.git
synced 2026-08-03 22:30:29 +00:00
cmEnvironment: Add class for environment modification
This commit is contained in:
@@ -2,12 +2,16 @@
|
|||||||
file LICENSE.rst or https://cmake.org/licensing for details. */
|
file LICENSE.rst or https://cmake.org/licensing for details. */
|
||||||
#include "cmEnvironment.h"
|
#include "cmEnvironment.h"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <cm/string_view>
|
#include <cm/string_view>
|
||||||
#include <cm/vector>
|
#include <cm/vector>
|
||||||
#include <cmext/algorithm>
|
#include <cmext/algorithm>
|
||||||
|
|
||||||
|
#include "cmStringAlgorithms.h"
|
||||||
|
#include "cmSystemTools.h"
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
# include "cmsys/String.h"
|
# include "cmsys/String.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -64,3 +68,138 @@ std::vector<std::string> cmEnvironment::GetVariables() const
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
auto const ValidOperators = std::set<cm::string_view>{
|
||||||
|
"set",
|
||||||
|
"unset",
|
||||||
|
"string_append",
|
||||||
|
"string_prepend",
|
||||||
|
"path_list_append",
|
||||||
|
"path_list_prepend",
|
||||||
|
"cmake_list_append",
|
||||||
|
"cmake_list_prepend",
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ListAppend
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ListAppend(std::string val, char sep)
|
||||||
|
: value(std::move(val))
|
||||||
|
, separator(sep)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(std::string& output) const
|
||||||
|
{
|
||||||
|
if (!output.empty()) {
|
||||||
|
output += separator;
|
||||||
|
}
|
||||||
|
output += value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string value;
|
||||||
|
char separator;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ListPrepend
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ListPrepend(std::string val, char sep)
|
||||||
|
: value(std::move(val))
|
||||||
|
, separator(sep)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(std::string& output) const
|
||||||
|
{
|
||||||
|
if (!output.empty()) {
|
||||||
|
output.insert(output.begin(), separator);
|
||||||
|
}
|
||||||
|
output.insert(0, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string value;
|
||||||
|
char separator;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
bool cmEnvironmentModification::Add(std::vector<std::string> const& envmod)
|
||||||
|
{
|
||||||
|
bool ok = true;
|
||||||
|
for (auto const& entry : envmod) {
|
||||||
|
ok &= this->Add(entry);
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cmEnvironmentModification::Add(std::string const& envmod)
|
||||||
|
{
|
||||||
|
// Split on `=`
|
||||||
|
auto const eq_loc = envmod.find_first_of('=');
|
||||||
|
if (eq_loc == std::string::npos) {
|
||||||
|
cmSystemTools::Error(cmStrCat(
|
||||||
|
"Error: Missing `=` after the variable name in: ", envmod, '\n'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split operation on `:`
|
||||||
|
auto const op_value_start = eq_loc + 1;
|
||||||
|
auto const colon_loc = envmod.find_first_of(':', op_value_start);
|
||||||
|
if (colon_loc == std::string::npos) {
|
||||||
|
cmSystemTools::Error(
|
||||||
|
cmStrCat("Error: Missing `:` after the operation in: ", envmod, '\n'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto entry = Entry{};
|
||||||
|
entry.Name = envmod.substr(0, eq_loc);
|
||||||
|
entry.Op = envmod.substr(op_value_start, colon_loc - op_value_start);
|
||||||
|
entry.Value = envmod.substr(colon_loc + 1);
|
||||||
|
|
||||||
|
if (entry.Op == "reset") {
|
||||||
|
cm::erase_if(this->Entries,
|
||||||
|
[&entry](Entry const& e) { return e.Name == entry.Name; });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cm::contains(ValidOperators, entry.Op)) {
|
||||||
|
cmSystemTools::Error(cmStrCat(
|
||||||
|
"Error: Unrecognized environment manipulation argument: ", entry.Op,
|
||||||
|
'\n'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->Entries.push_back(std::move(entry));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmEnvironmentModification::ApplyTo(cmEnvironment& env)
|
||||||
|
{
|
||||||
|
char const path_sep = cmSystemTools::GetSystemPathlistSeparator();
|
||||||
|
|
||||||
|
for (auto const& e : this->Entries) {
|
||||||
|
if (e.Op == "set") {
|
||||||
|
env.PutEnv(e.Name + "=" + e.Value);
|
||||||
|
} else if (e.Op == "unset") {
|
||||||
|
env.UnPutEnv(e.Name);
|
||||||
|
} else if (e.Op == "string_append") {
|
||||||
|
env.Modify(e.Name, [&e](std::string& output) { output += e.Value; });
|
||||||
|
} else if (e.Op == "string_prepend") {
|
||||||
|
env.Modify(e.Name,
|
||||||
|
[&e](std::string& output) { output.insert(0, e.Value); });
|
||||||
|
} else if (e.Op == "path_list_append") {
|
||||||
|
env.Modify(e.Name, ListAppend(e.Value, path_sep));
|
||||||
|
} else if (e.Op == "path_list_prepend") {
|
||||||
|
env.Modify(e.Name, ListPrepend(e.Value, path_sep));
|
||||||
|
} else if (e.Op == "cmake_list_append") {
|
||||||
|
env.Modify(e.Name, ListAppend(e.Value, ';'));
|
||||||
|
} else if (e.Op == "cmake_list_prepend") {
|
||||||
|
env.Modify(e.Name, ListPrepend(e.Value, ';'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -53,3 +53,22 @@ protected:
|
|||||||
};
|
};
|
||||||
std::map<std::string, cm::optional<std::string>, EnvNameLess> Map;
|
std::map<std::string, cm::optional<std::string>, EnvNameLess> Map;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class cmEnvironmentModification
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool Add(std::string const& envmod);
|
||||||
|
bool Add(std::vector<std::string> const& envmod);
|
||||||
|
|
||||||
|
void ApplyTo(cmEnvironment& env);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Entry
|
||||||
|
{
|
||||||
|
std::string Name;
|
||||||
|
std::string Value;
|
||||||
|
std::string Op;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<Entry> Entries;
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user