mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Rewrite several file path routines to use boost::filesystem
This is a basis for moving .gnucash to a more modern location for application specific user data (following the xdg spec).
This commit is contained in:
parent
2006155985
commit
ae75bc963f
@ -438,7 +438,7 @@ SET (Boost_FIND_QUIETLY ON)
|
||||
IF (NOT DEFINED ${BOOST_ROOT})
|
||||
SET(BOOST_ROOT $ENV{BOOST_ROOT})
|
||||
ENDIF()
|
||||
FIND_PACKAGE (Boost 1.54.0 REQUIRED COMPONENTS date_time regex locale)
|
||||
FIND_PACKAGE (Boost 1.54.0 REQUIRED COMPONENTS date_time regex locale filesystem)
|
||||
|
||||
IF (Boost_FOUND)
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
|
@ -430,7 +430,7 @@ show_session_error (QofBackendError io_error,
|
||||
fmt = _("You attempted to save in\n%s\nor a subdirectory thereof. "
|
||||
"This is not allowed as %s reserves that directory for internal use.\n\n"
|
||||
"Please try again in a different directory.");
|
||||
gnc_error_dialog (parent, fmt, gnc_dotgnucash_dir(), PACKAGE_NAME);
|
||||
gnc_error_dialog (parent, fmt, gnc_userdata_dir(), PACKAGE_NAME);
|
||||
break;
|
||||
|
||||
case ERR_SQL_DB_TOO_OLD:
|
||||
@ -1139,7 +1139,7 @@ check_file_path (const char *path)
|
||||
{
|
||||
/* Remember the directory as the default. */
|
||||
gchar *dir = g_path_get_dirname(path);
|
||||
const gchar *dotgnucash = gnc_dotgnucash_dir();
|
||||
const gchar *dotgnucash = gnc_userdata_dir();
|
||||
char *dirpath = dir;
|
||||
|
||||
/* Prevent user from storing file in GnuCash' private configuration
|
||||
|
@ -719,7 +719,7 @@ gnc_gui_init(void)
|
||||
gnc_window_set_progressbar_window (GNC_WINDOW(main_window));
|
||||
|
||||
#ifdef MAC_INTEGRATION
|
||||
map = gnc_build_dotgnucash_path(ACCEL_MAP_NAME);
|
||||
map = gnc_build_userdata_path(ACCEL_MAP_NAME);
|
||||
if (!g_file_test (map, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
g_free (map);
|
||||
@ -728,7 +728,7 @@ gnc_gui_init(void)
|
||||
g_free(data_dir);
|
||||
}
|
||||
#else
|
||||
map = gnc_build_dotgnucash_path(ACCEL_MAP_NAME);
|
||||
map = gnc_build_userdata_path(ACCEL_MAP_NAME);
|
||||
#endif /* MAC_INTEGRATION */
|
||||
gtk_accel_map_load(map);
|
||||
g_free(map);
|
||||
@ -765,7 +765,7 @@ gnc_gui_shutdown (void)
|
||||
if (gnome_is_running && !gnome_is_terminating)
|
||||
{
|
||||
gnome_is_terminating = TRUE;
|
||||
map = gnc_build_dotgnucash_path(ACCEL_MAP_NAME);
|
||||
map = gnc_build_userdata_path(ACCEL_MAP_NAME);
|
||||
gtk_accel_map_save(map);
|
||||
g_free(map);
|
||||
gtk_main_quit();
|
||||
|
@ -799,7 +799,7 @@ pcd_save_custom_data(PrintCheckDialog *pcd, const gchar *title)
|
||||
pcd->splits_account_x, pcd->splits_account_y);
|
||||
|
||||
filename = g_strconcat(title, CHECK_NAME_EXTENSION, NULL);
|
||||
pathname = g_build_filename(gnc_dotgnucash_dir(), CHECK_FMT_DIR,
|
||||
pathname = g_build_filename(gnc_userdata_dir(), CHECK_FMT_DIR,
|
||||
filename, NULL);
|
||||
|
||||
if (gnc_key_file_save_to_file(pathname, key_file, &error))
|
||||
@ -1558,7 +1558,7 @@ read_formats(PrintCheckDialog *pcd, GtkListStore *store)
|
||||
g_free(dirname);
|
||||
g_free(pkgdatadir);
|
||||
|
||||
dirname = gnc_build_dotgnucash_path(CHECK_FMT_DIR);
|
||||
dirname = gnc_build_userdata_path(CHECK_FMT_DIR);
|
||||
/* Translators: This is a directory name. It may be presented to
|
||||
* the user to indicate that some data file was defined by a
|
||||
* user herself. */
|
||||
@ -1901,7 +1901,7 @@ read_image (const gchar *filename)
|
||||
if (!g_file_test(tmp_name, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
g_free(tmp_name);
|
||||
dirname = gnc_build_dotgnucash_path(CHECK_FMT_DIR);
|
||||
dirname = gnc_build_userdata_path(CHECK_FMT_DIR);
|
||||
tmp_name = g_build_filename(dirname, filename, (char *)NULL);
|
||||
g_free(dirname);
|
||||
}
|
||||
|
@ -344,7 +344,7 @@ try_load_config_array(const gchar *fns[])
|
||||
|
||||
for (i = 0; fns[i]; i++)
|
||||
{
|
||||
filename = gnc_build_dotgnucash_path(fns[i]);
|
||||
filename = gnc_build_userdata_path(fns[i]);
|
||||
if (gfec_try_load(filename))
|
||||
{
|
||||
g_free(filename);
|
||||
@ -703,7 +703,7 @@ gnc_log_init()
|
||||
|
||||
{
|
||||
gchar *log_config_filename;
|
||||
log_config_filename = gnc_build_dotgnucash_path("log.conf");
|
||||
log_config_filename = gnc_build_userdata_path("log.conf");
|
||||
if (g_file_test(log_config_filename, G_FILE_TEST_EXISTS))
|
||||
qof_log_parse_log_config(log_config_filename);
|
||||
g_free(log_config_filename);
|
||||
|
@ -91,7 +91,7 @@
|
||||
(false-if-exception
|
||||
(read)))
|
||||
|
||||
(let* ((pref-filename (gnc-build-dotgnucash-path "qif-accounts-map"))
|
||||
(let* ((pref-filename (gnc-build-userdata-path "qif-accounts-map"))
|
||||
(results '()))
|
||||
|
||||
;; Get the user's saved mappings.
|
||||
@ -293,7 +293,7 @@
|
||||
|
||||
;; This procedure does all the work. We'll define it, then call it safely.
|
||||
(define (private-save)
|
||||
(with-output-to-file (gnc-build-dotgnucash-path "qif-accounts-map")
|
||||
(with-output-to-file (gnc-build-userdata-path "qif-accounts-map")
|
||||
(lambda ()
|
||||
(display ";;; qif-accounts-map")
|
||||
(newline)
|
||||
|
@ -1116,7 +1116,7 @@ gnc_plugin_page_report_constr_init(GncPluginPageReport *plugin_page, gint report
|
||||
GncPluginPage *parent;
|
||||
gboolean use_new;
|
||||
gchar *name;
|
||||
gchar *saved_reports_path = gnc_build_dotgnucash_path (SAVED_REPORTS_FILE);
|
||||
gchar *saved_reports_path = gnc_build_userdata_path (SAVED_REPORTS_FILE);
|
||||
gchar *report_save_str = g_strdup_printf (
|
||||
_("Update the current report's saved configuration. "
|
||||
"The report will be saved in the file %s. "), saved_reports_path);
|
||||
|
@ -82,7 +82,7 @@
|
||||
;; Then look in Gnucash's standard report directory.
|
||||
;; If no file is found, returns just 'fname' for use in error messages.
|
||||
;; Note: this has been tested on Linux and Windows Vista so far...
|
||||
(let* ((userpath (gnc-build-dotgnucash-path fname))
|
||||
(let* ((userpath (gnc-build-userdata-path fname))
|
||||
(syspath (gnc-build-report-path fname)))
|
||||
; make sure there's a trailing delimiter
|
||||
(if (access? userpath R_OK)
|
||||
|
@ -279,8 +279,8 @@ gnc_saved_reports_write_internal (const gchar *file, const gchar *contents, gboo
|
||||
gboolean gnc_saved_reports_backup (void)
|
||||
{
|
||||
gboolean success = FALSE;
|
||||
gchar *saved_rpts_path = gnc_build_dotgnucash_path (SAVED_REPORTS_FILE);
|
||||
gchar *saved_rpts_bkp_path = g_strconcat (saved_rpts_path, "-backup", NULL);
|
||||
gchar *saved_rpts_path = gnc_build_userdata_path (SAVED_REPORTS_FILE);
|
||||
gchar *saved_rpts_bkp_path = gnc_build_userdata_path (SAVED_REPORTS_FILE "-backup");
|
||||
gchar *contents = NULL;
|
||||
GError *save_error = NULL;
|
||||
|
||||
@ -310,7 +310,7 @@ gboolean
|
||||
gnc_saved_reports_write_to_file (const gchar* report_def, gboolean overwrite)
|
||||
{
|
||||
gboolean success = FALSE;
|
||||
gchar *saved_rpts_path = gnc_build_dotgnucash_path (SAVED_REPORTS_FILE);
|
||||
gchar *saved_rpts_path = gnc_build_userdata_path (SAVED_REPORTS_FILE);
|
||||
|
||||
if (report_def)
|
||||
{
|
||||
|
@ -127,7 +127,7 @@
|
||||
(record-accessor <html-style-sheet> 'style))
|
||||
|
||||
(define gnc:current-saved-stylesheets
|
||||
(gnc-build-dotgnucash-path "stylesheets-2.0"))
|
||||
(gnc-build-userdata-path "stylesheets-2.0"))
|
||||
|
||||
(define (gnc:save-style-sheet-options)
|
||||
(let ((port (false-if-exception
|
||||
|
@ -30,7 +30,6 @@
|
||||
(use-modules (gnucash report report-system))
|
||||
(use-modules (gnucash app-utils))
|
||||
(use-modules (gnucash engine))
|
||||
(use-modules (sw_engine))
|
||||
(use-modules (gnucash report report-system collectors))
|
||||
(use-modules (gnucash report report-system list-extras))
|
||||
|
||||
|
@ -228,7 +228,7 @@ error_handler(const char *msg)
|
||||
}
|
||||
|
||||
gboolean
|
||||
gfec_try_load(gchar *fn)
|
||||
gfec_try_load(const gchar *fn)
|
||||
{
|
||||
g_debug("looking for %s", fn);
|
||||
if (g_file_test(fn, G_FILE_TEST_EXISTS))
|
||||
|
@ -18,6 +18,6 @@ typedef void (*gfec_error_handler)(const char *error_message);
|
||||
SCM gfec_eval_file(const char *file, gfec_error_handler error_handler);
|
||||
SCM gfec_eval_string(const char *str, gfec_error_handler error_handler);
|
||||
SCM gfec_apply(SCM proc, SCM arglist, gfec_error_handler error_handler);
|
||||
gboolean gfec_try_load(gchar *fn);
|
||||
gboolean gfec_try_load(const gchar *fn);
|
||||
|
||||
#endif
|
||||
|
@ -61,7 +61,7 @@ static gboolean parser_inited = FALSE;
|
||||
static gchar *
|
||||
gnc_exp_parser_filname (void)
|
||||
{
|
||||
return gnc_build_dotgnucash_path("expressions-2.0");
|
||||
return gnc_build_userdata_path("expressions-2.0");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -16,7 +16,7 @@ SET (core_utils_SOURCES
|
||||
binreloc.c
|
||||
gnc-prefs.c
|
||||
gnc-environment.c
|
||||
gnc-filepath-utils.c
|
||||
gnc-filepath-utils.cpp
|
||||
gnc-gkeyfile-utils.c
|
||||
gnc-glib-utils.c
|
||||
gnc-guile-utils.c
|
||||
@ -117,7 +117,7 @@ SET(core_utils_noinst_HEADERS
|
||||
)
|
||||
|
||||
SET(core_utils_ALL_SOURCES ${core_utils_SOURCES} ${core_utils_noinst_HEADERS})
|
||||
SET(core_utils_ALL_LIBRARIES ${GUILE_LDFLAGS} ${GLIB2_LDFLAGS} ${GOBJECT_LDFLAGS} ${GTK_MAC_LDFLAGS})
|
||||
SET(core_utils_ALL_LIBRARIES ${Boost_LIBRARIES} -lboost_filesystem ${GUILE_LDFLAGS} ${GLIB2_LDFLAGS} ${GOBJECT_LDFLAGS} ${GTK_MAC_LDFLAGS})
|
||||
SET(core_utils_ALL_INCLUDES
|
||||
${CMAKE_SOURCE_DIR}/common
|
||||
${CMAKE_BINARY_DIR}/common
|
||||
|
@ -8,7 +8,7 @@ libgnc_core_utils_la_SOURCES = \
|
||||
binreloc.c \
|
||||
gnc-prefs.c \
|
||||
gnc-environment.c \
|
||||
gnc-filepath-utils.c \
|
||||
gnc-filepath-utils.cpp \
|
||||
gnc-gkeyfile-utils.c \
|
||||
gnc-glib-utils.c \
|
||||
gnc-guile-utils.c \
|
||||
@ -21,7 +21,8 @@ libgnc_core_utils_la_LIBADD = \
|
||||
${GUILE_LIBS} \
|
||||
${GLIB_LIBS} \
|
||||
${BINRELOC_LIBS} \
|
||||
${GTK_MAC_LIBS}
|
||||
${GTK_MAC_LIBS} \
|
||||
${BOOST_LDFLAGS} -lboost_filesystem
|
||||
|
||||
|
||||
noinst_HEADERS = \
|
||||
@ -58,7 +59,8 @@ AM_CPPFLAGS = \
|
||||
${GLIB_CFLAGS} \
|
||||
${GTK_MAC_CFLAGS} \
|
||||
-I${top_builddir}/common \
|
||||
-I${top_srcdir}/common
|
||||
-I${top_srcdir}/common \
|
||||
$(BOOST_CPPFLAGS)
|
||||
|
||||
gncscmmoddir = ${GNC_SCM_INSTALL_DIR}/gnucash
|
||||
gncscmmod_DATA = core-utils.scm
|
||||
|
@ -65,8 +65,8 @@ gchar * gnc_path_get_stdreportsdir(void);
|
||||
%newobject gnc_path_find_localized_html_file;
|
||||
gchar * gnc_path_find_localized_html_file(const gchar *);
|
||||
|
||||
%newobject gnc_build_dotgnucash_path;
|
||||
gchar * gnc_build_dotgnucash_path(const gchar *);
|
||||
%newobject gnc_build_userdata_path;
|
||||
gchar * gnc_build_userdata_path(const gchar *);
|
||||
|
||||
gchar * gnc_build_report_path(const gchar *);
|
||||
gchar * gnc_build_stdreports_path(const gchar *);
|
||||
|
@ -41,7 +41,7 @@
|
||||
(re-export gnc-path-get-bindir)
|
||||
(re-export gnc-path-get-stdreportsdir)
|
||||
(re-export gnc-path-find-localized-html-file)
|
||||
(re-export gnc-build-dotgnucash-path)
|
||||
(re-export gnc-build-userdata-path)
|
||||
(re-export gnc-build-report-path)
|
||||
(re-export gnc-build-stdreports-path)
|
||||
(re-export gnc-utf8?)
|
||||
|
@ -26,6 +26,7 @@
|
||||
* @author Copyright (c) 2000 Dave Peticolas
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
#include "config.h"
|
||||
|
||||
#include <platform.h>
|
||||
@ -55,6 +56,12 @@
|
||||
#include <glib/gwin32.h>
|
||||
#define PATH_MAX MAXPATHLEN
|
||||
#endif
|
||||
}
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace bfs = boost::filesystem;
|
||||
namespace bst = boost::system;
|
||||
|
||||
/**
|
||||
* Scrubs a filename by changing "strange" chars (e.g. those that are not
|
||||
@ -164,7 +171,7 @@ gnc_resolve_file_path (const gchar * filefrag)
|
||||
return fullpath;
|
||||
|
||||
/* Look in the users config dir (e.g. $HOME/.gnucash/data) */
|
||||
fullpath = gnc_build_data_path(filefrag);
|
||||
fullpath = g_strdup(gnc_build_data_path(filefrag));
|
||||
if (g_file_test(fullpath, G_FILE_TEST_IS_REGULAR))
|
||||
return fullpath;
|
||||
|
||||
@ -196,7 +203,7 @@ gnc_path_find_localized_html_file_internal (const gchar * file_name)
|
||||
const gchar *env_doc_path = g_getenv("GNC_DOC_PATH");
|
||||
const gchar *default_dirs[] =
|
||||
{
|
||||
gnc_build_dotgnucash_path ("html"),
|
||||
gnc_build_userdata_path ("html"),
|
||||
gnc_path_get_pkgdocdir (),
|
||||
gnc_path_get_pkgdatadir (),
|
||||
NULL
|
||||
@ -292,190 +299,156 @@ gnc_path_find_localized_html_file (const gchar *file_name)
|
||||
}
|
||||
|
||||
/* ====================================================================== */
|
||||
|
||||
/** @brief Check that the supplied directory path exists, is a directory, and
|
||||
* that the user has adequate permissions to use it.
|
||||
*
|
||||
* @param dirname The path to check
|
||||
*/
|
||||
static gboolean
|
||||
gnc_validate_directory (const gchar *dirname, gboolean create, gchar **msg)
|
||||
static bool
|
||||
gnc_validate_directory (const bfs::path &dirname, bool create)
|
||||
{
|
||||
GStatBuf statbuf;
|
||||
gint rc;
|
||||
if (dirname.empty())
|
||||
return false;
|
||||
|
||||
*msg = NULL;
|
||||
rc = g_stat (dirname, &statbuf);
|
||||
if (rc)
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
case ENOENT:
|
||||
if (create)
|
||||
{
|
||||
rc = g_mkdir (dirname,
|
||||
#ifdef G_OS_WIN32
|
||||
0 /* The mode argument is ignored on windows */
|
||||
#else
|
||||
S_IRWXU /* perms = S_IRWXU = 0700 */
|
||||
#endif
|
||||
);
|
||||
if (rc)
|
||||
{
|
||||
*msg = g_strdup_printf(
|
||||
_("An error occurred while creating the directory:\n"
|
||||
" %s\n"
|
||||
"Please correct the problem and restart GnuCash.\n"
|
||||
"The reported error was '%s' (errno %d).\n"),
|
||||
dirname, g_strerror(errno) ? g_strerror(errno) : "", errno);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*msg = g_strdup_printf(
|
||||
_("Note: the directory\n"
|
||||
" %s\n"
|
||||
"doesn't exist. This is however not fatal.\n"),
|
||||
dirname);
|
||||
return FALSE;
|
||||
}
|
||||
g_stat (dirname, &statbuf);
|
||||
break;
|
||||
if (!bfs::exists(dirname) && (!create))
|
||||
return false;
|
||||
|
||||
case EACCES:
|
||||
*msg = g_strdup_printf(
|
||||
_("The directory\n"
|
||||
" %s\n"
|
||||
"exists but cannot be accessed. This program \n"
|
||||
"must have full access (read/write/execute) to \n"
|
||||
"the directory in order to function properly.\n"),
|
||||
dirname);
|
||||
return FALSE;
|
||||
/* Optionally create directories if they don't exist yet
|
||||
* Note this will do nothing if the directory and its
|
||||
* parents already exist, but will fail if the path
|
||||
* points to a file or a softlink. So it serves as a test
|
||||
* for that as well.
|
||||
*/
|
||||
bfs::create_directories(dirname);
|
||||
|
||||
case ENOTDIR:
|
||||
*msg = g_strdup_printf(
|
||||
_("The path\n"
|
||||
" %s\n"
|
||||
"exists but it is not a directory. Please delete\n"
|
||||
"the file and start GnuCash again.\n"),
|
||||
dirname);
|
||||
return FALSE;
|
||||
auto d = bfs::directory_entry (dirname);
|
||||
auto perms = d.status().permissions();
|
||||
|
||||
default:
|
||||
*msg = g_strdup_printf(
|
||||
_("An unknown error occurred when validating that the\n"
|
||||
" %s\n"
|
||||
"directory exists and is usable. Please correct the\n"
|
||||
"problem and restart GnuCash. The reported error \n"
|
||||
"was '%s' (errno %d)."),
|
||||
dirname, g_strerror(errno) ? g_strerror(errno) : "", errno);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
/* On Windows only write permission will be checked.
|
||||
* So strictly speaking we'd need two error messages here depending
|
||||
* on the platform. For simplicity this detail is glossed over though. */
|
||||
if ((perms & bfs::owner_all) != bfs::owner_all)
|
||||
throw (bfs::filesystem_error(
|
||||
std::string(_("Insufficient permissions, at least write and access permissions required: "))
|
||||
+ dirname.c_str(), dirname,
|
||||
bst::error_code(bst::errc::permission_denied, bst::generic_category())));
|
||||
|
||||
if ((statbuf.st_mode & S_IFDIR) != S_IFDIR)
|
||||
{
|
||||
*msg = g_strdup_printf(
|
||||
_("The path\n"
|
||||
" %s\n"
|
||||
"exists but it is not a directory. Please delete\n"
|
||||
"the file and start GnuCash again.\n"),
|
||||
dirname);
|
||||
return FALSE;
|
||||
}
|
||||
#ifndef G_OS_WIN32
|
||||
/* The mode argument is ignored on windows anyway */
|
||||
if ((statbuf.st_mode & S_IRWXU) != S_IRWXU)
|
||||
{
|
||||
*msg = g_strdup_printf(
|
||||
_("The permissions are wrong on the directory\n"
|
||||
" %s\n"
|
||||
"They must be at least 'rwx' for the user.\n"),
|
||||
dirname);
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @fn const gchar * gnc_dotgnucash_dir ()
|
||||
static auto usr_conf_dir = bfs::path();
|
||||
|
||||
static void
|
||||
gnc_filepath_init()
|
||||
{
|
||||
auto try_home_dir = true;
|
||||
auto env_var = g_getenv("GNC_DOT_DIR");
|
||||
if (env_var)
|
||||
usr_conf_dir = env_var;
|
||||
|
||||
if (!usr_conf_dir.empty())
|
||||
{
|
||||
try
|
||||
{
|
||||
gnc_validate_directory(usr_conf_dir, true);
|
||||
try_home_dir = false;
|
||||
}
|
||||
catch (const bfs::filesystem_error& ex)
|
||||
{
|
||||
g_warning("%s is not a suitable base directory for the user configuration."
|
||||
"Trying home directory instead.\nThe failure is\n%s",
|
||||
usr_conf_dir.c_str(), ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
if (try_home_dir)
|
||||
{
|
||||
usr_conf_dir = g_get_home_dir();
|
||||
try
|
||||
{
|
||||
if (!gnc_validate_directory(usr_conf_dir, false))
|
||||
usr_conf_dir = g_get_tmp_dir();
|
||||
}
|
||||
catch (const bfs::filesystem_error& ex)
|
||||
{
|
||||
g_warning("Cannot find suitable home directory. Using tmp directory instead.\n"
|
||||
"The failure is\n%s", ex.what());
|
||||
usr_conf_dir = g_get_tmp_dir();
|
||||
}
|
||||
}
|
||||
g_assert(!usr_conf_dir.empty());
|
||||
|
||||
usr_conf_dir /= ".gnucash";
|
||||
|
||||
if (!gnc_validate_directory(usr_conf_dir, true))
|
||||
{
|
||||
g_warning("Cannot find suitable .gnucash directory in home directory. Using tmp directory instead.");
|
||||
|
||||
usr_conf_dir = g_get_tmp_dir();
|
||||
g_assert(!usr_conf_dir.empty());
|
||||
usr_conf_dir /= ".gnucash";
|
||||
/* This may throw and end the program! */
|
||||
gnc_validate_directory(usr_conf_dir, true);
|
||||
}
|
||||
|
||||
/* Since we're in code that is only executed once....
|
||||
* Note these calls may throw and end the program! */
|
||||
gnc_validate_directory(usr_conf_dir / "books", true);
|
||||
gnc_validate_directory(usr_conf_dir / "checks", true);
|
||||
gnc_validate_directory(usr_conf_dir / "translog", true);
|
||||
}
|
||||
|
||||
/** @fn const gchar * gnc_userdata_dir ()
|
||||
* @brief Ensure that the user's configuration directory exists and is minimally populated.
|
||||
*
|
||||
* Note that the default path is $HOME/.gnucash; This can be changed
|
||||
* by the environment variable $GNC_DOT_DIR.
|
||||
*
|
||||
* @return An absolute path to the configuration directory
|
||||
* @return An absolute path to the configuration directory. This string is
|
||||
* by the gnc_filepath_utils code and should not be freed by the user.
|
||||
*/
|
||||
const gchar *
|
||||
gnc_dotgnucash_dir (void)
|
||||
gnc_userdata_dir (void)
|
||||
{
|
||||
static gchar *dotgnucash = NULL;
|
||||
gchar *tmp_dir;
|
||||
gchar *errmsg = NULL;
|
||||
if (usr_conf_dir.empty())
|
||||
gnc_filepath_init();
|
||||
|
||||
if (dotgnucash)
|
||||
return dotgnucash;
|
||||
|
||||
dotgnucash = g_strdup(g_getenv("GNC_DOT_DIR"));
|
||||
|
||||
if (!dotgnucash)
|
||||
{
|
||||
const gchar *home = g_get_home_dir();
|
||||
if (!home || !gnc_validate_directory(home, FALSE, &errmsg))
|
||||
{
|
||||
g_free(errmsg);
|
||||
g_warning("Cannot find suitable home directory. Using tmp directory instead.");
|
||||
home = g_get_tmp_dir();
|
||||
}
|
||||
g_assert(home);
|
||||
|
||||
dotgnucash = g_build_filename(home, ".gnucash", (gchar *)NULL);
|
||||
}
|
||||
if (!gnc_validate_directory(dotgnucash, TRUE, &errmsg))
|
||||
{
|
||||
const gchar *tmp = g_get_tmp_dir();
|
||||
g_free(errmsg);
|
||||
g_free(dotgnucash);
|
||||
g_warning("Cannot find suitable .gnucash directory in home directory. Using tmp directory instead.");
|
||||
g_assert(tmp);
|
||||
|
||||
dotgnucash = g_build_filename(tmp, ".gnucash", (gchar *)NULL);
|
||||
|
||||
if (!gnc_validate_directory(dotgnucash, TRUE, &errmsg))
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Since we're in code that is only executed once.... */
|
||||
tmp_dir = g_build_filename(dotgnucash, "books", (gchar *)NULL);
|
||||
if (!gnc_validate_directory(tmp_dir, TRUE, &errmsg))
|
||||
exit(1);
|
||||
g_free(tmp_dir);
|
||||
tmp_dir = g_build_filename(dotgnucash, "checks", (gchar *)NULL);
|
||||
if (!gnc_validate_directory(tmp_dir, TRUE, &errmsg))
|
||||
exit(1);
|
||||
g_free(tmp_dir);
|
||||
tmp_dir = g_build_filename(dotgnucash, "translog", (gchar *)NULL);
|
||||
if (!gnc_validate_directory(tmp_dir, TRUE, &errmsg))
|
||||
exit(1);
|
||||
g_free(tmp_dir);
|
||||
|
||||
return dotgnucash;
|
||||
return usr_conf_dir.c_str();
|
||||
}
|
||||
|
||||
/** @fn gchar * gnc_build_dotgnucash_path (const gchar *filename)
|
||||
static const bfs::path&
|
||||
gnc_userdata_dir_as_path (void)
|
||||
{
|
||||
if (usr_conf_dir.empty())
|
||||
gnc_filepath_init();
|
||||
|
||||
return usr_conf_dir;
|
||||
}
|
||||
|
||||
/** @fn gchar * gnc_build_userdata_path (const gchar *filename)
|
||||
* @brief Make a path to filename in the user's configuration directory.
|
||||
*
|
||||
* @param filename The name of the file
|
||||
*
|
||||
* @return An absolute path.
|
||||
* @return An absolute path. The returned string should be freed by the user
|
||||
* using g_free().
|
||||
*/
|
||||
|
||||
gchar *
|
||||
gnc_build_dotgnucash_path (const gchar *filename)
|
||||
gnc_build_userdata_path (const gchar *filename)
|
||||
{
|
||||
return g_build_filename(gnc_dotgnucash_dir(), filename, (gchar *)NULL);
|
||||
return g_strdup((gnc_userdata_dir_as_path() / filename).c_str());
|
||||
}
|
||||
|
||||
static bfs::path
|
||||
gnc_build_userdata_subdir_path (const gchar *subdir, const gchar *filename)
|
||||
{
|
||||
gchar* filename_dup = g_strdup(filename);
|
||||
|
||||
scrub_filename(filename_dup);
|
||||
auto result = (gnc_userdata_dir_as_path() / subdir) / filename_dup;
|
||||
g_free(filename_dup);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @fn gchar * gnc_build_book_path (const gchar *filename)
|
||||
@ -483,20 +456,14 @@ gnc_build_dotgnucash_path (const gchar *filename)
|
||||
*
|
||||
* @param filename The name of the file
|
||||
*
|
||||
* @return An absolute path.
|
||||
* @return An absolute path. The returned string should be freed by the user
|
||||
* using g_free().
|
||||
*/
|
||||
|
||||
gchar *
|
||||
gnc_build_book_path (const gchar *filename)
|
||||
{
|
||||
gchar* filename_dup = g_strdup(filename);
|
||||
gchar* result = NULL;
|
||||
|
||||
scrub_filename(filename_dup);
|
||||
result = g_build_filename(gnc_dotgnucash_dir(), "books",
|
||||
filename_dup, (gchar *)NULL);
|
||||
g_free(filename_dup);
|
||||
return result;
|
||||
return g_strdup(gnc_build_userdata_subdir_path("books", filename).c_str());
|
||||
}
|
||||
|
||||
/** @fn gchar * gnc_build_translog_path (const gchar *filename)
|
||||
@ -504,20 +471,14 @@ gnc_build_book_path (const gchar *filename)
|
||||
*
|
||||
* @param filename The name of the file
|
||||
*
|
||||
* @return An absolute path.
|
||||
* @return An absolute path. The returned string should be freed by the user
|
||||
* using g_free().
|
||||
*/
|
||||
|
||||
gchar *
|
||||
gnc_build_translog_path (const gchar *filename)
|
||||
{
|
||||
gchar* filename_dup = g_strdup(filename);
|
||||
gchar* result = NULL;
|
||||
|
||||
scrub_filename(filename_dup);
|
||||
result = g_build_filename(gnc_dotgnucash_dir(), "translog",
|
||||
filename_dup, (gchar *)NULL);
|
||||
g_free(filename_dup);
|
||||
return result;
|
||||
return g_strdup(gnc_build_userdata_subdir_path("translog", filename).c_str());
|
||||
}
|
||||
|
||||
/** @fn gchar * gnc_build_data_path (const gchar *filename)
|
||||
@ -525,19 +486,14 @@ gnc_build_translog_path (const gchar *filename)
|
||||
*
|
||||
* @param filename The name of the file
|
||||
*
|
||||
* @return An absolute path.
|
||||
* @return An absolute path. The returned string should be freed by the user
|
||||
* using g_free().
|
||||
*/
|
||||
|
||||
gchar *
|
||||
gnc_build_data_path (const gchar *filename)
|
||||
{
|
||||
gchar* filename_dup = g_strdup(filename);
|
||||
gchar* result;
|
||||
|
||||
scrub_filename(filename_dup);
|
||||
result = g_build_filename(gnc_dotgnucash_dir(), "data", filename_dup, (gchar *)NULL);
|
||||
g_free(filename_dup);
|
||||
return result;
|
||||
return g_strdup(gnc_build_userdata_subdir_path("data", filename).c_str());
|
||||
}
|
||||
|
||||
/** @fn gchar * gnc_build_report_path (const gchar *filename)
|
||||
@ -545,7 +501,8 @@ gnc_build_data_path (const gchar *filename)
|
||||
*
|
||||
* @param filename The name of the file
|
||||
*
|
||||
* @return An absolute path.
|
||||
* @return An absolute path. The returned string should be freed by the user
|
||||
* using g_free().
|
||||
*/
|
||||
|
||||
gchar *
|
||||
@ -560,7 +517,8 @@ gnc_build_report_path (const gchar *filename)
|
||||
*
|
||||
* @param filename The name of the file
|
||||
*
|
||||
* @return An absolute path.
|
||||
* @return An absolute path. The returned string should be freed by the user
|
||||
* using g_free().
|
||||
*/
|
||||
|
||||
gchar *
|
@ -75,8 +75,8 @@ gchar *gnc_resolve_file_path (const gchar *filefrag);
|
||||
*/
|
||||
gchar *gnc_path_find_localized_html_file (const gchar *file_name);
|
||||
|
||||
const gchar *gnc_dotgnucash_dir (void);
|
||||
gchar *gnc_build_dotgnucash_path (const gchar *filename);
|
||||
const gchar *gnc_userdata_dir (void);
|
||||
gchar *gnc_build_userdata_path (const gchar *filename);
|
||||
gchar *gnc_build_book_path (const gchar *filename);
|
||||
gchar *gnc_build_translog_path (const gchar *filename);
|
||||
gchar *gnc_build_data_path (const gchar *filename);
|
||||
|
@ -14,5 +14,8 @@ ENDMACRO()
|
||||
|
||||
ADD_CORE_UTILS_TEST(test-gnc-glib-utils test-gnc-glib-utils.c)
|
||||
ADD_CORE_UTILS_TEST(test-resolve-file-path test-resolve-file-path.c)
|
||||
ADD_CORE_UTILS_TEST(test-usr-conf-dir test-usr-conf-dir.c)
|
||||
ADD_CORE_UTILS_TEST(test-usr-conf-dir-invalid-home test-usr-conf-dir-invalid-home.c)
|
||||
|
||||
SET_DIST_LIST(test_core_utils_DIST CMakeLists.txt Makefile.am test-gnc-glib-utils.c test-resolve-file-path.c)
|
||||
SET_DIST_LIST(test_core_utils_DIST CMakeLists.txt Makefile.am test-gnc-glib-utils.c
|
||||
test-resolve-file-path.c test-usr-conf-dir.c test-usr-conf-dir-invalid-home.c)
|
||||
|
@ -10,20 +10,24 @@ AM_CPPFLAGS = \
|
||||
-I${top_srcdir}/libgnucash/core-utils \
|
||||
-I${top_srcdir}/libgnucash/engine \
|
||||
${GUILE_CFLAGS} \
|
||||
${GLIB_CFLAGS}
|
||||
${GLIB_CFLAGS} \
|
||||
$(BOOST_CPPFLAGS)
|
||||
|
||||
LDADD = \
|
||||
../libgnc-core-utils.la \
|
||||
${top_builddir}/common/test-core/libtest-core.la \
|
||||
${GLIB_LIBS}
|
||||
${GLIB_LIBS} \
|
||||
${BOOST_LDFLAGS}
|
||||
|
||||
# these tests are ordered kind more or less in the order
|
||||
# that they should be executed, with more basic tests coming first.
|
||||
#
|
||||
|
||||
TESTS = \
|
||||
test-gnc-glib-utils \
|
||||
test-resolve-file-path \
|
||||
test-gnc-glib-utils
|
||||
test-usr-conf-dir \
|
||||
test-usr-conf-dir-invalid-home
|
||||
|
||||
GNC_TEST_DEPS = \
|
||||
--library-dir ${top_builddir}/libgnucash/core-utils
|
||||
|
@ -29,16 +29,16 @@
|
||||
#include "test-stuff.h"
|
||||
#include "gnc-filepath-utils.h"
|
||||
|
||||
struct test_strings_struct
|
||||
struct relpath_strings_struct
|
||||
{
|
||||
char *input;
|
||||
char *output;
|
||||
int prefix_home;
|
||||
};
|
||||
|
||||
typedef struct test_strings_struct test_strings;
|
||||
typedef struct relpath_strings_struct relpath_strings;
|
||||
|
||||
test_strings strs[] =
|
||||
relpath_strings strs[] =
|
||||
{
|
||||
{
|
||||
G_DIR_SEPARATOR_S ".gnucash" G_DIR_SEPARATOR_S "test-account-name",
|
||||
@ -57,6 +57,18 @@ int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
char *home_dir = NULL;
|
||||
|
||||
if (argc > 1)
|
||||
/* One can pass a homedir on the command line. This
|
||||
* will most likely cause the test to fail, but it can be
|
||||
* used to pass invalid home directories manually. The
|
||||
* test error messages should then show the system's temporary
|
||||
* directory to be used instead */
|
||||
home_dir = argv[1];
|
||||
else
|
||||
/* Set up a fake home directory to play with */
|
||||
home_dir = g_dir_make_tmp("gnucashXXXXXX", NULL);
|
||||
|
||||
for (i = 0; strs[i].input != NULL; i++)
|
||||
{
|
||||
@ -66,15 +78,15 @@ main(int argc, char **argv)
|
||||
|
||||
if (strs[i].prefix_home == 1)
|
||||
{
|
||||
dain = g_build_filename(g_get_home_dir(), strs[i].input,
|
||||
dain = g_build_filename(home_dir, strs[i].input,
|
||||
(gchar *)NULL);
|
||||
wantout = g_build_filename(g_get_home_dir(), strs[i].output,
|
||||
wantout = g_build_filename(home_dir, strs[i].output,
|
||||
(gchar *)NULL);
|
||||
}
|
||||
else if (strs[i].prefix_home == 2)
|
||||
{
|
||||
dain = g_strdup(strs[i].input);
|
||||
wantout = g_build_filename(g_get_home_dir(), strs[i].output,
|
||||
wantout = g_build_filename(home_dir, strs[i].output,
|
||||
(gchar *)NULL);
|
||||
}
|
||||
else
|
||||
@ -92,6 +104,7 @@ main(int argc, char **argv)
|
||||
g_free(wantout);
|
||||
g_free(daout);
|
||||
}
|
||||
|
||||
print_test_results();
|
||||
return get_rv();
|
||||
}
|
||||
|
110
libgnucash/core-utils/test/test-usr-conf-dir-invalid-home.c
Normal file
110
libgnucash/core-utils/test/test-usr-conf-dir-invalid-home.c
Normal file
@ -0,0 +1,110 @@
|
||||
/***************************************************************************
|
||||
* test-resolve-file-path.c
|
||||
*
|
||||
* Thu Sep 29 22:48:57 2005
|
||||
* Copyright 2005 GnuCash team
|
||||
****************************************************************************/
|
||||
/*
|
||||
* This program 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include "test-stuff.h"
|
||||
#include "gnc-filepath-utils.h"
|
||||
|
||||
struct usr_confpath_strings_struct
|
||||
{
|
||||
int func_num;
|
||||
char *funcname;
|
||||
char *output;
|
||||
};
|
||||
|
||||
typedef struct usr_confpath_strings_struct usr_confpath_strings;
|
||||
|
||||
usr_confpath_strings strs2[] =
|
||||
{
|
||||
{
|
||||
0, "gnc_build_userdata_path",
|
||||
".gnucash"
|
||||
},
|
||||
{
|
||||
1, "gnc_build_book_path",
|
||||
".gnucash" G_DIR_SEPARATOR_S "books"
|
||||
},
|
||||
{
|
||||
2, "gnc_build_translog_path",
|
||||
".gnucash" G_DIR_SEPARATOR_S "translog"
|
||||
},
|
||||
{
|
||||
3, "gnc_build_data_path",
|
||||
".gnucash" G_DIR_SEPARATOR_S "data"
|
||||
},
|
||||
{ 0, NULL, NULL },
|
||||
};
|
||||
|
||||
int
|
||||
main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
|
||||
{
|
||||
int i;
|
||||
const char *tmp_dir = g_get_tmp_dir();
|
||||
|
||||
/* Run usr conf dir tests with a valid and writable homedir */
|
||||
g_setenv("HOME", "/notexist", TRUE);
|
||||
for (i = 0; strs2[i].funcname != NULL; i++)
|
||||
{
|
||||
char *daout;
|
||||
char *wantout;
|
||||
|
||||
if (strs2[i].func_num == 0)
|
||||
{
|
||||
wantout = g_build_filename(tmp_dir, strs2[i].output, "foo",
|
||||
(gchar *)NULL);
|
||||
daout = gnc_build_userdata_path("foo");
|
||||
}
|
||||
else if (strs2[i].func_num == 1)
|
||||
{
|
||||
wantout = g_build_filename(tmp_dir, strs2[i].output, "foo",
|
||||
(gchar *)NULL);
|
||||
daout = gnc_build_book_path("foo");
|
||||
}
|
||||
else if (strs2[i].func_num == 2)
|
||||
{
|
||||
wantout = g_build_filename(tmp_dir, strs2[i].output, "foo",
|
||||
(gchar *)NULL);
|
||||
daout = gnc_build_translog_path("foo");
|
||||
}
|
||||
else // if (strs2[i].prefix_home == 3)
|
||||
{
|
||||
wantout = g_build_filename(tmp_dir, strs2[i].output, "foo",
|
||||
(gchar *)NULL);
|
||||
daout = gnc_build_data_path("foo");
|
||||
}
|
||||
|
||||
do_test_args(g_strcmp0(daout, wantout) == 0,
|
||||
"gnc_build_x_path",
|
||||
__FILE__, __LINE__,
|
||||
"%s (%s) vs %s", daout, strs2[i].funcname, wantout);
|
||||
g_free(wantout);
|
||||
g_free(daout);
|
||||
}
|
||||
|
||||
print_test_results();
|
||||
return get_rv();
|
||||
}
|
121
libgnucash/core-utils/test/test-usr-conf-dir.c
Normal file
121
libgnucash/core-utils/test/test-usr-conf-dir.c
Normal file
@ -0,0 +1,121 @@
|
||||
/***************************************************************************
|
||||
* test-resolve-file-path.c
|
||||
*
|
||||
* Thu Sep 29 22:48:57 2005
|
||||
* Copyright 2005 GnuCash team
|
||||
****************************************************************************/
|
||||
/*
|
||||
* This program 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include "test-stuff.h"
|
||||
#include "gnc-filepath-utils.h"
|
||||
|
||||
struct usr_confpath_strings_struct
|
||||
{
|
||||
int func_num;
|
||||
char *funcname;
|
||||
char *output;
|
||||
};
|
||||
|
||||
typedef struct usr_confpath_strings_struct usr_confpath_strings;
|
||||
|
||||
usr_confpath_strings strs2[] =
|
||||
{
|
||||
{
|
||||
0, "gnc_build_userdata_path",
|
||||
".gnucash"
|
||||
},
|
||||
{
|
||||
1, "gnc_build_book_path",
|
||||
".gnucash" G_DIR_SEPARATOR_S "books"
|
||||
},
|
||||
{
|
||||
2, "gnc_build_translog_path",
|
||||
".gnucash" G_DIR_SEPARATOR_S "translog"
|
||||
},
|
||||
{
|
||||
3, "gnc_build_data_path",
|
||||
".gnucash" G_DIR_SEPARATOR_S "data"
|
||||
},
|
||||
{ 0, NULL, NULL },
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
char *home_dir = NULL;
|
||||
|
||||
if (argc > 1)
|
||||
/* One can pass a homedir on the command line. This
|
||||
* will most likely cause the test to fail, but it can be
|
||||
* used to pass invalid home directories manually. The
|
||||
* test error messages should then show the system's temporary
|
||||
* directory to be used instead */
|
||||
home_dir = argv[1];
|
||||
else
|
||||
/* Set up a fake home directory to play with */
|
||||
home_dir = g_dir_make_tmp("gnucashXXXXXX", NULL);
|
||||
|
||||
/* Run usr conf dir tests with a valid and writable homedir */
|
||||
g_setenv("HOME", home_dir, TRUE);
|
||||
for (i = 0; strs2[i].funcname != NULL; i++)
|
||||
{
|
||||
char *daout;
|
||||
char *wantout;
|
||||
|
||||
if (strs2[i].func_num == 0)
|
||||
{
|
||||
wantout = g_build_filename(home_dir, strs2[i].output, "foo",
|
||||
(gchar *)NULL);
|
||||
daout = gnc_build_userdata_path("foo");
|
||||
}
|
||||
else if (strs2[i].func_num == 1)
|
||||
{
|
||||
wantout = g_build_filename(home_dir, strs2[i].output, "foo",
|
||||
(gchar *)NULL);
|
||||
daout = gnc_build_book_path("foo");
|
||||
}
|
||||
else if (strs2[i].func_num == 2)
|
||||
{
|
||||
wantout = g_build_filename(home_dir, strs2[i].output, "foo",
|
||||
(gchar *)NULL);
|
||||
daout = gnc_build_translog_path("foo");
|
||||
}
|
||||
else // if (strs2[i].prefix_home == 3)
|
||||
{
|
||||
wantout = g_build_filename(home_dir, strs2[i].output, "foo",
|
||||
(gchar *)NULL);
|
||||
daout = gnc_build_data_path("foo");
|
||||
}
|
||||
|
||||
do_test_args(g_strcmp0(daout, wantout) == 0,
|
||||
"gnc_build_x_path",
|
||||
__FILE__, __LINE__,
|
||||
"%s (%s) vs %s", daout, strs2[i].funcname, wantout);
|
||||
g_free(wantout);
|
||||
g_free(daout);
|
||||
}
|
||||
|
||||
print_test_results();
|
||||
return get_rv();
|
||||
}
|
@ -598,7 +598,7 @@ libgnucash/backend/xml/sixtp-utils.cpp
|
||||
libgnucash/core-utils/binreloc.c
|
||||
libgnucash/core-utils/core-utils.scm
|
||||
libgnucash/core-utils/gnc-environment.c
|
||||
libgnucash/core-utils/gnc-filepath-utils.c
|
||||
libgnucash/core-utils/gnc-filepath-utils.cpp
|
||||
libgnucash/core-utils/gnc-gkeyfile-utils.c
|
||||
libgnucash/core-utils/gnc-glib-utils.c
|
||||
libgnucash/core-utils/gnc-guile-utils.c
|
||||
|
Loading…
Reference in New Issue
Block a user