Don't access the global env, use my local copy instead.

This commit is contained in:
King_DuckZ 2020-04-12 16:39:36 +02:00
parent 884a816cbb
commit a1a7b8c5af
13 changed files with 101 additions and 186 deletions

View file

@ -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;

View file

@ -20,5 +20,7 @@
#include <string>
namespace duck {
std::string chost();
class SysPaths;
std::string chost(const SysPaths&);
} //namespace duck

View file

@ -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

View file

@ -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

View file

@ -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",

View file

@ -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

View file

@ -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;

View file

@ -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',

View file

@ -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;
}

View file

@ -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

View file

@ -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;

View file

@ -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) {

View file

@ -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;