r15787 - gnucash/trunk/src - Play nicer with recent releases of glib that have tightened what's
David Hampton
hampton at cvs.gnucash.org
Tue Apr 3 23:40:16 EDT 2007
Author: hampton
Date: 2007-04-03 23:40:14 -0400 (Tue, 03 Apr 2007)
New Revision: 15787
Trac: http://svn.gnucash.org/trac/changeset/15787
Modified:
gnucash/trunk/src/app-utils/file-utils.c
gnucash/trunk/src/app-utils/file-utils.h
gnucash/trunk/src/app-utils/gnc-exp-parser.c
gnucash/trunk/src/business/business-gnome/dialog-invoice.c
gnucash/trunk/src/core-utils/gnc-gkeyfile-utils.c
gnucash/trunk/src/core-utils/gnc-gkeyfile-utils.h
gnucash/trunk/src/gnome-utils/gnc-main-window.c
gnucash/trunk/src/gnome-utils/gnc-plugin-file-history.c
gnucash/trunk/src/gnome-utils/gnc-tree-view-account.c
gnucash/trunk/src/gnome/dialog-print-check.c
gnucash/trunk/src/gnome/gnc-plugin-page-register.c
gnucash/trunk/src/report/report-gnome/gnc-plugin-page-report.c
Log:
Play nicer with recent releases of glib that have tightened what's
considered a valid key in a key/value file. This change will cause
gnucash to rewrite any opened state file into a new version where all
key names fit the new glib requirements.
This code was originally committed to trunk as #15458 on 1/28/07, and
then backed out with #15461 on 1/29/07. Backward compatibility
support for this code was committed to the 2.0 branch in #15460 and
was released as part of 2.0.5. Now that 2.0.5 has now been out for
six weeks, this commit puts the original changes back into trunk.
Modified: gnucash/trunk/src/app-utils/file-utils.c
===================================================================
--- gnucash/trunk/src/app-utils/file-utils.c 2007-04-04 02:22:28 UTC (rev 15786)
+++ gnucash/trunk/src/app-utils/file-utils.c 2007-04-04 03:40:14 UTC (rev 15787)
@@ -23,6 +23,9 @@
#include <glib.h>
#include <glib/gstdio.h>
+#ifndef HAVE_GLIB_2_8
+#include <gfileutils-2.8.h>
+#endif
#include <libguile.h>
#include <errno.h>
#include <fcntl.h>
@@ -167,6 +170,63 @@
}
+/* Update one state file file to fit the new constraints introduced by
+ * glib 2.12.5. Supposedly its always been illegal to use spaces in
+ * key names, but it was never a problem with earlier releases of
+ * glib. Glib 2.12.5 added hard enforcement of this rule, completely
+ * ignoring any key/value pair where the key name contained an
+ * "illegal" character. Glib 2.12.7 relented and changed the hard
+ * failure to a warning, but the point has been made. Spaces in key
+ * names must go.
+ */
+static gboolean
+gnc_update_state_file_keys(const gchar *filename)
+{
+ const gchar *eol;
+ gchar *contents, **lines, *line, **kv, **parts, *part, *newkey;
+ GError *error = NULL;
+ int i, j;
+
+ if (!g_file_get_contents(filename, &contents, NULL, &error)) {
+ DEBUG("Error reading state file: %s", error->message);
+ g_error_free(error);
+ return FALSE;
+ }
+
+ lines = g_strsplit(contents, "\n", -1);
+ g_free(contents);
+
+ /* Strip spaces from non-comment lines, and rewrite the new text
+ * over top of the old text. The new line is guaranteed to be at
+ * most the same number of characters as the old. */
+ for (i = 0, line = lines[i++]; line; line = lines[i++]) {
+ if ((*line == '\0') || (*line == '#') || (*line == '[')) {
+ continue;
+ } else {
+ kv = g_strsplit(line, "=", 2);
+ parts = g_strsplit(kv[0], " ", -1);
+ for (j = 0, part = parts[j++]; part; part = parts[j++])
+ part[0] = g_ascii_toupper(part[0]);
+ newkey = g_strjoinv("", parts);
+ g_sprintf(line, "%s=%s", newkey, kv[1]);
+ g_free(newkey);
+ g_strfreev(parts);
+ g_strfreev(kv);
+ }
+ }
+
+ contents = g_strjoinv("\n", lines);
+ if (!g_file_set_contents(filename, contents, -1, &error)) {
+ DEBUG("Error writing state file: %s", error->message);
+ g_error_free(error);
+ g_free(contents);
+ return FALSE;
+ }
+
+ g_free(contents);
+ return TRUE;
+}
+
/* Find the state file that corresponds to this URL and guid. The
* URL is used to compute the base name of the file (which will be in
* ~/.gnucash/books) and the guid is used to differentiate when the
@@ -179,6 +239,7 @@
gchar *basename, *original = NULL, *filename, *tmp, *file_guid;
GKeyFile *key_file = NULL;
GError *error = NULL;
+ gboolean do_increment;
gint i;
ENTER("url %s, guid %s", url, guid);
@@ -199,9 +260,24 @@
else
filename = g_strdup_printf("%s_%d", original, i);
DEBUG("Trying %s", filename);
- key_file = gnc_key_file_load_from_file(filename, FALSE, FALSE);
+ key_file = gnc_key_file_load_from_file(filename, FALSE, FALSE, &error);
DEBUG("Result %p", key_file);
+ if (error &&
+ (error->domain == G_KEY_FILE_ERROR) &&
+ (error->code == G_KEY_FILE_ERROR_PARSE)) {
+ /* Handle the case where glib was updated first, and is refusing
+ * to read old state files. */
+ if (gnc_update_state_file_keys(filename)) {
+ DEBUG("Trying %s again", filename);
+ key_file = gnc_key_file_load_from_file(filename, FALSE, FALSE, NULL);
+ DEBUG("Result %p", key_file);
+ }
+ }
+ if (error) {
+ g_error_free(error);
+ error = NULL;
+ }
if (!key_file) {
DEBUG("No key file by that name");
break;
@@ -209,7 +285,7 @@
file_guid = g_key_file_get_string(key_file,
STATE_FILE_TOP, STATE_FILE_BOOK_GUID,
- &error);
+ NULL);
DEBUG("File GUID is %s", file_guid);
if (safe_strcmp(guid, file_guid) == 0) {
DEBUG("Matched !!!");
@@ -217,11 +293,26 @@
break;
}
+ /* Handle the case where gnucash was updated first, and is trying
+ * to find new key names in an old state files. */
+ file_guid = g_key_file_get_string(key_file,
+ STATE_FILE_TOP, STATE_FILE_BOOK_GUID_OLD,
+ NULL);
+ DEBUG("%s is %s", STATE_FILE_BOOK_GUID,
+ file_guid ? file_guid : "<not found>");
+ if (safe_strcmp(guid, file_guid) == 0) {
+ DEBUG("Matched !!!");
+ do_increment = !gnc_update_state_file_keys(filename);
+ } else {
+ do_increment = TRUE;
+ }
+
DEBUG("Clean up this pass");
g_free(file_guid);
g_key_file_free(key_file);
g_free(filename);
- i++;
+ if (do_increment)
+ i++;
}
DEBUG("Clean up");
Modified: gnucash/trunk/src/app-utils/file-utils.h
===================================================================
--- gnucash/trunk/src/app-utils/file-utils.h 2007-04-04 02:22:28 UTC (rev 15786)
+++ gnucash/trunk/src/app-utils/file-utils.h 2007-04-04 03:40:14 UTC (rev 15787)
@@ -60,8 +60,9 @@
/* Definitions shared by file-utils.c and gnc-main-window.c */
-#define STATE_FILE_TOP "Top"
-#define STATE_FILE_BOOK_GUID "Book Guid"
+#define STATE_FILE_TOP "Top"
+#define STATE_FILE_BOOK_GUID "BookGuid"
+#define STATE_FILE_BOOK_GUID_OLD "Book Guid"
/** Find the state file that corresponds to this URL and guid. The
* URL is used to compute the base name of the file (which will be in
Modified: gnucash/trunk/src/app-utils/gnc-exp-parser.c
===================================================================
--- gnucash/trunk/src/app-utils/gnc-exp-parser.c 2007-04-04 02:22:28 UTC (rev 15786)
+++ gnucash/trunk/src/app-utils/gnc-exp-parser.c 2007-04-04 03:40:14 UTC (rev 15787)
@@ -86,7 +86,7 @@
if ( addPredefined ) {
filename = gnc_exp_parser_filname();
- key_file = gnc_key_file_load_from_file(filename, TRUE, FALSE);
+ key_file = gnc_key_file_load_from_file(filename, TRUE, FALSE, NULL);
if (key_file) {
keys = g_key_file_get_keys(key_file, GROUP_NAME, NULL, NULL);
for (key = keys; key && *key; key++) {
Modified: gnucash/trunk/src/business/business-gnome/dialog-invoice.c
===================================================================
--- gnucash/trunk/src/business/business-gnome/dialog-invoice.c 2007-04-04 02:22:28 UTC (rev 15786)
+++ gnucash/trunk/src/business/business-gnome/dialog-invoice.c 2007-04-04 03:40:14 UTC (rev 15787)
@@ -1676,10 +1676,10 @@
return iw;
}
-#define KEY_INVOICE_TYPE "Invoice Type"
-#define KEY_INVOICE_GUID "Invoice GUID"
-#define KEY_OWNER_TYPE "Owner Type"
-#define KEY_OWNER_GUID "Owner GUID"
+#define KEY_INVOICE_TYPE "InvoiceType"
+#define KEY_INVOICE_GUID "InvoiceGUID"
+#define KEY_OWNER_TYPE "OwnerType"
+#define KEY_OWNER_GUID "OwnerGUID"
GncPluginPage *
gnc_invoice_recreate_page (GKeyFile *key_file,
Modified: gnucash/trunk/src/core-utils/gnc-gkeyfile-utils.c
===================================================================
--- gnucash/trunk/src/core-utils/gnc-gkeyfile-utils.c 2007-04-04 02:22:28 UTC (rev 15786)
+++ gnucash/trunk/src/core-utils/gnc-gkeyfile-utils.c 2007-04-04 03:40:14 UTC (rev 15787)
@@ -265,7 +265,8 @@
GKeyFile *
gnc_key_file_load_from_file (const gchar *filename,
gboolean ignore_error,
- gboolean return_empty_struct)
+ gboolean return_empty_struct,
+ GError **caller_error)
{
GKeyFile *key_file;
GError *error = NULL;
@@ -290,7 +291,7 @@
if (!ignore_error)
g_warning("Unable to read file %s: %s\n", filename, error->message);
- g_error_free(error);
+ g_propagate_error(caller_error, error);
return key_file;
}
Modified: gnucash/trunk/src/core-utils/gnc-gkeyfile-utils.h
===================================================================
--- gnucash/trunk/src/core-utils/gnc-gkeyfile-utils.h 2007-04-04 02:22:28 UTC (rev 15786)
+++ gnucash/trunk/src/core-utils/gnc-gkeyfile-utils.h 2007-04-04 03:40:14 UTC (rev 15787)
@@ -71,7 +71,8 @@
*/
GKeyFile *gnc_key_file_load_from_file (const gchar *file,
gboolean ignore_error,
- gboolean return_empty_struct);
+ gboolean return_empty_struct,
+ GError **caller_error);
/** Write a key/value file from memory to disk. If there is no data
Modified: gnucash/trunk/src/gnome/dialog-print-check.c
===================================================================
--- gnucash/trunk/src/gnome/dialog-print-check.c 2007-04-04 02:22:28 UTC (rev 15786)
+++ gnucash/trunk/src/gnome/dialog-print-check.c 2007-04-04 03:40:14 UTC (rev 15787)
@@ -1004,7 +1004,7 @@
check_format_t *format;
pathname = g_build_filename(dirname, file, (char *)NULL);
- key_file = gnc_key_file_load_from_file(pathname, FALSE, FALSE);
+ key_file = gnc_key_file_load_from_file(pathname, FALSE, FALSE, NULL);
g_free(pathname);
if (!key_file) {
g_warning("Check file %s, cannot load file", file);
Modified: gnucash/trunk/src/gnome/gnc-plugin-page-register.c
===================================================================
--- gnucash/trunk/src/gnome/gnc-plugin-page-register.c 2007-04-04 02:22:28 UTC (rev 15786)
+++ gnucash/trunk/src/gnome/gnc-plugin-page-register.c 2007-04-04 03:40:14 UTC (rev 15787)
@@ -831,10 +831,10 @@
NULL
};
-#define KEY_REGISTER_TYPE "Register Type"
-#define KEY_ACCOUNT_NAME "Account Name"
-#define KEY_REGISTER_STYLE "Register Style"
-#define KEY_DOUBLE_LINE "Double Line Mode"
+#define KEY_REGISTER_TYPE "RegisterType"
+#define KEY_ACCOUNT_NAME "AccountName"
+#define KEY_REGISTER_STYLE "RegisterStyle"
+#define KEY_DOUBLE_LINE "DoubleLineMode"
#define LABEL_ACCOUNT "Account"
#define LABEL_SUBACCOUNT "SubAccount"
Modified: gnucash/trunk/src/gnome-utils/gnc-main-window.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-main-window.c 2007-04-04 02:22:28 UTC (rev 15786)
+++ gnucash/trunk/src/gnome-utils/gnc-main-window.c 2007-04-04 03:40:14 UTC (rev 15787)
@@ -402,20 +402,20 @@
/************************************************************
* *
************************************************************/
-#define WINDOW_COUNT "Window Count"
-#define WINDOW_STRING "Window %d"
-#define WINDOW_GEOMETRY "Window Geometry"
-#define WINDOW_POSITION "Window Position"
-#define WINDOW_MAXIMIZED "Window Maximized"
-#define TOOLBAR_VISIBLE "Toolbar Visible"
-#define STATUSBAR_VISIBLE "Statusbar Visible"
-#define SUMMARYBAR_VISIBLE "Summarybar Visible"
-#define WINDOW_FIRSTPAGE "First Page"
-#define WINDOW_PAGECOUNT "Page Count"
-#define WINDOW_PAGEORDER "Page Order"
-#define PAGE_TYPE "Page Type"
-#define PAGE_NAME "Page Name"
-#define PAGE_STRING "Page %d"
+#define WINDOW_COUNT "WindowCount"
+#define WINDOW_STRING "Window %d"
+#define WINDOW_GEOMETRY "WindowGeometry"
+#define WINDOW_POSITION "WindowPosition"
+#define WINDOW_MAXIMIZED "WindowMaximized"
+#define TOOLBAR_VISIBLE "ToolbarVisible"
+#define STATUSBAR_VISIBLE "StatusbarVisible"
+#define SUMMARYBAR_VISIBLE "SummarybarVisible"
+#define WINDOW_FIRSTPAGE "FirstPage"
+#define WINDOW_PAGECOUNT "PageCount"
+#define WINDOW_PAGEORDER "PageOrder"
+#define PAGE_TYPE "PageType"
+#define PAGE_NAME "PageName"
+#define PAGE_STRING "Page %d"
typedef struct {
GKeyFile *key_file;
Modified: gnucash/trunk/src/gnome-utils/gnc-plugin-file-history.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-plugin-file-history.c 2007-04-04 02:22:28 UTC (rev 15786)
+++ gnucash/trunk/src/gnome-utils/gnc-plugin-file-history.c 2007-04-04 03:40:14 UTC (rev 15787)
@@ -435,7 +435,7 @@
/* Copy the old values from the gnucash 1.x/gnome1 settings file to
* the gnucash 2.x/gconf settings area. */
mdi_file = g_build_filename(home, ".gnome", "GnuCash", (gchar *)NULL);
- keyfile = gnc_key_file_load_from_file (mdi_file, FALSE, FALSE);
+ keyfile = gnc_key_file_load_from_file (mdi_file, FALSE, FALSE, NULL);
if (keyfile) {
keys = g_key_file_get_keys(keyfile, GNOME1_HISTORY, NULL, NULL);
if (keys) {
Modified: gnucash/trunk/src/gnome-utils/gnc-tree-view-account.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-tree-view-account.c 2007-04-04 02:22:28 UTC (rev 15786)
+++ gnucash/trunk/src/gnome-utils/gnc-tree-view-account.c 2007-04-04 03:40:14 UTC (rev 15787)
@@ -1853,12 +1853,12 @@
LEAVE(" ");
}
-#define ACCT_COUNT "Number of Open Accounts"
-#define ACCT_OPEN "Open Account %d"
-#define ACCT_SELECTED "Selected Account"
-#define SHOW_HIDDEN "Show Hidden"
-#define SHOW_ZERO "Show Zero Total"
-#define ACCT_TYPES "Account Types"
+#define ACCT_COUNT "NumberOfOpenAccounts"
+#define ACCT_OPEN "OpenAccount%d"
+#define ACCT_SELECTED "SelectedAccount"
+#define SHOW_HIDDEN "ShowHidden"
+#define SHOW_ZERO "ShowZeroTotal"
+#define ACCT_TYPES "AccountTypes"
typedef struct foo {
GKeyFile *key_file;
Modified: gnucash/trunk/src/report/report-gnome/gnc-plugin-page-report.c
===================================================================
--- gnucash/trunk/src/report/report-gnome/gnc-plugin-page-report.c 2007-04-04 02:22:28 UTC (rev 15786)
+++ gnucash/trunk/src/report/report-gnome/gnc-plugin-page-report.c 2007-04-04 03:40:14 UTC (rev 15787)
@@ -649,8 +649,8 @@
/** The key name used it the state file for storing the report
* options. */
-#define SCHEME_OPTIONS "Scheme Options"
-#define SCHEME_OPTIONS_N "Scheme Options %d"
+#define SCHEME_OPTIONS "SchemeOptions"
+#define SCHEME_OPTIONS_N "SchemeOptions%d"
/** Save enough information about this report page that it can be
More information about the gnucash-changes
mailing list