r22637 - gnucash/trunk/src - Rewrite gncFindFile function in C and move it to file-utils.

Geert Janssens gjanssens at code.gnucash.org
Wed Dec 12 12:42:23 EST 2012


Author: gjanssens
Date: 2012-12-12 12:42:22 -0500 (Wed, 12 Dec 2012)
New Revision: 22637
Trac: http://svn.gnucash.org/trac/changeset/22637

Modified:
   gnucash/trunk/src/app-utils/file-utils.c
   gnucash/trunk/src/app-utils/file-utils.h
   gnucash/trunk/src/core-utils/gnc-filepath-utils.c
   gnucash/trunk/src/core-utils/gnc-filepath-utils.h
Log:
Rewrite gncFindFile function in C and move it to file-utils.

The code made a roundtrip into guile (for historical reasons I guess).
The guile code used to be able to provide custom paths to search for
based on some command line parameter set at startup. This parameter
is no longer accepted since a very long time back.

Also note that the gncFindFile function is not actively in use. It is
only called by gncReadFile, which in turn is only called when our html
code is asked to load a generic file or a help file to stream (protocol
file or help). Both protocols are used nowhere in the current GnuCash
code.

gncFindFile (now gnc_path_find_localized_html_file) is only kept for
a. custom reports that potentially use the file protocol
b. jqplot which uses the guile equivalent of this function
   (see a subsequent commit)

Modified: gnucash/trunk/src/app-utils/file-utils.c
===================================================================
--- gnucash/trunk/src/app-utils/file-utils.c	2012-12-12 17:42:10 UTC (rev 22636)
+++ gnucash/trunk/src/app-utils/file-utils.c	2012-12-12 17:42:22 UTC (rev 22637)
@@ -23,7 +23,6 @@
 
 #include <glib.h>
 #include <glib/gstdio.h>
-#include <libguile.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <string.h>
@@ -38,7 +37,6 @@
 # define read _read
 #endif
 
-#include "guile-mappings.h"
 #include "file-utils.h"
 #include "gnc-engine.h"
 #include "gnc-filepath-utils.h"
@@ -51,34 +49,6 @@
 /********************************************************************\
 \********************************************************************/
 
-char *
-gncFindFile (const char * filename)
-{
-    char *full_filename = NULL;
-    char * return_string = NULL;
-    SCM find_doc_file;
-    SCM scm_filename;
-    SCM scm_result;
-
-    if (!filename || *filename == '\0')
-        return NULL;
-
-    find_doc_file = scm_c_eval_string("gnc:find-doc-file");
-    scm_filename = scm_makfrom0str ((char *) filename);
-    scm_result = scm_call_1(find_doc_file, scm_filename);
-
-    if (scm_is_string(scm_result))
-    {
-        scm_dynwind_begin (0);
-        full_filename = scm_to_locale_string(scm_result);
-        return_string = g_strdup (full_filename);
-        scm_dynwind_free (full_filename);
-        scm_dynwind_end ();
-    }
-
-    return return_string;
-}
-
 /********************************************************************\
  * gncReadFile                                                      *
  *                                                                  *
@@ -95,14 +65,10 @@
     int   size = 0;
     int   fd;
 
-    /* construct absolute path -- twiddle the relative path we received */
     if (!filename || filename[0] == '\0') return 0;
 
-    /* take absolute paths without searching */
-    if (!g_path_is_absolute (filename))
-        fullname = gncFindFile (filename);
-    else
-        fullname = g_strdup (filename);
+    /* construct absolute path if we received a relative path */
+    fullname = gnc_path_find_localized_html_file (filename);
 
     if (!fullname) return 0;
 

Modified: gnucash/trunk/src/app-utils/file-utils.h
===================================================================
--- gnucash/trunk/src/app-utils/file-utils.h	2012-12-12 17:42:10 UTC (rev 22636)
+++ gnucash/trunk/src/app-utils/file-utils.h	2012-12-12 17:42:22 UTC (rev 22637)
@@ -45,21 +45,6 @@
 
 #include <stdio.h>		/* for FILE* */
 
-/** Locates a file in the search path of the program and
- * returns its absolute pathname.
- *
- * If the file is not found
- * this function will return NULL.
- *
- *  Uses the global xxxPath as the path to search
- *
- * @param filename The filename to search
- *
- * @return The absolute path to the file or NULL if the file
- * wasn't found.
- */
-char * gncFindFile (const char * filename);
-
 /** Reads the contents of a file into a buffer for further processing.
  *
  *  If the filename is not an absolute filename, it will be searched

Modified: gnucash/trunk/src/core-utils/gnc-filepath-utils.c
===================================================================
--- gnucash/trunk/src/core-utils/gnc-filepath-utils.c	2012-12-12 17:42:10 UTC (rev 22636)
+++ gnucash/trunk/src/core-utils/gnc-filepath-utils.c	2012-12-12 17:42:22 UTC (rev 22637)
@@ -171,6 +171,117 @@
 
 }
 
+/* Searches for a file fragment paths set via GNC_DOC_PATH environment
+ * variable. If this variable is not set, fall back to search in
+ * - a html directory in the local user's gnucash settings directory
+ *   (typically $HOME/.gnucash/html)
+ * - the gnucash documentation directory
+ *   (typically /usr/share/doc/gnucash)
+ * It searches in this order.
+ *
+ * This is used by gnc_path_find_localized_file to search for
+ * localized versions of files if they exist.
+ */
+static gchar *
+gnc_path_find_localized_html_file_internal (const gchar * file_name)
+{
+    gchar *full_path = NULL;
+    int i;
+    const gchar *env_doc_path = g_getenv("GNC_DOC_PATH");
+    const gchar *default_dirs[] =
+        {
+            gnc_build_dotgnucash_path ("html"),
+            gnc_path_get_pkgdocdir (),
+            NULL
+        };
+    gchar **dirs;
+
+    if (!file_name || *file_name == '\0')
+        return NULL;
+
+    /* Allow search path override via GNC_DOC_PATH environment variable */
+    if (env_doc_path)
+        dirs = g_strsplit (env_doc_path, G_SEARCHPATH_SEPARATOR_S, -1);
+    else
+        dirs = (gchar **)default_dirs;
+
+    for (i = 0; dirs[i]; i++)
+    {
+        full_path = g_build_filename (dirs[1], file_name, (gchar *)NULL);
+        full_path = check_path_return_if_valid (full_path);
+        if (full_path != NULL)
+            return full_path;
+    }
+
+    return NULL;
+}
+
+/** @brief Find an absolute path to a localized version of a given
+ *  relative path to a html or html related file.
+ *  If no localized version exists, an absolute path to the file
+ *  is searched for. If that file doesn't exist either, returns NULL.
+ *
+ *  @warning file_name should be a simple path fragment. It shouldn't
+ *  contain xml:// or http:// or <whatever>:// other protocol specifiers.
+ *
+ *  If passed a string which g_path_is_absolute declares an absolute
+ *  path, return the argument.
+ *
+ *  Otherwise, assume that file_name is a well-formed relative path and
+ *  try to find a file with its path relative to
+ *  \li a localized subdirectory in the html directory
+ *      of the user's configuration directory
+ *      (e.g. $HOME/.gnucash/html/de_DE, $HOME/.gnucash/html/en,...)
+ *  \li a localized subdirectory in the gnucash documentation directory
+ *      (e.g. /usr/share/doc/gnucash/C,...)
+ *  \li the html directory of the user's configuration directory
+ *      (e.g. $HOME/.gnucash/html)
+ *  \li the gnucash documentation directory
+ *      (e.g. /usr/share/doc/gnucash/)
+ *
+ *  The paths are searched for in that order. If a matching file is
+ *  found, return the absolute path to it.
+
+ *  If one isn't found, return NULL.
+ *
+ *  @param file_name The file path to resolve
+ *
+ *  @return An absolute file path or NULL if no file is found.
+ */
+gchar *
+gnc_path_find_localized_html_file (const gchar *file_name)
+{
+    gchar *loc_file_name = NULL;
+    gchar *full_path = NULL;
+    const gchar * const *lang;
+    int i;
+
+    if (!file_name || *file_name == '\0')
+        return NULL;
+
+    /* An absolute path is returned unmodified. */
+    if (g_path_is_absolute (file_name))
+        return g_strdup (file_name);
+
+    /* First try to find the file in any of the localized directories
+     * the user has set up on his system
+     */
+    for (lang = g_get_language_names (); *lang; lang++)
+    {
+        loc_file_name = g_build_filename (*lang, file_name, (gchar *)NULL);
+        full_path = gnc_path_find_localized_html_file_internal (loc_file_name);
+        g_free (loc_file_name);
+        if (full_path != NULL)
+            return full_path;
+    }
+
+    /* If not found in a localized directory, try to find the file
+     * in any of the base directories
+     */
+    full_path = gnc_path_find_localized_html_file_internal (file_name);
+    return full_path;
+}
+
 /* ====================================================================== */
 
 /** @brief Check that the supplied directory path exists, is a directory, and

Modified: gnucash/trunk/src/core-utils/gnc-filepath-utils.h
===================================================================
--- gnucash/trunk/src/core-utils/gnc-filepath-utils.h	2012-12-12 17:42:10 UTC (rev 22636)
+++ gnucash/trunk/src/core-utils/gnc-filepath-utils.h	2012-12-12 17:42:22 UTC (rev 22637)
@@ -41,6 +41,40 @@
  */
 gchar *gnc_resolve_file_path (const gchar *filefrag);
 
+/** @brief Find an absolute path to a localized version of a given
+ *  relative path to a html or html related file.
+ *  If no localized version exists, an absolute path to the file
+ *  is searched for. If that file doesn't exist either, returns NULL.
+ *
+ *  @warning file_name should be a simple path fragment. It shouldn't
+ *  contain xml:// or http:// or <whatever>:// other protocol specifiers.
+ *
+ *  If passed a string which g_path_is_absolute declares an absolute
+ *  path, return the argument.
+ *
+ *  Otherwise, assume that file_name is a well-formed relative path and
+ *  try to find a file with its path relative to
+ *  \li a localized subdirectory in the html directory
+ *      of the user's configuration directory
+ *      (e.g. $HOME/.gnucash/html/de_DE, $HOME/.gnucash/html/en,...)
+ *  \li a localized subdirectory in the gnucash documentation directory
+ *      (e.g. /usr/share/doc/gnucash/C,...)
+ *  \li the html directory of the user's configuration directory
+ *      (e.g. $HOME/.gnucash/html)
+ *  \li the gnucash documentation directory
+ *      (e.g. /usr/share/doc/gnucash/)
+ *
+ *  The paths are searched for in that order. If a matching file is
+ *  found, return the absolute path to it.
+
+ *  If one isn't found, return NULL.
+ *
+ *  @param file_name The file path to resolve
+ *
+ *  @return An absolute file path or NULL if no file is found.
+ */
+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);
 gchar *gnc_build_book_path (const gchar *filename);



More information about the gnucash-changes mailing list