Don't access the global env, use my local copy instead.
This commit is contained in:
parent
884a816cbb
commit
a1a7b8c5af
13 changed files with 101 additions and 186 deletions
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
|
||||
#include "chost.hpp"
|
||||
#include "env.hpp"
|
||||
#include "syspaths.hpp"
|
||||
#include "run_cmd.hpp"
|
||||
#include "gentoofunctions.hpp"
|
||||
#include "replace_bash_vars.hpp"
|
||||
|
@ -65,13 +65,13 @@ namespace duck {
|
|||
}
|
||||
} //unnamed namespace
|
||||
|
||||
std::string chost() {
|
||||
std::string chost(const SysPaths& sp) {
|
||||
using std::string;
|
||||
|
||||
{
|
||||
// If it's set in the env, trust the setting. If it's wrong,
|
||||
// then that's the caller's problem.
|
||||
auto ret = env("CHOST");
|
||||
auto ret = sp.env("CHOST");
|
||||
if (ret and not ret->empty())
|
||||
return string(*ret);
|
||||
}
|
||||
|
@ -83,16 +83,16 @@ namespace duck {
|
|||
chost_str = run_cmd("portageq", "envvar", "CHOST").out;
|
||||
}
|
||||
else {
|
||||
ewarn("Python seems to be broken, attempting to locate CHOST ourselves ...");
|
||||
ewarn(sp, "Python seems to be broken, attempting to locate CHOST ourselves ...");
|
||||
chost_str = try_real_hard_to_find_CHOST();
|
||||
}
|
||||
|
||||
if (chost_str.empty()) {
|
||||
eerror(replace_bash_vars("${argv0}: Could not get portage CHOST!"));
|
||||
eerror(replace_bash_vars("${argv0}: You should verify that CHOST is set in one of these places:"));
|
||||
eerror(replace_bash_vars("${argv0}: - ${EROOT}/etc/portage/make.conf"));
|
||||
eerror(replace_bash_vars("${argv0}: - active environment"));
|
||||
throw std::runtime_error(replace_bash_vars("${argv0}: Could not get portage CHOST!"));
|
||||
eerror(sp, replace_bash_vars(sp, "${argv0}: Could not get portage CHOST!"));
|
||||
eerror(sp, replace_bash_vars(sp, "${argv0}: You should verify that CHOST is set in one of these places:"));
|
||||
eerror(sp, replace_bash_vars(sp, "${argv0}: - ${EROOT}/etc/portage/make.conf"));
|
||||
eerror(sp, replace_bash_vars(sp, "${argv0}: - active environment"));
|
||||
throw std::runtime_error(replace_bash_vars(sp, "${argv0}: Could not get portage CHOST!"));
|
||||
}
|
||||
|
||||
return chost_str;
|
||||
|
|
|
@ -20,5 +20,7 @@
|
|||
#include <string>
|
||||
|
||||
namespace duck {
|
||||
std::string chost();
|
||||
class SysPaths;
|
||||
|
||||
std::string chost(const SysPaths&);
|
||||
} //namespace duck
|
||||
|
|
93
src/env.cpp
93
src/env.cpp
|
@ -1,93 +0,0 @@
|
|||
/* Copyright 2020, Michele Santullo
|
||||
* This file is part of user-gcc.
|
||||
*
|
||||
* User-gcc is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* User-gcc is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with user-gcc. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "env.hpp"
|
||||
#include <unistd.h>
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
|
||||
#if defined(__GNU_LIBRARY__) && ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 17) || __GLIBC__ > 2)
|
||||
# define HasSecureGetenv
|
||||
#endif
|
||||
|
||||
namespace duck {
|
||||
namespace {
|
||||
const char* raw_fetch_env (const char* name) {
|
||||
assert(name);
|
||||
if (not name)
|
||||
return nullptr;
|
||||
|
||||
#if defined(HasSecureGetenv)
|
||||
const char* const val_ptr = secure_getenv(name);
|
||||
#else
|
||||
const char* const val_ptr = getenv(name);
|
||||
#endif
|
||||
|
||||
return val_ptr;
|
||||
}
|
||||
|
||||
} //unnamed namespace
|
||||
|
||||
std::string_view env (const char* name, std::string_view def) noexcept {
|
||||
const auto ret = raw_fetch_env(name);
|
||||
return (ret ? std::string_view(ret) : def);
|
||||
}
|
||||
|
||||
std::optional<std::string_view> env (const char* name) noexcept {
|
||||
using optional = std::optional<std::string_view>;
|
||||
const auto ret = raw_fetch_env(name);
|
||||
return (ret ? optional{ret} : optional{});
|
||||
}
|
||||
|
||||
std::string_view env_throw (const char* name) {
|
||||
const auto ret = raw_fetch_env(name);
|
||||
if (ret) {
|
||||
return {ret};
|
||||
}
|
||||
else {
|
||||
if (name) {
|
||||
throw std::runtime_error(
|
||||
std::string("Environment variable \"") + name + "\" not set"
|
||||
);
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("Environment variable name is null");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool is_env_set (const char* name) noexcept {
|
||||
const auto ret = raw_fetch_env(name);
|
||||
return not not ret;
|
||||
}
|
||||
|
||||
std::string_view env (const std::string& name, std::string_view def) noexcept {
|
||||
return env(name.c_str(), def);
|
||||
}
|
||||
|
||||
std::optional<std::string_view> env (const std::string& name) noexcept {
|
||||
return env(name.c_str());
|
||||
}
|
||||
|
||||
std::string_view env_throw (const std::string& name) {
|
||||
return env_throw(name.c_str());
|
||||
}
|
||||
|
||||
bool is_env_set (const std::string& name) noexcept {
|
||||
return is_env_set(name.c_str());
|
||||
}
|
||||
} //namespace duck
|
36
src/env.hpp
36
src/env.hpp
|
@ -1,36 +0,0 @@
|
|||
/* Copyright 2020, Michele Santullo
|
||||
* This file is part of user-gcc.
|
||||
*
|
||||
* User-gcc is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* User-gcc is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with user-gcc. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
#include <string>
|
||||
|
||||
namespace duck {
|
||||
|
||||
std::string_view env (const char* name, std::string_view def) noexcept;
|
||||
std::optional<std::string_view> env (const char* name) noexcept;
|
||||
std::string_view env_throw (const char* name);
|
||||
bool is_env_set (const char* name) noexcept;
|
||||
|
||||
std::string_view env (const std::string& name, std::string_view def) noexcept;
|
||||
std::optional<std::string_view> env (const std::string& name) noexcept;
|
||||
std::string_view env_throw (const std::string& name);
|
||||
bool is_env_set (const std::string& name) noexcept;
|
||||
|
||||
} //namespace duck
|
|
@ -16,10 +16,10 @@
|
|||
*/
|
||||
|
||||
#include "gentoofunctions.hpp"
|
||||
#include "env.hpp"
|
||||
#include "string_view_cat.hpp"
|
||||
#include "config.h"
|
||||
#include "run_cmd.hpp"
|
||||
#include "syspaths.hpp"
|
||||
#include <iostream>
|
||||
#if __cplusplus == 201703L
|
||||
# include <experimental/array>
|
||||
|
@ -72,39 +72,41 @@ namespace duck {
|
|||
}
|
||||
|
||||
void generic_eprint (
|
||||
const SysPaths& sp,
|
||||
std::ostream& stream,
|
||||
const char* quiet_var,
|
||||
const char* msg_prefix_var,
|
||||
std::string_view quiet_var,
|
||||
std::string_view msg_prefix_var,
|
||||
std::string_view log_pri,
|
||||
std::string_view log_tag,
|
||||
std::string_view new_e_cmd,
|
||||
std::string_view msg,
|
||||
const char* newline
|
||||
) {
|
||||
if (yesno(env(quiet_var, ""))) {
|
||||
if (yesno(sp, sp[quiet_var])) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if (not yesno(env("RC_ENDCOL", "")) and g_last_e_cmd == "ebegin") {
|
||||
if (not yesno(sp, sp["RC_ENDCOL"]) and g_last_e_cmd == "ebegin") {
|
||||
stream << '\n';
|
||||
}
|
||||
stream << ' ' << env(msg_prefix_var, "") << '*'
|
||||
<< env("NORMAL", "") << ' ' << env("RC_INDENTATION", "")
|
||||
stream << ' ' << sp[msg_prefix_var] << '*'
|
||||
<< sp["NORMAL"] << ' ' << sp["RC_INDENTATION"]
|
||||
<< msg << newline;
|
||||
}
|
||||
|
||||
esyslog(log_pri, log_tag, msg);
|
||||
esyslog(sp, log_pri, log_tag, msg);
|
||||
g_last_e_cmd = new_e_cmd;
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
void vewarn (std::string_view msg) {
|
||||
if (yesno(env("EINFO_VERBOSE", ""), true))
|
||||
ewarn(msg);
|
||||
void vewarn (const SysPaths& sp, std::string_view msg) {
|
||||
if (yesno(sp, sp["EINFO_VERBOSE"], true))
|
||||
ewarn(sp, msg);
|
||||
}
|
||||
|
||||
void ewarn (std::string_view msg) {
|
||||
void ewarn (const SysPaths& sp, std::string_view msg) {
|
||||
generic_eprint(
|
||||
sp,
|
||||
std::clog,
|
||||
"EINFO_QUIET",
|
||||
"WARN",
|
||||
|
@ -116,8 +118,8 @@ namespace duck {
|
|||
);
|
||||
}
|
||||
|
||||
void esyslog(std::string_view pri, std::string_view tag, std::string_view msg) {
|
||||
if (not env("EINFO_LOG", "").empty() and not run_cmd_retcode("command -v logger > /dev/null 2>&1")) {
|
||||
void esyslog(const SysPaths& sp, std::string_view pri, std::string_view tag, std::string_view msg) {
|
||||
if (not sp["EINFO_LOG"].empty() and not run_cmd_retcode("command -v logger > /dev/null 2>&1")) {
|
||||
if (msg.empty())
|
||||
return;
|
||||
|
||||
|
@ -125,7 +127,7 @@ namespace duck {
|
|||
}
|
||||
}
|
||||
|
||||
bool yesno (const std::string& var, bool force_quiet) {
|
||||
bool yesno (const SysPaths& sp, std::string_view var, bool force_quiet) {
|
||||
{
|
||||
const auto ret = yesno_impl(var);
|
||||
switch (ret) {
|
||||
|
@ -136,7 +138,7 @@ namespace duck {
|
|||
}
|
||||
|
||||
{
|
||||
auto val = env(var, "");
|
||||
auto val = sp[var];
|
||||
if (val.empty())
|
||||
return false;
|
||||
|
||||
|
@ -145,18 +147,15 @@ namespace duck {
|
|||
case Yes: return true;
|
||||
case No: return false;
|
||||
default:
|
||||
vewarn(std::string("\"") + var + "\" (\"" + val + "\") is not set properly");
|
||||
vewarn(sp, std::string("\"") + var + "\" (\"" + val + "\") is not set properly");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool yesno (std::string_view var, bool force_quiet) {
|
||||
return yesno(to_string(var), force_quiet);
|
||||
}
|
||||
|
||||
void eerror (std::string_view msg) {
|
||||
void eerror (const SysPaths& sp, std::string_view msg) {
|
||||
generic_eprint(
|
||||
sp,
|
||||
std::clog,
|
||||
"EERROR_QUIET",
|
||||
"BAD",
|
||||
|
|
|
@ -21,10 +21,11 @@
|
|||
#include <string>
|
||||
|
||||
namespace duck {
|
||||
void vewarn (std::string_view msg);
|
||||
void ewarn (std::string_view msg);
|
||||
bool yesno (const std::string& var, bool force_quiet=false);
|
||||
bool yesno (std::string_view var, bool force_quiet=false);
|
||||
void esyslog(std::string_view pri, std::string_view tag, std::string_view msg);
|
||||
void eerror (std::string_view msg);
|
||||
class SysPaths;
|
||||
|
||||
void vewarn (const SysPaths& sp, std::string_view msg);
|
||||
void ewarn (const SysPaths& sp, std::string_view msg);
|
||||
bool yesno (const SysPaths& sp, std::string_view var, bool force_quiet=false);
|
||||
void esyslog(const SysPaths& sp, std::string_view pri, std::string_view tag, std::string_view msg);
|
||||
void eerror (const SysPaths& sp, std::string_view msg);
|
||||
} //namespace duck
|
||||
|
|
|
@ -128,7 +128,7 @@ namespace duck {
|
|||
std::cout << "Using " << PROJECT_NAME << " info in " << sp.root() << '\n';
|
||||
}
|
||||
|
||||
std::string chost = duck::chost();
|
||||
std::string chost = duck::chost(sp);
|
||||
const std::string& ctarget = chost;
|
||||
|
||||
std::string_view filter;
|
||||
|
@ -154,7 +154,7 @@ namespace duck {
|
|||
if (starts_with(filename, chost + "-"))
|
||||
curr_ctarget = chost;
|
||||
else
|
||||
ewarn("broken config file: " + std::string(ver_path));
|
||||
ewarn(sp, "broken config file: " + std::string(ver_path));
|
||||
}
|
||||
|
||||
++z;
|
||||
|
|
|
@ -9,7 +9,6 @@ project_config_file = configure_file(
|
|||
|
||||
executable(meson.project_name(),
|
||||
'main.cpp',
|
||||
'env.cpp',
|
||||
project_config_file,
|
||||
'list_profiles.cpp',
|
||||
'syspaths.cpp',
|
||||
|
|
|
@ -17,15 +17,14 @@
|
|||
|
||||
#include "replace_bash_vars.hpp"
|
||||
#include "config.h"
|
||||
#include "env.hpp"
|
||||
#include "string_view_cat.hpp"
|
||||
#include "syspaths.hpp"
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
|
||||
namespace duck {
|
||||
namespace {
|
||||
struct VarInfo {
|
||||
std::string name;
|
||||
std::string_view name;
|
||||
std::size_t orig_len{};
|
||||
};
|
||||
|
||||
|
@ -38,7 +37,7 @@ namespace duck {
|
|||
// return text;
|
||||
//}
|
||||
|
||||
VarInfo extract_var_name (std::string_view text) {
|
||||
VarInfo extract_var_name (const SysPaths& sp, std::string_view text) {
|
||||
assert(not text.empty());
|
||||
assert(text.front() == '$');
|
||||
if (text.size() == 1) {
|
||||
|
@ -46,7 +45,7 @@ namespace duck {
|
|||
}
|
||||
else if (text.size() == 2) {
|
||||
if (std::isalnum(text[1]))
|
||||
return {to_string(text.substr(1, 1)), 2};
|
||||
return {text.substr(1, 1), 2};
|
||||
return {};
|
||||
}
|
||||
else {
|
||||
|
@ -58,9 +57,9 @@ namespace duck {
|
|||
}
|
||||
else {
|
||||
std::string_view token(text.substr(2, end - 2));
|
||||
std::string retval(token.empty() || token.front() != '!' ? to_string(token) : to_string(token.substr(1)));
|
||||
std::string_view retval(token.empty() || token.front() != '!' ? token : token.substr(1));
|
||||
if (not token.empty() and token.front() == '!') {
|
||||
return {to_string(env(retval, "")), end + 1};
|
||||
return {sp[retval], end + 1};
|
||||
}
|
||||
else {
|
||||
return {retval, end + 1};
|
||||
|
@ -71,13 +70,13 @@ namespace duck {
|
|||
std::size_t z;
|
||||
for (z = 1; z < text.size() && std::isalnum(text[z]); ++z) {
|
||||
}
|
||||
return {to_string(text.substr(1, z - 1)), z + 1};
|
||||
return {text.substr(1, z - 1), z + 1};
|
||||
}
|
||||
}
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
std::string replace_bash_vars (std::string_view text) {
|
||||
std::string replace_bash_vars (const SysPaths& sp, std::string_view text) {
|
||||
std::size_t pos = 0;
|
||||
std::size_t prev_start = 0;
|
||||
std::string rtext;
|
||||
|
@ -85,7 +84,7 @@ namespace duck {
|
|||
|
||||
while ((pos = text.find('$', pos)) != std::string::npos) {
|
||||
if (0 == pos or rtext[pos-1] != '\\') {
|
||||
auto var = extract_var_name(text.substr(pos));
|
||||
auto var = extract_var_name(sp, text.substr(pos));
|
||||
if (not var.orig_len) {
|
||||
++pos;
|
||||
continue;
|
||||
|
@ -96,7 +95,7 @@ namespace duck {
|
|||
if (var.name == "argv0")
|
||||
rtext += PROJECT_NAME;
|
||||
else
|
||||
rtext += env(var.name, "");
|
||||
rtext += sp[var.name];
|
||||
pos += var.orig_len;
|
||||
prev_start = pos;
|
||||
}
|
||||
|
|
|
@ -21,5 +21,7 @@
|
|||
#include <string>
|
||||
|
||||
namespace duck {
|
||||
std::string replace_bash_vars (std::string_view text);
|
||||
class SysPaths;
|
||||
|
||||
std::string replace_bash_vars (const SysPaths& sp, std::string_view text);
|
||||
} //namespace duck
|
||||
|
|
|
@ -33,6 +33,10 @@ namespace duck {
|
|||
return str;
|
||||
}
|
||||
|
||||
inline std::string_view to_string_view (const char* str) {
|
||||
return (str ? std::string_view{str} : std::string_view{""});
|
||||
}
|
||||
|
||||
inline std::string operator+ (std::string_view a, std::string_view b) {
|
||||
std::string ret(to_string(a));
|
||||
ret += b;
|
||||
|
|
|
@ -16,9 +16,10 @@
|
|||
*/
|
||||
|
||||
#include "syspaths.hpp"
|
||||
#include "env.hpp"
|
||||
#include "to_var_map.hpp"
|
||||
#include "string_view_cat.hpp"
|
||||
#include <unistd.h>
|
||||
#include <cassert>
|
||||
|
||||
namespace duck {
|
||||
namespace {
|
||||
|
@ -33,17 +34,50 @@ namespace duck {
|
|||
const std::size_t pos = text.find_first_not_of('/');
|
||||
return (text.npos == pos ? text : text.substr(pos));
|
||||
}
|
||||
|
||||
std::string_view val_or_def (const VarMap& map, std::string_view key, std::string_view def) noexcept {
|
||||
try {
|
||||
auto itm = map.find(key);
|
||||
return (map.end() == itm ? def : itm->second);
|
||||
}
|
||||
catch (...) {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
SysPaths::SysPaths() :
|
||||
m_env(to_var_map_ignore_ownership(environ)),
|
||||
m_root(duck::env("ROOT", "/")),
|
||||
m_eprefix(fix_eprefix(duck::env("EPREFIX", ""))),
|
||||
m_root(val_or_def(m_env, "ROOT", "/")),
|
||||
m_eprefix(fix_eprefix(val_or_def(m_env, "EPREFIX", ""))),
|
||||
m_eroot(m_root / remove_front_slash(std::string(m_eprefix))),
|
||||
m_env_d(m_eroot / "etc/env.d"),
|
||||
m_gcc_env_d(m_env_d / "gcc")
|
||||
{
|
||||
}
|
||||
|
||||
std::string_view SysPaths::operator[] (std::string_view name) const noexcept {
|
||||
assert(not name.empty());
|
||||
return val_or_def(m_env, name, "");
|
||||
}
|
||||
|
||||
std::optional<std::string_view> SysPaths::env (std::string_view name) const noexcept {
|
||||
try {
|
||||
assert(not name.empty());
|
||||
auto it_found = m_env.find(name);
|
||||
if (m_env.end() == it_found)
|
||||
return {};
|
||||
else
|
||||
return std::make_optional(it_found->second);
|
||||
}
|
||||
catch (...) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
std::string_view SysPaths::env (std::string_view name, std::string_view def) const noexcept {
|
||||
assert(not name.empty());
|
||||
return val_or_def(m_env, name, def);
|
||||
}
|
||||
|
||||
void SysPaths::set_colours (std::string_view colours) {
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#endif
|
||||
#include <unordered_map>
|
||||
#include <string_view>
|
||||
#include <optional>
|
||||
|
||||
namespace duck {
|
||||
class SysPaths {
|
||||
|
@ -34,9 +35,12 @@ namespace duck {
|
|||
SysPaths();
|
||||
~SysPaths() noexcept = default;
|
||||
|
||||
std::string_view operator[] (std::string_view name) const noexcept;
|
||||
std::optional<std::string_view> env (std::string_view name) const noexcept;
|
||||
std::string_view env (std::string_view name, std::string_view def) const noexcept;
|
||||
|
||||
void set_colours (std::string_view colours);
|
||||
VarMapView colours() const { return {&m_colours}; }
|
||||
VarMapView env() const { return {&m_env}; }
|
||||
|
||||
const path_type& root() const;
|
||||
const path_type& eroot() const;
|
||||
|
|
Loading…
Reference in a new issue