From a1a7b8c5afef5a9ac37a1a6655e2349997ee5b36 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Sun, 12 Apr 2020 16:39:36 +0200 Subject: [PATCH] Don't access the global env, use my local copy instead. --- src/chost.cpp | 18 ++++---- src/chost.hpp | 4 +- src/env.cpp | 93 --------------------------------------- src/env.hpp | 36 --------------- src/gentoofunctions.cpp | 43 +++++++++--------- src/gentoofunctions.hpp | 13 +++--- src/list_profiles.cpp | 4 +- src/meson.build | 1 - src/replace_bash_vars.cpp | 21 +++++---- src/replace_bash_vars.hpp | 4 +- src/string_view_cat.hpp | 4 ++ src/syspaths.cpp | 40 +++++++++++++++-- src/syspaths.hpp | 6 ++- 13 files changed, 101 insertions(+), 186 deletions(-) delete mode 100644 src/env.cpp delete mode 100644 src/env.hpp diff --git a/src/chost.cpp b/src/chost.cpp index 700b1b6..fa1e43a 100644 --- a/src/chost.cpp +++ b/src/chost.cpp @@ -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; diff --git a/src/chost.hpp b/src/chost.hpp index 7d23b1e..1f44861 100644 --- a/src/chost.hpp +++ b/src/chost.hpp @@ -20,5 +20,7 @@ #include namespace duck { - std::string chost(); + class SysPaths; + + std::string chost(const SysPaths&); } //namespace duck diff --git a/src/env.cpp b/src/env.cpp deleted file mode 100644 index 768b212..0000000 --- a/src/env.cpp +++ /dev/null @@ -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 . - */ - -#include "env.hpp" -#include -#include -#include - -#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 env (const char* name) noexcept { - using optional = std::optional; - 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 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 diff --git a/src/env.hpp b/src/env.hpp deleted file mode 100644 index d34a0c1..0000000 --- a/src/env.hpp +++ /dev/null @@ -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 . - */ - -#pragma once - -#include -#include -#include - -namespace duck { - -std::string_view env (const char* name, std::string_view def) noexcept; -std::optional 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 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 diff --git a/src/gentoofunctions.cpp b/src/gentoofunctions.cpp index 26c5546..95929e6 100644 --- a/src/gentoofunctions.cpp +++ b/src/gentoofunctions.cpp @@ -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 #if __cplusplus == 201703L # include @@ -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", diff --git a/src/gentoofunctions.hpp b/src/gentoofunctions.hpp index 82c71d0..31d5386 100644 --- a/src/gentoofunctions.hpp +++ b/src/gentoofunctions.hpp @@ -21,10 +21,11 @@ #include 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 diff --git a/src/list_profiles.cpp b/src/list_profiles.cpp index 49d1ae8..eec26a1 100644 --- a/src/list_profiles.cpp +++ b/src/list_profiles.cpp @@ -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; diff --git a/src/meson.build b/src/meson.build index 84656b6..9a01898 100644 --- a/src/meson.build +++ b/src/meson.build @@ -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', diff --git a/src/replace_bash_vars.cpp b/src/replace_bash_vars.cpp index 0490c6a..fb8b463 100644 --- a/src/replace_bash_vars.cpp +++ b/src/replace_bash_vars.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 #include 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; } diff --git a/src/replace_bash_vars.hpp b/src/replace_bash_vars.hpp index 81f719e..bde5efc 100644 --- a/src/replace_bash_vars.hpp +++ b/src/replace_bash_vars.hpp @@ -21,5 +21,7 @@ #include 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 diff --git a/src/string_view_cat.hpp b/src/string_view_cat.hpp index 656fe22..e49a99c 100644 --- a/src/string_view_cat.hpp +++ b/src/string_view_cat.hpp @@ -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; diff --git a/src/syspaths.cpp b/src/syspaths.cpp index f8331bc..ef8f848 100644 --- a/src/syspaths.cpp +++ b/src/syspaths.cpp @@ -16,9 +16,10 @@ */ #include "syspaths.hpp" -#include "env.hpp" #include "to_var_map.hpp" +#include "string_view_cat.hpp" #include +#include 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 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) { diff --git a/src/syspaths.hpp b/src/syspaths.hpp index 72be10c..41a992f 100644 --- a/src/syspaths.hpp +++ b/src/syspaths.hpp @@ -25,6 +25,7 @@ #endif #include #include +#include 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 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;