gnucash maint: Multiple changes pushed

John Ralls jralls at code.gnucash.org
Sun Apr 22 19:13:42 EDT 2018


Updated	 via  https://github.com/Gnucash/gnucash/commit/8e9b1346 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/35cd165b (commit)
	from  https://github.com/Gnucash/gnucash/commit/451bbd53 (commit)



commit 8e9b13461ef841d0179308e5b6d37a8c486e05aa
Author: John Ralls <jralls at ceridwen.us>
Date:   Sun Apr 22 16:09:03 2018 -0700

    Reverse Swig "off-by-one" error.
    
    See
    https://github.com/swig/swig/commit/46ab0c252da9ab846265a60517ca462e5256cd24
    
    Fixes the rest of Bug 795134.
    Seems to fix Bug 794965 - Non-English Characters don't display properly
    in reports.

diff --git a/common/guile-mappings.h b/common/guile-mappings.h
index 386b24b..5e758a2 100644
--- a/common/guile-mappings.h
+++ b/common/guile-mappings.h
@@ -21,6 +21,10 @@
 
 /* Convenience macros */
 
+#if defined(scm_to_utf8_string) && SCM_MAJOR_VERSION >= 2
+#undef scm_to_utf8_string
+#undef scm_from_utf8_string
+#endif
 #define scm_is_equal(obj1,obj2)	scm_is_true(scm_equal_p(obj1,obj2))
 #define scm_is_exact(obj)	scm_is_true(scm_exact_p(obj))
 #define scm_is_list(obj)	scm_is_true(scm_list_p(obj))

commit 35cd165bec46743351978c47b2221b78e21039f7
Author: John Ralls <jralls at ceridwen.us>
Date:   Fri Apr 20 14:09:53 2018 -0700

    Bug 795134 - Improper handle of unicode character in username
    
    Part 1: gnc-filename-utils didn't manage the encoding differences
    between Windows (UTF16) and GLib (UTF-8).

diff --git a/gnucash/gnucash-bin.c b/gnucash/gnucash-bin.c
index 51525ec..e9a8277 100644
--- a/gnucash/gnucash-bin.c
+++ b/gnucash/gnucash-bin.c
@@ -81,7 +81,11 @@ static int          gnucash_show_version = 0;
 static int          debugging        = 0;
 static int          extra            = 0;
 static gchar      **log_flags        = NULL;
-static gchar       *log_to_filename  = NULL;
+#ifdef __MINGW64__
+static wchar_t     *log_to_filename  = NULL;
+#else
+static char        *log_to_filename  = NULL;
+#endif
 static int          nofile           = 0;
 static const gchar *gsettings_prefix = NULL;
 static const char  *add_quotes_file  = NULL;
@@ -679,7 +683,12 @@ gnc_log_init()
 {
     if (log_to_filename != NULL)
     {
-        qof_log_init_filename_special(log_to_filename);
+#ifdef __MINGW64__
+	char* filename = g_utf16_to_utf8(log_to_filename, -1, NULL, NULL, NULL);
+#else
+	char* filename = log_to_filename;
+#endif
+        qof_log_init_filename_special(filename);
     }
     else
     {
diff --git a/libgnucash/core-utils/gnc-filepath-utils.cpp b/libgnucash/core-utils/gnc-filepath-utils.cpp
index e259798..6fc3a08 100644
--- a/libgnucash/core-utils/gnc-filepath-utils.cpp
+++ b/libgnucash/core-utils/gnc-filepath-utils.cpp
@@ -66,14 +66,19 @@ extern "C" {
 
 #include <boost/filesystem.hpp>
 #include <boost/locale.hpp>
+#include <codecvt>
 #include <iostream>
 
 
-
 #if PLATFORM(WINDOWS)
-#include <codecvt>
-#include <locale>
+using codecvt = std::codecvt_utf8<wchar_t, 0x10FFFF, std::little_endian>;
+using string = std::wstring;
+#else
+using codecvt = std::codecvt;
+using string = std::string;
 #endif
+static codecvt cvt;
+static std::locale bfs_locale(std::locale(), new codecvt);
 
 namespace bfs = boost::filesystem;
 namespace bst = boost::system;
@@ -366,7 +371,8 @@ gnc_validate_directory (const bfs::path &dirname)
          * we need to overrule it during build (when guile interferes)
          * and testing.
          */
-        auto home_dir = bfs::path (g_get_home_dir ());
+	bfs::path home_dir(g_get_home_dir(), cvt);
+	home_dir.imbue(bfs_locale);
         auto homedir_exists = bfs::exists(home_dir);
         auto is_descendant = dir_is_descendant (dirname, home_dir);
         if (!homedir_exists && is_descendant)
@@ -432,11 +438,16 @@ copy_recursive(const bfs::path& src, const bfs::path& dest)
         for(auto direntry = bfs::recursive_directory_iterator(src);
             direntry != bfs::recursive_directory_iterator(); ++direntry)
         {
-            auto cur_str = direntry->path().string();
+#ifdef G_OS_WIN32
+            string cur_str = direntry->path().wstring();
+#else
+            string cur_str = direntry->path().string();
+#endif
             auto cur_len = cur_str.size();
-            auto rel_str = std::string(cur_str, old_len, cur_len - old_len);
-            auto relpath = bfs::path(rel_str).relative_path();
-            auto newpath = bfs::absolute (relpath, dest);
+	    string rel_str(cur_str, old_len, cur_len - old_len);
+	    bfs::path relpath(rel_str, cvt);
+            auto newpath = bfs::absolute (relpath.relative_path(), dest);
+	    newpath.imbue(bfs_locale);
             bfs::copy(direntry->path(), newpath);
         }
     }
@@ -458,31 +469,27 @@ copy_recursive(const bfs::path& src, const bfs::path& dest)
  * So this function is a copy of glib's internal get_special_folder
  * and minimally adjusted to fetch CSIDL_APPDATA
  */
-static char *
-win32_get_userdata_home (void)
+static bfs::path
+get_user_data_dir ()
 {
     wchar_t path[MAX_PATH+1];
     HRESULT hr;
     LPITEMIDLIST pidl = NULL;
     BOOL b;
-    char *retval = NULL;
 
     hr = SHGetSpecialFolderLocation (NULL, CSIDL_APPDATA, &pidl);
     if (hr == S_OK)
     {
         b = SHGetPathFromIDListW (pidl, path);
-        if (b)
-        {
-            std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
-            retval = g_strdup(utf8_conv.to_bytes(path).c_str());
-        }
         CoTaskMemFree (pidl);
     }
+    bfs::path retval(path, cvt);
+    retval.imbue(bfs_locale);
     return retval;
 }
 #elif defined MAC_INTEGRATION
-static char*
-quarz_get_userdata_home(void)
+static bfs::path
+get_user_data_dir()
 {
     char *retval = NULL;
     NSFileManager*fm = [NSFileManager defaultManager];
@@ -492,9 +499,14 @@ quarz_get_userdata_home(void)
     {
         NSURL* dirUrl = [appSupportDir objectAtIndex:0];
         NSString* dirPath = [dirUrl path];
-        retval = g_strdup([dirPath UTF8String]);
     }
-    return retval;
+    return [dirPath UTF8String];
+}
+#else
+static bfs::path
+get_user_data_dir()
+{
+    return g_get_user_data_dir();
 }
 #endif
 
@@ -508,22 +520,8 @@ static bfs::path
 get_userdata_home(void)
 {
     auto try_tmp_dir = true;
-    gchar *data_dir = NULL;
-    auto userdata_home = bfs::path();
+    auto userdata_home = get_user_data_dir();
 
-#ifdef G_OS_WIN32
-    data_dir = win32_get_userdata_home ();
-#elif defined MAC_INTEGRATION
-    data_dir = quarz_get_userdata_home ();
-#endif
-
-    if (data_dir)
-    {
-        userdata_home = data_dir;
-        g_free(data_dir);
-    }
-    else
-        userdata_home = g_get_user_data_dir();
 
     /* g_get_user_data_dir doesn't check whether the path exists nor attempts to
      * create it. So while it may return an actual path we may not be able to use it.
@@ -548,7 +546,9 @@ get_userdata_home(void)
        Hopefully we can always write there. */
     if (try_tmp_dir)
     {
-        userdata_home = bfs::path (g_get_tmp_dir ()) / g_get_user_name ();
+	bfs::path newpath(g_get_tmp_dir (), cvt);
+	newpath.imbue(bfs_locale);
+        userdata_home = std::move(newpath);
     }
     g_assert(!userdata_home.empty());
 
@@ -564,33 +564,21 @@ get_userdata_home(void)
 static bfs::path
 get_userconfig_home(void)
 {
-    gchar *config_dir = NULL;
-    auto userconfig_home = bfs::path();
-
-#ifdef G_OS_WIN32
-    config_dir = win32_get_userdata_home ();
-#elif defined MAC_INTEGRATION
-    config_dir = quarz_get_userdata_home ();
-#endif
-
     /* On Windows and Macs the data directory is used, for Linux
        $HOME/.config is used */
-    if (config_dir)
-    {
-        userconfig_home = config_dir;
-        g_free(config_dir);
-    }
-    else
-        userconfig_home = g_get_user_config_dir();
-
-    return userconfig_home;
+#if defined (G_OS_WIN32) || defined (MAC_INTEGRATION)
+    return get_user_data_dir();
+#else
+    return g_get_user_config_dir();
+#endif
 }
 
 static std::string migrate_gnc_datahome()
 {
     auto success = false;
     // Specify location of dictionaries
-    auto old_dir = bfs::path(g_get_home_dir()) / ".gnucash";
+    bfs::path old_dir(g_get_home_dir(), cvt);
+    old_dir += ".gnucash";
 
     bl::generator gen;
     gen.add_messages_path(gnc_path_get_datadir());
@@ -760,7 +748,9 @@ gnc_filepath_init (void)
      * 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");
-    build_dir = bfs::path(env_build_dir ? env_build_dir : "");
+    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())
     {
@@ -787,7 +777,9 @@ gnc_filepath_init (void)
         auto gnc_userdata_home_env = g_getenv ("GNC_DATA_HOME");
         if (gnc_userdata_home_env)
         {
-            gnc_userdata_home = bfs::path (gnc_userdata_home_env);
+	    bfs::path newdir(gnc_userdata_home_env, cvt);
+	    newdir.imbue(bfs_locale);
+            gnc_userdata_home = std::move(newdir);
             try
             {
                 gnc_userdata_home_exists = bfs::exists (gnc_userdata_home);
diff --git a/libgnucash/engine/qoflog.cpp b/libgnucash/engine/qoflog.cpp
index 7d0707b..fc2738d 100644
--- a/libgnucash/engine/qoflog.cpp
+++ b/libgnucash/engine/qoflog.cpp
@@ -166,7 +166,7 @@ qof_log_init_filename(const gchar* log_filename)
 #if PLATFORM(WINDOWS)
             /* MSVC compiler: Somehow the OS thinks file descriptor from above
              * still isn't open. So we open normally with the file name and that's it. */
-            fout = fopen(fname, "wb");
+            fout = g_fopen(fname, "wb");
 #else
             /* We must not overwrite /dev/null */
             g_assert(g_strcmp0(log_filename, "/dev/null") != 0);



Summary of changes:
 common/guile-mappings.h                      |   4 +
 gnucash/gnucash-bin.c                        |  13 +++-
 libgnucash/core-utils/gnc-filepath-utils.cpp | 106 +++++++++++++--------------
 libgnucash/engine/qoflog.cpp                 |   2 +-
 4 files changed, 65 insertions(+), 60 deletions(-)



More information about the gnucash-changes mailing list