gnucash maint: Multiple changes pushed
Geert Janssens
gjanssens at code.gnucash.org
Fri Dec 28 12:47:16 EST 2018
Updated via https://github.com/Gnucash/gnucash/commit/267852ba (commit)
via https://github.com/Gnucash/gnucash/commit/272ca421 (commit)
via https://github.com/Gnucash/gnucash/commit/ac2e0946 (commit)
from https://github.com/Gnucash/gnucash/commit/2634f23f (commit)
commit 267852ba763331aa04ab0f7be33d3d74f4297a82
Author: Geert Janssens <geert at kobaltwit.be>
Date: Fri Dec 28 18:47:06 2018 +0100
Add a note on cvt and imbuing locales in a boost::filesystem::path object
diff --git a/libgnucash/core-utils/gnc-filepath-utils.cpp b/libgnucash/core-utils/gnc-filepath-utils.cpp
index 01ca259..e612c1c 100644
--- a/libgnucash/core-utils/gnc-filepath-utils.cpp
+++ b/libgnucash/core-utils/gnc-filepath-utils.cpp
@@ -68,7 +68,23 @@ extern "C" {
#include <boost/locale.hpp>
#include <iostream>
-
+/* Below cvt and bfs_locale should be used with boost::filesystem::path (bfs)
+ * objects created alter in this source file. The rationale is as follows:
+ * - a bfs object has an internal, locale and platform dependent
+ * representation of a file system path
+ * - glib's internal representation is always utf8
+ * - when creating a bfs object, we should pass a cvt to convert from
+ * utf8 to the object's internal representation
+ * - if we later want to use the bfs object's internal representation
+ * in a glib context we should imbue the locale below so that
+ * bfs will use it to convert back to utf8
+ * - if the bfs object's internal representation will never be used
+ * in a glib context, imbuing is not needed (although probably more
+ * future proof)
+ * - also note creating a bfs based on another one will inherit the
+ * locale from the source path. So in that case there's not need
+ * to imbue it again.
+ */
#if PLATFORM(WINDOWS)
#include <codecvt>
using codecvt = std::codecvt_utf8<wchar_t, 0x10FFFF, std::little_endian>;
commit 272ca421b73929e5bba1a585c854477414bea91c
Author: Geert Janssens <geert at kobaltwit.be>
Date: Fri Dec 28 18:36:46 2018 +0100
Set up filepath utils to determine the GNC_CONFIG_HOME in the same way as GNC_DATA_HOME
Until now GNC_CONFIG_HOME was more or less hard-coded.
Now it can be set via environment variable GNC_CONFIG_HOME.
In addition it will automatically be created to avoid potential
user confusion.
diff --git a/libgnucash/core-utils/gnc-filepath-utils.cpp b/libgnucash/core-utils/gnc-filepath-utils.cpp
index 92bf682..01ca259 100644
--- a/libgnucash/core-utils/gnc-filepath-utils.cpp
+++ b/libgnucash/core-utils/gnc-filepath-utils.cpp
@@ -718,14 +718,89 @@ constexpr auto path_package = PACKAGE_NAME;
constexpr auto path_package = PACKAGE;
#endif
-
-char *
-gnc_filepath_init (void)
+// Initialize the user's config directory for gnucash
+// creating it if it doesn't exist yet.
+static void
+gnc_file_path_init_config_home (void)
{
- // Initialize the user's config directory for gnucash
- gnc_userconfig_home = get_userconfig_home() / path_package;
+ auto have_valid_userconfig_home = false;
+
+ /* If this code is run while building/testing, use a fake GNC_CONFIG_HOME
+ * in the base of the build directory. This is to deal with all kinds of
+ * issues when the build environment is not a complete environment (like
+ * it could be missing a valid home directory). */
+ auto env_build_dir = g_getenv ("GNC_BUILDDIR");
+ bfs::path new_dir(env_build_dir ? env_build_dir : "", cvt);
+ new_dir.imbue(bfs_locale);
+ build_dir = std::move(new_dir);
+ auto running_uninstalled = (g_getenv ("GNC_UNINSTALLED") != NULL);
+ if (running_uninstalled && !build_dir.empty())
+ {
+ gnc_userconfig_home = build_dir / "gnc_config_home";
+ try
+ {
+ gnc_validate_directory (gnc_userconfig_home); // May throw
+ have_valid_userconfig_home = true;
+ }
+ catch (const bfs::filesystem_error& ex)
+ {
+ auto path_string = gnc_userconfig_home.string();
+ g_warning("%s (due to run during at build time) is not a suitable directory for user configuration files. "
+ "Trying another directory instead.\n(Error: %s)",
+ path_string.c_str(), ex.what());
+ }
+ }
+
+ if (!have_valid_userconfig_home)
+ {
+ /* If environment variable GNC_CONFIG_HOME is set, try whether
+ * it points at a valid directory. */
+ auto gnc_userconfig_home_env = g_getenv ("GNC_CONFIG_HOME");
+ if (gnc_userconfig_home_env)
+ {
+ bfs::path newdir(gnc_userconfig_home_env, cvt);
+ newdir.imbue(bfs_locale);
+ gnc_userconfig_home = std::move(newdir);
+ try
+ {
+ gnc_validate_directory (gnc_userconfig_home); // May throw
+ have_valid_userconfig_home = true;
+ }
+ catch (const bfs::filesystem_error& ex)
+ {
+ auto path_string = gnc_userconfig_home.string();
+ g_warning("%s (from environment variable 'GNC_CONFIG_HOME') is not a suitable directory for user configuration files. "
+ "Trying the default instead.\n(Error: %s)",
+ path_string.c_str(), ex.what());
+ }
+ }
+ }
+ if (!have_valid_userconfig_home)
+ {
+ /* Determine platform dependent default userconfig_home_path
+ * and check whether it's valid */
+ auto userconfig_home = get_userconfig_home();
+ gnc_userconfig_home = userconfig_home / path_package;
+ try
+ {
+ gnc_validate_directory (gnc_userconfig_home);
+ }
+ catch (const bfs::filesystem_error& ex)
+ {
+ g_warning ("User configuration directory doesn't exist, yet could not be created. Proceed with caution.\n"
+ "(Error: %s)", ex.what());
+ }
+ }
+}
+// Initialize the user's config directory for gnucash
+// creating it if it didn't exist yet.
+// The function will return true if the directory already
+// existed or false if it had to be created
+static bool
+gnc_file_path_init_data_home (void)
+{
// Initialize the user's data directory for gnucash
auto gnc_userdata_home_exists = false;
auto have_valid_userdata_home = false;
@@ -764,8 +839,8 @@ gnc_filepath_init (void)
auto gnc_userdata_home_env = g_getenv ("GNC_DATA_HOME");
if (gnc_userdata_home_env)
{
- bfs::path newdir(gnc_userdata_home_env, cvt);
- newdir.imbue(bfs_locale);
+ bfs::path newdir(gnc_userdata_home_env, cvt);
+ newdir.imbue(bfs_locale);
gnc_userdata_home = std::move(newdir);
try
{
@@ -778,7 +853,7 @@ gnc_filepath_init (void)
auto path_string = gnc_userdata_home.string();
g_warning("%s (from environment variable 'GNC_DATA_HOME') is not a suitable directory for user data. "
"Trying the default instead.\n(Error: %s)",
- path_string.c_str(), ex.what());
+ path_string.c_str(), ex.what());
}
}
}
@@ -801,6 +876,25 @@ gnc_filepath_init (void)
}
}
+ return gnc_userdata_home_exists;
+}
+
+// Initialize the user's config and data directory for gnucash
+// This function will also create these directories if they didn't
+// exist yet.
+// In addition it will trigger a migration if the user's data home
+// didn't exist but the now obsolete GNC_DOT_DIR ($HOME/.gnucash)
+// does.
+// Finally it well ensure a number of default required directories
+// will be created if they don't exist yet.
+char *
+gnc_filepath_init (void)
+{
+ gnc_userconfig_home = get_userconfig_home() / path_package;
+
+ gnc_file_path_init_config_home ();
+ auto gnc_userdata_home_exists = gnc_file_path_init_data_home ();
+
/* Run migration code before creating the default directories
If migrating, these default directories are copied instead of created. */
auto migration_notice = std::string ();
commit ac2e0946eac6e00113bf1c4af48e9735230f1331
Author: Geert Janssens <geert at kobaltwit.be>
Date: Fri Dec 28 16:13:58 2018 +0100
Rewrite path scrubbing in a c++ way
diff --git a/libgnucash/core-utils/gnc-filepath-utils.cpp b/libgnucash/core-utils/gnc-filepath-utils.cpp
index 67e930d..92bf682 100644
--- a/libgnucash/core-utils/gnc-filepath-utils.cpp
+++ b/libgnucash/core-utils/gnc-filepath-utils.cpp
@@ -90,26 +90,6 @@ namespace bfs = boost::filesystem;
namespace bst = boost::system;
namespace bl = boost::locale;
-/**
- * Scrubs a filename by changing "strange" chars (e.g. those that are not
- * valid in a win32 file name) to "_".
- *
- * @param filename File name - updated in place
- */
-static void
-scrub_filename(char* filename)
-{
- char* p;
-
-#define STRANGE_CHARS "/:"
- p = strpbrk(filename, STRANGE_CHARS);
- while (p)
- {
- *p = '_';
- p = strpbrk(filename, STRANGE_CHARS);
- }
-}
-
/** Check if the path exists and is a regular file.
*
* \param path -- freed if the path doesn't exist or isn't a regular file
@@ -942,14 +922,22 @@ gnc_build_userdata_path (const gchar *filename)
return g_strdup((gnc_userdata_dir_as_path() / filename).string().c_str());
}
+/* Test whether c is a valid character for a win32 file name.
+ * If so return false, otherwise return true.
+ */
+static bool
+is_invalid_char (char c)
+{
+ return (c == '/') || ( c == ':');
+}
+
static bfs::path
gnc_build_userdata_subdir_path (const gchar *subdir, const gchar *filename)
{
- gchar* filename_dup = g_strdup(filename);
+ auto fn = std::string(filename);
- scrub_filename(filename_dup);
- auto result = (gnc_userdata_dir_as_path() / subdir) / filename_dup;
- g_free(filename_dup);
+ std::replace_if (fn.begin(), fn.end(), is_invalid_char, '_');
+ auto result = (gnc_userdata_dir_as_path() / subdir) / fn;
return result;
}
Summary of changes:
libgnucash/core-utils/gnc-filepath-utils.cpp | 164 +++++++++++++++++++++------
1 file changed, 131 insertions(+), 33 deletions(-)
More information about the gnucash-changes
mailing list