commit 1c45abe5e1bffc45f24f947552fc8725440d3447
parent ad0c3a48ce95c8bedfb12a7911a25b77e6247f36
Author: deurzen <max@deurzen.net>
Date: Wed, 1 Jun 2022 14:55:34 +0200
implements nested env var evaluation
Diffstat:
2 files changed, 72 insertions(+), 0 deletions(-)
diff --git a/include/kranewl/env.hh b/include/kranewl/env.hh
@@ -0,0 +1,5 @@
+#pragma once
+
+#include <string>
+
+void parse_and_set_env_vars(std::string const&);
diff --git a/src/kranewl/env.cc b/src/kranewl/env.cc
@@ -0,0 +1,67 @@
+#include <kranewl/env.hh>
+
+#include <cctype>
+#include <cstdint>
+#include <cstdlib>
+#include <fstream>
+#include <locale>
+#include <regex>
+
+#include <spdlog/spdlog.h>
+
+static inline std::string
+evaluate_value(std::string const& value)
+{
+ static const std::regex regex(R"(\$([a-zA-Z0-9_]+))");
+
+ std::string evaluation = {};
+ std::smatch match;
+
+ auto it = value.cbegin();
+ auto end = value.cend();
+
+ while (std::regex_search(it, end, match, regex)) {
+ char const* env = getenv(match.str(1).c_str());
+ evaluation += match.prefix();
+ evaluation += env ? env : "";
+ it = match.suffix().first;
+ }
+
+ evaluation.append(it, value.cend());
+ return evaluation;
+}
+
+void
+parse_and_set_env_vars(std::string const& env_path)
+{
+ struct Assignment_ctype : std::ctype<char> {
+ Assignment_ctype()
+ : std::ctype<char>(get_table())
+ {}
+
+ static mask const* get_table()
+ {
+ static mask rc[table_size];
+ rc[static_cast<std::size_t>('=')] = std::ctype_base::space;
+ rc[static_cast<std::size_t>('\n')] = std::ctype_base::space;
+ rc[static_cast<std::size_t>('\r')] = std::ctype_base::space;
+ return &rc[0];
+ }
+ };
+
+ std::ifstream env_if(env_path);
+ env_if.imbue(std::locale(env_if.getloc(), new Assignment_ctype));
+
+ const auto isspace = [](char c) {
+ return std::isspace(static_cast<unsigned char>(c));
+ };
+
+ std::string var, value;
+ while (env_if >> var >> value) {
+ var.erase(std::remove_if(var.begin(), var.end(), isspace), var.end());
+ value.erase(std::remove_if(value.begin(), value.end(), isspace), value.end());
+
+ spdlog::info("Setting environment variable: {}={}", var, value);
+ setenv(var.c_str(), evaluate_value(value).c_str(), true);
+ }
+}