diff options
author | Kjell Ahlstedt <kjellahlstedt@gmail.com> | 2021-05-23 14:59:54 +0200 |
---|---|---|
committer | Kjell Ahlstedt <kjellahlstedt@gmail.com> | 2021-05-23 14:59:54 +0200 |
commit | b8343851afbe33b7ceb50893f9d7221cffce4dd1 (patch) | |
tree | cd6b2698ccc8ab789cb58d75763aaf55d680b54b | |
parent | 85c707d3e77c993ec221f08adffdd0918b60fbc7 (diff) | |
download | glibmm-b8343851afbe33b7ceb50893f9d7221cffce4dd1.tar.gz |
Add Glib::Environ and tests/glibmm_environ
Fixes #89
-rw-r--r-- | glib/glibmm.h | 1 | ||||
-rwxr-xr-x | glib/glibmm/environ.cc | 58 | ||||
-rwxr-xr-x | glib/glibmm/environ.h | 93 | ||||
-rw-r--r-- | glib/glibmm/filelist.am | 2 | ||||
-rw-r--r-- | glib/glibmm/meson.build | 1 | ||||
-rw-r--r-- | tests/Makefile.am | 2 | ||||
-rwxr-xr-x | tests/glibmm_environ/main.cc | 48 | ||||
-rw-r--r-- | tests/meson.build | 1 |
8 files changed, 206 insertions, 0 deletions
diff --git a/glib/glibmm.h b/glib/glibmm.h index 44e8cda1..5e3b278d 100644 --- a/glib/glibmm.h +++ b/glib/glibmm.h @@ -112,6 +112,7 @@ #include <glibmm/datetime.h> #include <glibmm/dispatcher.h> #include <glibmm/enums.h> +#include <glibmm/environ.h> #include <glibmm/error.h> #include <glibmm/exceptionhandler.h> #include <glibmm/fileutils.h> diff --git a/glib/glibmm/environ.cc b/glib/glibmm/environ.cc new file mode 100755 index 00000000..4586ef58 --- /dev/null +++ b/glib/glibmm/environ.cc @@ -0,0 +1,58 @@ +/* Copyright (C) 2021 The glibmm Development Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <glibmm/environ.h> +#include <glibmm/vectorutils.h> + +namespace Glib +{ + +Environ::Environ() +: envp(g_get_environ(), &g_strfreev) +{} + +Environ::Environ(const std::vector<std::string>& env_vec) +: envp(g_new(char*, env_vec.size() + 1), &g_strfreev) +{ + for (unsigned int i = 0; i < env_vec.size(); ++i) + envp.get()[i] = g_strdup(env_vec[i].c_str()); + envp.get()[env_vec.size()] = nullptr; +} + +std::optional<std::string> Environ::get(StdStringView variable) const +{ + const char* value = g_environ_getenv(envp.get(), variable.c_str()); + if (value) + return std::optional<std::string>(std::in_place, value); + return std::optional<std::string>(); +} + +void Environ::set(StdStringView variable, StdStringView value, bool overwrite) +{ + envp.reset(g_environ_setenv(envp.release(), variable.c_str(), value.c_str(), overwrite)); +} + +void Environ::unset(StdStringView variable) +{ + envp.reset(g_environ_unsetenv(envp.release(), variable.c_str())); +} + +std::vector<std::string> Environ::to_vector() const +{ + return Glib::ArrayHandler<std::string>::array_to_vector(envp.get(), Glib::OWNERSHIP_NONE); +} + +} // namespace Glib diff --git a/glib/glibmm/environ.h b/glib/glibmm/environ.h new file mode 100755 index 00000000..238ef532 --- /dev/null +++ b/glib/glibmm/environ.h @@ -0,0 +1,93 @@ +#ifndef _GLIBMM_ENVIRON_H +#define _GLIBMM_ENVIRON_H +/* Copyright (C) 2021 The glibmm Development Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <glibmm/ustring.h> +#include <memory> +#include <optional> +#include <string> +#include <vector> + +namespace Glib +{ + +/** A convenience class for manipulating a copy of the environment variables. + * + * Useful for generating the @a envp parameter in calls to + * Glib::spawn_async_with_pipes(), Glib::spawn_async() and Glib::spawn_sync(). + * + * If you want to change the environment itself (i.e. not a copy of it), + * see Glib::getenv(), Glib::setenv() and Glib::unsetenv(). + * + * @newin{2,70} + */ +class Environ +{ +public: + /** Constructs a list of environment variables for the current process. + * + * Each item in the list is of the form 'NAME=VALUE'. + */ + GLIBMM_API Environ(); + + /** Constructs a %Glib::Environ instance from a vector. + * + * @param env_vec A vector with the environment variables. Each element in + * the vector must be of the form 'NAME=VALUE'. + */ + GLIBMM_API explicit Environ(const std::vector<std::string>& env_vec); + + /** Gets the value of the environment variable @a variable. + * + * @param variable The environment variable to get, must not contain '='. + * @return The value of the environment variable, or an empty std::optional + * if the environment variable is not set in this %Environ. + */ + GLIBMM_API std::optional<std::string> get(StdStringView variable) const; + + /// Same as get(). + GLIBMM_API std::optional<std::string> operator[](StdStringView variable) const + { return get(variable); } + + /** Sets the environment variable @a variable in the provided list to @a value. + * + * @param variable The environment variable to set, must not contain '='. + * @param value The value to set the variable to. + * @param overwrite Whether to change the variable if it already exists. + */ + GLIBMM_API void set(StdStringView variable, StdStringView value, bool overwrite = true); + + /** Removes the environment variable @a variable from the provided list. + * + * @param variable The environment variable to remove, must not contain '='. + */ + GLIBMM_API void unset(StdStringView variable); + + /** Get a vector with the environment variables. + * + * @return A vector with the environment variables. Each element in the vector + * is of the form 'NAME=VALUE'. + */ + GLIBMM_API std::vector<std::string> to_vector() const; + +private: + std::unique_ptr<char*, decltype(&g_strfreev)> envp; +}; + +} // namespace Glib + +#endif /* _GLIBMM_ENVIRON_H */ diff --git a/glib/glibmm/filelist.am b/glib/glibmm/filelist.am index e606d5fd..6bd16f1c 100644 --- a/glib/glibmm/filelist.am +++ b/glib/glibmm/filelist.am @@ -8,6 +8,7 @@ glibmm_files_extra_cc = \ class.cc \ debug.cc \ dispatcher.cc \ + environ.cc \ error.cc \ exceptionhandler.cc \ extraclassinit.cc \ @@ -40,6 +41,7 @@ glibmm_files_extra_h = \ containerhandle_shared.h \ debug.h \ dispatcher.h \ + environ.h \ error.h \ exceptionhandler.h \ extraclassinit.h \ diff --git a/glib/glibmm/meson.build b/glib/glibmm/meson.build index b736a3cf..29f55bdd 100644 --- a/glib/glibmm/meson.build +++ b/glib/glibmm/meson.build @@ -76,6 +76,7 @@ glibmm_extra_h_cc_basenames = [ 'class', 'debug', 'dispatcher', + 'environ', 'error', 'exceptionhandler', 'extraclassinit', diff --git a/tests/Makefile.am b/tests/Makefile.am index 9adab850..9887f204 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -29,6 +29,7 @@ check_PROGRAMS = \ glibmm_base64/test \ glibmm_binding/test \ glibmm_date/test \ + glibmm_environ/test \ glibmm_buildfilename/test \ glibmm_interface_implementation/test \ glibmm_interface_move/test \ @@ -97,6 +98,7 @@ glibmm_base64_test_SOURCES = glibmm_base64/main.cc glibmm_binding_test_SOURCES = glibmm_binding/main.cc glibmm_buildfilename_test_SOURCES = glibmm_buildfilename/main.cc glibmm_date_test_SOURCES = glibmm_date/main.cc +glibmm_environ_test_SOURCES = glibmm_environ/main.cc glibmm_interface_implementation_test_SOURCES = glibmm_interface_implementation/main.cc glibmm_interface_implementation_test_LDADD = $(giomm_ldadd) diff --git a/tests/glibmm_environ/main.cc b/tests/glibmm_environ/main.cc new file mode 100755 index 00000000..c99e279d --- /dev/null +++ b/tests/glibmm_environ/main.cc @@ -0,0 +1,48 @@ +#include <glibmm.h> +#include <iostream> + +int +main(int, char**) +{ + Glib::Environ env1; + Glib::Environ env2(env1.to_vector()); + g_assert_true(env1.to_vector() == env2.to_vector()); + + // Empty environment. + const std::vector<std::string> empty_vector; + Glib::Environ env3(empty_vector); + g_assert_true(env3.to_vector().size() == 0); + + auto path = env1.get("PATH"); + if (!path) + { + // There ought to be a PATH. If there isn't, add one. + std::cout << "No PATH!" << std::endl; + env1.set("PATH", "/a/b/c"); + } + + path = env1["PATH"]; + if (!path) + { + // Now there really must be a PATH. + std::cerr << "Still no PATH!" << std::endl; + return EXIT_FAILURE; + } + + const std::string name = "GLIBMM_TEST_VAR"; + const std::string value = "This is a test value"; + env1.set(name, value); + g_assert_true(env1[name] == value); + env1.set(name, "Second value", false); + g_assert_true(env1.get(name) == value); + env1.set(name, "Second value"); + g_assert_true(env1.get(name) == "Second value"); + env1.unset(name); + if (env1.get(name)) + { + std::cerr << name << " not removed" << std::endl; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/tests/meson.build b/tests/meson.build index 653ed878..4d1135dc 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -18,6 +18,7 @@ test_programs = [ [['glibmm_buildfilename'], 'test', ['main.cc'], false], [['glibmm_bytearray'], 'test', ['main.cc'], false], [['glibmm_date'], 'test', ['main.cc'], false], + [['glibmm_environ'], 'test', ['main.cc'], false], [['glibmm_interface_implementation'], 'test', ['main.cc'], true], [['glibmm_interface_move'], 'test', ['main.cc'], false], [['glibmm_mainloop'], 'test', ['main.cc'], false], |