[patch 6/8] [budget-persist.diff] Budget persistence for the file
backend
c.shoemaker at cox.net
c.shoemaker at cox.net
Sat Oct 15 00:18:33 EDT 2005
* src/backend/file/Makefile.am
* src/backend/file/gnc-budget-xml-v2.c
* src/backend/file/gnc-recurrence-xml-v2.c
* src/backend/file/gnc-xml.h
* src/backend/file/io-gncxml-v2.c
* src/backend/file/io-gncxml-v2.h
* src/backend/file/sixtp-dom-generators.c
* src/backend/file/sixtp-dom-generators.h
* src/backend/file/sixtp-dom-parsers.c
* src/backend/file/sixtp-dom-parsers.h
* src/backend/file/sixtp-utils.c
* src/backend/file/test/Makefile.am
- add Budget persistence for the file backend
* src/backend/file/sixtp-dom-generators.c
* src/backend/file/sixtp-dom-generators.h
- add 'const' qualifier to GDate pointer in gdate_to_dom_tree()
- reindent function
src/backend/file/Makefile.am | 2
src/backend/file/gnc-budget-xml-v2.c | 227 +++++++++++++++++++++++++++++++
src/backend/file/gnc-recurrence-xml-v2.c | 129 +++++++++++++++++
src/backend/file/gnc-xml.h | 4
src/backend/file/io-gncxml-v2.c | 74 +++++++++-
src/backend/file/io-gncxml-v2.h | 3
src/backend/file/sixtp-dom-generators.c | 50 +++---
src/backend/file/sixtp-dom-generators.h | 4
src/backend/file/sixtp-dom-parsers.c | 27 +++
src/backend/file/sixtp-dom-parsers.h | 6
src/backend/file/sixtp-utils.c | 3
src/backend/file/test/Makefile.am | 8 -
12 files changed, 500 insertions(+), 37 deletions(-)
Index: gnucash/src/backend/file/Makefile.am
===================================================================
--- gnucash.orig/src/backend/file/Makefile.am
+++ gnucash/src/backend/file/Makefile.am
@@ -18,10 +18,12 @@ libgnc_backend_file_la_SOURCES = \
gnc-account-xml-v2.c \
gnc-backend-file.c \
gnc-book-xml-v2.c \
+ gnc-budget-xml-v2.c \
gnc-commodity-xml-v2.c \
gnc-freqspec-xml-v2.c \
gnc-lot-xml-v2.c \
gnc-pricedb-xml-v2.c \
+ gnc-recurrence-xml-v2.c \
gnc-schedxaction-xml-v2.c \
gnc-transaction-xml-v2.c \
io-example-account.c \
Index: gnucash/src/backend/file/gnc-budget-xml-v2.c
===================================================================
--- /dev/null
+++ gnucash/src/backend/file/gnc-budget-xml-v2.c
@@ -0,0 +1,227 @@
+/********************************************************************\
+ * gnc-budget-xml-v2.c -- budget xml i/o implementation *
+ * *
+ * Copyright (C) 2005 Chris Shoemaker <c.shoemaker at cox.net> *
+ * *
+ * 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, contact: *
+ * *
+ * Free Software Foundation Voice: +1-617-542-5942 *
+ * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
+ * Boston, MA 02111-1307, USA gnu at gnu.org *
+ * *
+\********************************************************************/
+
+
+#include "config.h"
+
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gnc-xml-helper.h"
+#include "sixtp.h"
+#include "sixtp-utils.h"
+#include "sixtp-parsers.h"
+#include "sixtp-utils.h"
+#include "sixtp-dom-parsers.h"
+#include "sixtp-dom-generators.h"
+
+#include "gnc-xml.h"
+#include "io-gncxml-gen.h"
+#include "io-gncxml-v2.h"
+
+static QofLogModule log_module = GNC_MOD_IO;
+
+const gchar *budget_version_string = "2.0.0";
+
+/* ids */
+#define gnc_budget_string "gnc:budget"
+#define bgt_id_string "bgt:id"
+#define bgt_name_string "bgt:name"
+#define bgt_description_string "bgt:description"
+#define bgt_num_periods_string "bgt:num-periods"
+#define bgt_recurrence_string "bgt:recurrence"
+#define bgt_slots_string "bgt:slots"
+
+xmlNodePtr
+gnc_budget_dom_tree_create(GncBudget *bgt)
+{
+ xmlNodePtr ret;
+ KvpFrame *kf;
+
+ ENTER ("(budget=%p)", bgt);
+
+ ret = xmlNewNode(NULL, gnc_budget_string);
+ xmlSetProp(ret, "version", budget_version_string);
+
+ /* field: GUID */
+ xmlAddChild(ret, guid_to_dom_tree(bgt_id_string,
+ gnc_budget_get_guid(bgt)));
+ /* field: char* name */
+ xmlAddChild(ret, text_to_dom_tree(bgt_name_string,
+ gnc_budget_get_name(bgt)));
+ /* field: char* description */
+ xmlAddChild(ret, text_to_dom_tree(bgt_description_string,
+ gnc_budget_get_description(bgt)));
+ /* field: guint num_periods */
+ xmlAddChild(ret, guint_to_dom_tree(bgt_num_periods_string,
+ gnc_budget_get_num_periods(bgt)));
+ /* field: Recurrence* */
+ xmlAddChild(ret, recurrence_to_dom_tree(bgt_recurrence_string,
+ gnc_budget_get_recurrence(bgt)));
+ /* slots */
+ kf = qof_instance_get_slots(QOF_INSTANCE(bgt));
+ if (kf) {
+ xmlNodePtr kvpnode = kvp_frame_to_dom_tree(bgt_slots_string, kf);
+ if (kvpnode)
+ xmlAddChild(ret, kvpnode);
+ }
+
+ LEAVE (" ");
+ return ret;
+}
+
+/***********************************************************************/
+static inline gboolean
+set_string(xmlNodePtr node, GncBudget* bgt,
+ void (*func)(GncBudget *bgt, const gchar *txt))
+{
+ gchar* txt = dom_tree_to_text(node);
+ g_return_val_if_fail(txt, FALSE);
+
+ func(bgt, txt);
+ g_free(txt);
+ return TRUE;
+}
+
+static gboolean
+budget_id_handler (xmlNodePtr node, gpointer bgt)
+{
+ GUID *guid;
+
+ guid = dom_tree_to_guid(node);
+ g_return_val_if_fail(guid, FALSE);
+ qof_entity_set_guid(QOF_ENTITY(bgt), guid);
+ g_free(guid);
+ return TRUE;
+}
+
+static gboolean
+budget_name_handler (xmlNodePtr node, gpointer bgt)
+{
+ return set_string(node, GNC_BUDGET(bgt), gnc_budget_set_name);
+}
+
+static gboolean
+budget_description_handler (xmlNodePtr node, gpointer bgt)
+{
+ return set_string(node, GNC_BUDGET(bgt), gnc_budget_set_description);
+}
+
+static gboolean
+budget_num_periods_handler (xmlNodePtr node, gpointer bgt)
+{
+ guint num_periods;
+
+ if (dom_tree_to_guint(node, &num_periods)) {
+ gnc_budget_set_num_periods(GNC_BUDGET(bgt), num_periods);
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+static gboolean
+budget_recurrence_handler (xmlNodePtr node, gpointer bgt)
+{
+ Recurrence *r;
+
+ if ((r = dom_tree_to_recurrence(node)) == NULL)
+ return FALSE;
+
+ gnc_budget_set_recurrence(GNC_BUDGET(bgt), r);
+ g_free(r);
+ return TRUE;
+}
+
+static gboolean
+budget_slots_handler (xmlNodePtr node, gpointer bgt)
+{
+ return dom_tree_to_kvp_frame_given(
+ node, qof_instance_get_slots(QOF_INSTANCE(bgt)));
+}
+
+static struct dom_tree_handler budget_handlers[] = {
+ { bgt_id_string, budget_id_handler, 1, 0 },
+ { bgt_name_string, budget_name_handler, 0, 0 },
+ { bgt_description_string, budget_description_handler, 0, 0 },
+ { bgt_num_periods_string, budget_num_periods_handler, 1, 0 },
+ { bgt_recurrence_string, budget_recurrence_handler, 1, 0 },
+ { bgt_slots_string, budget_slots_handler, 0, 0},
+ { NULL, 0, 0, 0 }
+};
+
+static gboolean
+gnc_budget_end_handler(gpointer data_for_children,
+ GSList* data_from_children, GSList* sibling_data,
+ gpointer parent_data, gpointer global_data,
+ gpointer *result, const gchar *tag)
+{
+ GncBudget *bgt;
+ xmlNodePtr tree = (xmlNodePtr)data_for_children;
+ gxpf_data *gdata = (gxpf_data*)global_data;
+ QofBook *book = gdata->bookdata;
+
+ if (parent_data) {
+ return TRUE;
+ }
+
+ /* OK. For some messed up reason this is getting called again with a
+ NULL tag. So we ignore those cases */
+ if(!tag) {
+ return TRUE;
+ }
+
+ g_return_val_if_fail(tree, FALSE);
+
+ bgt = dom_tree_to_budget(tree, book);
+ xmlFreeNode(tree);
+ if(bgt != NULL) {
+ /* ends up calling book_callback */
+ gdata->cb(tag, gdata->parsedata, bgt);
+ }
+
+ return bgt != NULL;
+}
+
+
+GncBudget*
+dom_tree_to_budget (xmlNodePtr node, QofBook *book)
+{
+ GncBudget *bgt;
+
+ bgt = gnc_budget_new(book);
+ if (!dom_tree_generic_parse (node, budget_handlers, bgt)) {
+ PERR ("failed to parse budget tree");
+ gnc_budget_free(bgt);
+ bgt = NULL;
+ }
+ return bgt;
+}
+
+sixtp*
+gnc_budget_sixtp_parser_create(void)
+{
+ return sixtp_dom_parser_new(gnc_budget_end_handler, NULL, NULL);
+}
+/* ====================== END OF FILE ===================*/
Index: gnucash/src/backend/file/gnc-recurrence-xml-v2.c
===================================================================
--- /dev/null
+++ gnucash/src/backend/file/gnc-recurrence-xml-v2.c
@@ -0,0 +1,129 @@
+/********************************************************************
+ * gnc-recurrence-xml-v2.c -- xml routines for Recurrence *
+ * *
+ * Copyright (C) 2005 Chris Shoemaker <c.shoemaker at cox.net> *
+ * *
+ * 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, contact: *
+ * *
+ * Free Software Foundation Voice: +1-617-542-5942 *
+ * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
+ * Boston, MA 02111-1307, USA gnu at gnu.org *
+ * *
+ *******************************************************************/
+
+
+#include "config.h"
+
+#include <glib.h>
+#include <string.h>
+
+#include "gnc-xml.h"
+#include "gnc-xml-helper.h"
+#include "gnc-engine-util.h"
+#include "gnc-trace.h"
+
+#include "sixtp.h"
+#include "sixtp-utils.h"
+#include "sixtp-parsers.h"
+#include "sixtp-utils.h"
+#include "sixtp-dom-parsers.h"
+#include "sixtp-dom-generators.h"
+#include "io-gncxml-v2.h"
+#include "Recurrence.h"
+
+static QofLogModule log_module = GNC_MOD_IO;
+
+const gchar *recurrence_version_string = "1.0.0";
+#define recurrence_root "gnc:recurrence"
+#define recurrence_mult "recurrence:mult"
+#define recurrence_period_type "recurrence:period_type"
+#define recurrence_start "recurrence:start"
+
+//TODO: I think three of these functions rightly belong in Recurrence.c.
+
+static gboolean
+recurrence_period_type_handler(xmlNodePtr node, gpointer d)
+{
+ PeriodType pt;
+ char *nodeTxt;
+
+ nodeTxt = dom_tree_to_text(node);
+ g_return_val_if_fail(nodeTxt, FALSE);
+ pt = recurrencePeriodTypeFromString(nodeTxt);
+ ((Recurrence *) d)->ptype = pt;
+ g_free(nodeTxt);
+ return (pt != -1);
+}
+
+static gboolean
+recurrence_start_date_handler(xmlNodePtr node, gpointer r)
+{
+ GDate *d;
+
+ d = dom_tree_to_gdate(node);
+ g_return_val_if_fail(d, FALSE);
+ g_return_val_if_fail(g_date_valid(d), FALSE);
+ ((Recurrence *) r)->start = *d;
+ g_date_free(d);
+ return TRUE;
+}
+
+static gboolean
+recurrence_mult_handler(xmlNodePtr node, gpointer r)
+{
+ return dom_tree_to_guint16(node, &((Recurrence *)r)->mult);
+}
+
+static struct dom_tree_handler recurrence_dom_handlers[] = {
+ { recurrence_mult, recurrence_mult_handler, 1, 0 },
+ { recurrence_period_type, recurrence_period_type_handler, 1, 0 },
+ { recurrence_start, recurrence_start_date_handler, 1, 0 },
+ { NULL, NULL, 0, 0 }
+};
+
+Recurrence *
+dom_tree_to_recurrence(xmlNodePtr node)
+{
+ gboolean successful;
+ Recurrence *r;
+
+ r = g_new(Recurrence, 1);
+ successful = dom_tree_generic_parse (node, recurrence_dom_handlers, r);
+ if (!successful) {
+ PERR ("failed to parse recurrence node");
+ xmlElemDump(stdout, NULL, node);
+ g_free(r);
+ r = NULL;
+ }
+ return r;
+}
+
+xmlNodePtr
+recurrence_to_dom_tree(const gchar *tag, const Recurrence *r)
+{
+ xmlNodePtr n;
+ PeriodType pt;
+ GDate d;
+
+ n = xmlNewNode(NULL, tag);
+ xmlSetProp(n, "version", recurrence_version_string );
+ xmlAddChild(n, guint_to_dom_tree(recurrence_mult,
+ recurrenceGetMultiplier(r)));
+ pt = recurrenceGetPeriodType(r);
+ xmlAddChild(n, text_to_dom_tree(recurrence_period_type,
+ recurrencePeriodTypeToString(pt)));
+ d = recurrenceGetDate(r);
+ xmlAddChild(n, gdate_to_dom_tree(recurrence_start, &d));
+ return n;
+}
Index: gnucash/src/backend/file/gnc-xml.h
===================================================================
--- gnucash.orig/src/backend/file/gnc-xml.h
+++ gnucash/src/backend/file/gnc-xml.h
@@ -32,6 +32,7 @@
#include "qofbook.h"
#include "gnc-engine.h"
#include "gnc-pricedb.h"
+#include "gnc-budget.h"
#include "gnc-xml-helper.h"
#include "sixtp.h"
@@ -58,6 +59,9 @@ sixtp* gnc_pricedb_sixtp_parser_create(v
xmlNodePtr gnc_schedXaction_dom_tree_create( SchedXaction *sx );
sixtp* gnc_schedXaction_sixtp_parser_create(void);
+xmlNodePtr gnc_budget_dom_tree_create( GncBudget *bgt );
+sixtp* gnc_budget_sixtp_parser_create(void);
+
xmlNodePtr gnc_transaction_dom_tree_create(Transaction *txn);
sixtp* gnc_transaction_sixtp_parser_create(void);
Index: gnucash/src/backend/file/io-gncxml-v2.c
===================================================================
--- gnucash.orig/src/backend/file/io-gncxml-v2.c
+++ gnucash/src/backend/file/io-gncxml-v2.c
@@ -273,7 +273,7 @@ add_template_transaction_local( sixtp_gd
xaccGetAccountFromName( acctGroup,
xaccAccountGetName( (Account*)n->data ) );
if ( tmpAcct != NULL ) {
-/* XXX hack alert FIXME .... Should the be 'Remove', or 'Destroy'?
+/* XXX hack alert FIXME .... Should this be 'Remove', or 'Destroy'?
* If we just remove, then this seems to be a memory leak to me, since
* it is never reparented. Shouldn't it be a Destroy ???
*/
@@ -302,6 +302,16 @@ add_pricedb_local(sixtp_gdv2 *data, GNCP
return TRUE;
}
+#if 0
+static gboolean
+add_budget_local(sixtp_gdv2 *data, GncBudget *bgt)
+{
+/* CAS:I don't think anything is needed here, because budgets are
+ * automatically added to their book's collections when they are created. */
+ return TRUE;
+}
+#endif
+
static void
do_counter_cb (const char *type, gpointer data_p, gpointer be_data_p)
{
@@ -379,6 +389,10 @@ gnc_counter_end_handler(gpointer data_fo
{
sixdata->counter.schedXactions_total = val;
}
+ else if(safe_strcmp(type, "budget") == 0)
+ {
+ sixdata->counter.budgets_total = val;
+ }
else
{
struct file_backend be_data;
@@ -421,6 +435,8 @@ print_counter_data(load_counter *data)
data->commodities_total, data->commodities_loaded);
PINFO("Scheduled Tansactions: Total: %d, Loaded: %d",
data->schedXactions_total, data->schedXactions_loaded);
+ PINFO("Budgets: Total: %d, Loaded: %d",
+ data->budgets_total, data->budgets_loaded);
}
static void
@@ -436,13 +452,15 @@ file_rw_feedback (sixtp_gdv2 *gd, const
counter = &gd->counter;
loaded = counter->transactions_loaded + counter->accounts_loaded +
counter->books_loaded + counter->commodities_loaded +
- counter->schedXactions_loaded;
+ counter->schedXactions_loaded + counter->budgets_loaded;
total = counter->transactions_total + counter->accounts_total +
counter->books_total + counter->commodities_total +
- counter->schedXactions_total;
+ counter->schedXactions_total + counter->budgets_total;
percentage = (loaded * 100)/total;
if (percentage > 100) {
+ /* FIXME: Perhaps the below should be replaced by:
+ print_counter_data(counter); */
printf("Transactions: Total: %d, Loaded: %d\n",
counter->transactions_total, counter->transactions_loaded);
printf("Accounts: Total: %d, Loaded: %d\n",
@@ -453,6 +471,8 @@ file_rw_feedback (sixtp_gdv2 *gd, const
counter->commodities_total, counter->commodities_loaded);
printf("Scheduled Tansactions: Total: %d, Loaded: %d\n",
counter->schedXactions_total, counter->schedXactions_loaded);
+ printf("Budgets: Total: %d, Loaded: %d\n",
+ counter->budgets_total, counter->budgets_loaded);
}
percentage = MIN(percentage, 100);
gd->gui_display_fn(NULL, percentage);
@@ -468,6 +488,7 @@ static const char *COUNT_DATA_TAG = "gnc
static const char *TRANSACTION_TAG = "gnc:transaction";
static const char *SCHEDXACTION_TAG = "gnc:schedxaction";
static const char *TEMPLATE_TRANSACTION_TAG = "gnc:template-transactions";
+static const char *BUDGET_TAG = "gnc:budget";
static void
add_item_cb (const char *type, gpointer data_p, gpointer be_data_p)
@@ -514,10 +535,15 @@ book_callback(const char *tag, gpointer
{
add_schedXaction_local(gd, (SchedXaction*)data);
}
- else if(safe_strcmp(tag, TEMPLATE_TRANSACTION_TAG ) == 0 )
+ else if(safe_strcmp(tag, TEMPLATE_TRANSACTION_TAG) == 0)
{
add_template_transaction_local( gd, (gnc_template_xaction_data*)data );
}
+ else if(safe_strcmp(tag, BUDGET_TAG) == 0)
+ {
+ // What's this for? Needed?
+ //add_budget_local(gd, (GncBudget *)data);
+ }
else
{
struct file_backend be_data;
@@ -612,6 +638,8 @@ gnc_sixtp_gdv2_new (
gd->counter.prices_total = 0;
gd->counter.schedXactions_loaded = 0;
gd->counter.schedXactions_total = 0;
+ gd->counter.budgets_loaded = 0;
+ gd->counter.budgets_total = 0;
gd->exporting = exporting;
gd->countCallback = countcallback;
gd->gui_display_fn = gui_display_fn;
@@ -670,6 +698,7 @@ qof_session_load_from_xml_file_v2(FileBa
PRICEDB_TAG, gnc_pricedb_sixtp_parser_create(),
COMMODITY_TAG, gnc_commodity_sixtp_parser_create(),
ACCOUNT_TAG, gnc_account_sixtp_parser_create(),
+ BUDGET_TAG, gnc_budget_sixtp_parser_create(),
TRANSACTION_TAG, gnc_transaction_sixtp_parser_create(),
SCHEDXACTION_TAG, gnc_schedXaction_sixtp_parser_create(),
TEMPLATE_TRANSACTION_TAG, gnc_template_transaction_sixtp_parser_create(),
@@ -796,6 +825,7 @@ static void write_pricedb (FILE *out, Qo
static void write_transactions (FILE *out, QofBook *book, sixtp_gdv2 *gd);
static void write_template_transaction_data (FILE *out, QofBook *book, sixtp_gdv2 *gd);
static void write_schedXactions(FILE *out, QofBook *book, sixtp_gdv2 *gd);
+static void write_budgets(FILE *out, QofBook *book, sixtp_gdv2 *gd);
static void
write_counts_cb (const char *type, gpointer data_p, gpointer be_data_p)
@@ -864,6 +894,9 @@ write_book(FILE *out, QofBook *book, six
}
write_book_parts (out, book);
+ /* gd->counter.{foo}_total fields should have all these totals
+ already collected. I don't know why we're re-calling all these
+ functions. */
write_counts(out,
"commodity",
gnc_commodity_table_get_size(
@@ -874,7 +907,9 @@ write_book(FILE *out, QofBook *book, six
gnc_book_count_transactions(book),
"schedxaction",
g_list_length( gnc_book_get_schedxactions(book) ),
- NULL);
+ "budget",
+ g_list_length(gnc_book_get_budgets(book)),
+ NULL);
qof_object_foreach_backend (GNC_FILE_BACKEND, write_counts_cb, &be_data);
@@ -884,7 +919,7 @@ write_book(FILE *out, QofBook *book, six
write_transactions(out, book, gd);
write_template_transaction_data(out, book, gd);
write_schedXactions(out, book, gd);
-
+ write_budgets(out, book, gd);
qof_object_foreach_backend (GNC_FILE_BACKEND, write_data_cb, &be_data);
if(fprintf( out, "</%s>\n", BOOK_TAG ) < 0) {
@@ -1034,6 +1069,29 @@ write_schedXactions( FILE *out, QofBook
} while ( (schedXactions = schedXactions->next) );
}
+static void
+write_budgets( FILE *out, QofBook *book, sixtp_gdv2 *gd)
+{
+ GList *budgetList;
+ GncBudget *tmp;
+ xmlNodePtr node;
+
+ /* get list of budgets from QofBook */
+ budgetList = gnc_book_get_budgets(book);
+
+ g_return_if_fail(budgetList);
+
+ do {
+ tmp = budgetList->data;
+ node = gnc_budget_dom_tree_create( tmp );
+ xmlElemDump( out, NULL, node );
+ fprintf( out, "\n" );
+ xmlFreeNode( node );
+ gd->counter.budgets_loaded++;
+ run_callback(gd, "budgets");
+ } while ((budgetList = budgetList->next));
+}
+
void
gnc_xml2_write_namespace_decl (FILE *out, const char *namespace)
{
@@ -1102,7 +1160,7 @@ gnc_book_write_to_xml_filehandle_v2(QofB
gd->counter.transactions_total = gnc_book_count_transactions(book);
gd->counter.schedXactions_total =
g_list_length( gnc_book_get_schedxactions(book));
-
+ gd->counter.budgets_total = g_list_length(gnc_book_get_budgets(book));
write_book(out, book, gd);
fprintf(out, "</" GNC_V2_STRING ">\n\n");
@@ -1207,7 +1265,7 @@ gnc_book_write_to_xml_file_v2(
FILE *out;
out = try_gz_open(filename, "w", compress);
- if (out == NULL)
+ if (out == NULL)
{
return FALSE;
}
Index: gnucash/src/backend/file/io-gncxml-v2.h
===================================================================
--- gnucash.orig/src/backend/file/io-gncxml-v2.h
+++ gnucash/src/backend/file/io-gncxml-v2.h
@@ -58,6 +58,9 @@ typedef struct
int schedXactions_total;
int schedXactions_loaded;
+
+ int budgets_total;
+ int budgets_loaded;
} load_counter;
typedef struct sixtp_gdv2 sixtp_gdv2;
Index: gnucash/src/backend/file/sixtp-dom-generators.c
===================================================================
--- gnucash.orig/src/backend/file/sixtp-dom-generators.c
+++ gnucash/src/backend/file/sixtp-dom-generators.c
@@ -38,14 +38,14 @@ static QofLogModule log_module = GNC_MOD
xmlNodePtr
text_to_dom_tree(const char *tag, const char *str)
{
- xmlNodePtr result;
+ xmlNodePtr result;
- g_return_val_if_fail(tag, NULL);
- g_return_val_if_fail(str, NULL);
- result = xmlNewNode(NULL, BAD_CAST tag);
- g_return_val_if_fail(result, NULL);
- xmlNodeAddContent(result, BAD_CAST str);
- return result;
+ g_return_val_if_fail(tag, NULL);
+ g_return_val_if_fail(str, NULL);
+ result = xmlNewNode(NULL, BAD_CAST tag);
+ g_return_val_if_fail(result, NULL);
+ xmlNodeAddContent(result, BAD_CAST str);
+ return result;
}
xmlNodePtr
@@ -55,11 +55,26 @@ int_to_dom_tree(const char *tag, gint64
xmlNodePtr result;
text = g_strdup_printf("%" G_GINT64_FORMAT, val);
+ g_return_val_if_fail(text, NULL);
result = text_to_dom_tree(tag, text);
g_free(text);
return result;
}
+
+xmlNodePtr
+guint_to_dom_tree(const char *tag, guint an_int)
+{
+ gchar *text;
+ xmlNodePtr result;
+ text = g_strdup_printf("%u", an_int );
+ g_return_val_if_fail(text, NULL);
+ result = text_to_dom_tree(tag, text);
+ g_free(text);
+ return result;
+}
+
+
xmlNodePtr
guid_to_dom_tree(const char *tag, const GUID* gid)
{
@@ -72,7 +87,7 @@ guid_to_dom_tree(const char *tag, const
if (!guid_to_string_buff(gid, guid_str))
{
- PERR("guid_to_string failed\n");
+ PERR("guid_to_string_buff failed\n");
return NULL;
}
@@ -158,7 +173,7 @@ timespec_to_dom_tree(const char *tag, co
}
xmlNodePtr
-gdate_to_dom_tree(const char *tag, GDate *date)
+gdate_to_dom_tree(const char *tag, const GDate *date)
{
xmlNodePtr ret;
gchar *date_str = NULL;
@@ -275,6 +290,7 @@ add_kvp_value_node(xmlNodePtr node, gcha
xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "string");
break;
case KVP_TYPE_GUID:
+ /* THREAD-UNSAFE */
add_text_to_node(val_node,"guid",
g_strdup(guid_to_string(kvp_value_get_guid(val))));
break;
@@ -371,19 +387,3 @@ kvp_frame_to_dom_tree(const char *tag, c
return ret;
}
-xmlNodePtr guint_to_dom_tree(const char *tag, guint an_int)
-{
- xmlNodePtr ret;
- gchar *numstr;
-
- numstr = g_strdup_printf( "%u", an_int );
- g_return_val_if_fail(numstr, NULL);
-
- ret = xmlNewNode(NULL, BAD_CAST tag);
-
- xmlNodeAddContent(ret, BAD_CAST numstr);
-
- g_free(numstr);
-
- return ret;
-}
Index: gnucash/src/backend/file/sixtp-dom-generators.h
===================================================================
--- gnucash.orig/src/backend/file/sixtp-dom-generators.h
+++ gnucash/src/backend/file/sixtp-dom-generators.h
@@ -34,6 +34,7 @@
#include "gnc-commodity.h"
#include "gnc-date.h"
#include "gnc-numeric.h"
+#include "Recurrence.h"
#include "kvp_frame.h"
#include "qofid.h"
@@ -44,10 +45,11 @@ xmlNodePtr commodity_ref_to_dom_tree(con
xmlNodePtr timespec_to_dom_tree(const char *tag, const Timespec *spec);
gchar * timespec_nsec_to_string(const Timespec *ts);
gchar * timespec_sec_to_string(const Timespec *ts);
-xmlNodePtr gdate_to_dom_tree(const char *tag, GDate *spec);
+xmlNodePtr gdate_to_dom_tree(const char *tag, const GDate *spec);
xmlNodePtr gnc_numeric_to_dom_tree(const char *tag, const gnc_numeric *num);
xmlNodePtr kvp_frame_to_dom_tree(const char *tag, const kvp_frame *frame);
xmlNodePtr guint_to_dom_tree(const char *tag, guint an_int);
+xmlNodePtr recurrence_to_dom_tree(const gchar *tag, const Recurrence *r);
gchar* double_to_string(double value);
Index: gnucash/src/backend/file/sixtp-dom-parsers.c
===================================================================
--- gnucash.orig/src/backend/file/sixtp-dom-parsers.c
+++ gnucash/src/backend/file/sixtp-dom-parsers.c
@@ -111,6 +111,33 @@ dom_tree_to_integer(xmlNodePtr node, gin
return ret;
}
+gboolean
+dom_tree_to_guint16(xmlNodePtr node, guint16 *i)
+{
+ gboolean ret;
+ guint j = 0;
+
+ ret = dom_tree_to_guint(node, &j);
+ *i = (guint16) j;
+ return ret;
+}
+
+gboolean
+dom_tree_to_guint(xmlNodePtr node, guint *i)
+{
+ gchar *text, *endptr;
+ gboolean ret;
+
+ text = dom_tree_to_text(node);
+ /* In spite of the strange string_to_gint64 function, I'm just
+ going to use strtoul here until someone shows me the error of
+ my ways. -CAS */
+ *i = (guint) strtoul(text, &endptr, 0);
+ ret = (endptr != text);
+ g_free(text);
+ return ret;
+}
+
kvp_value*
dom_tree_to_double_kvp_value(xmlNodePtr node)
{
Index: gnucash/src/backend/file/sixtp-dom-parsers.h
===================================================================
--- gnucash.orig/src/backend/file/sixtp-dom-parsers.h
+++ gnucash/src/backend/file/sixtp-dom-parsers.h
@@ -36,7 +36,7 @@
#include "kvp_frame.h"
#include "qofbook.h"
#include "qofid.h"
-
+#include "gnc-budget.h"
GUID* dom_tree_to_guid(xmlNodePtr node);
@@ -44,6 +44,7 @@ gnc_commodity* dom_tree_to_commodity_ref
gnc_commodity *dom_tree_to_commodity_ref_no_engine(xmlNodePtr node, QofBook *);
FreqSpec* dom_tree_to_freqSpec( xmlNodePtr node, QofBook *book);
+Recurrence* dom_tree_to_recurrence(xmlNodePtr node);
Timespec dom_tree_to_timespec(xmlNodePtr node);
#define is_valid_timespec(ts) (ts.tv_sec || ts.tv_nsec)
@@ -67,12 +68,15 @@ kvp_value* dom_tree_to_list_kvp_value(xm
kvp_value* dom_tree_to_frame_kvp_value(xmlNodePtr node);
gboolean dom_tree_to_integer(xmlNodePtr node, gint64 *daint);
+gboolean dom_tree_to_guint16(xmlNodePtr node, guint16 *i);
+gboolean dom_tree_to_guint(xmlNodePtr node, guint *i);
/* higher level structures */
Account* dom_tree_to_account(xmlNodePtr node, QofBook *book);
QofBook* dom_tree_to_book (xmlNodePtr node, QofBook *book);
GNCLot* dom_tree_to_lot (xmlNodePtr node, QofBook *book);
Transaction* dom_tree_to_transaction(xmlNodePtr node, QofBook *book);
+GncBudget* dom_tree_to_budget(xmlNodePtr node, QofBook *book);
struct dom_tree_handler
{
Index: gnucash/src/backend/file/sixtp-utils.c
===================================================================
--- gnucash.orig/src/backend/file/sixtp-utils.c
+++ gnucash/src/backend/file/sixtp-utils.c
@@ -211,7 +211,8 @@ string_to_double(const char *str, double
/*********/
/* gint64
*/
-
+/* Maybe there should be a comment here explaining why this function
+ doesn't call g_ascii_strtoull, because it's not so obvious. -CAS */
gboolean
string_to_gint64(const gchar *str, gint64 *v)
{
Index: gnucash/src/backend/file/test/Makefile.am
===================================================================
--- gnucash.orig/src/backend/file/test/Makefile.am
+++ gnucash/src/backend/file/test/Makefile.am
@@ -39,11 +39,13 @@ test_load_example_account_SOURCES = \
${top_srcdir}/src/backend/file/sixtp-stack.c \
${top_srcdir}/src/backend/file/sixtp-to-dom-parser.c \
${top_srcdir}/src/backend/file/io-example-account.c \
- ${top_srcdir}/src/backend/file/gnc-account-xml-v2.c \
${top_srcdir}/src/backend/file/io-gncxml-gen.c \
${top_srcdir}/src/backend/file/io-gncxml-v2.c \
${top_srcdir}/src/backend/file/io-utils.c \
+ ${top_srcdir}/src/backend/file/gnc-account-xml-v2.c \
+ ${top_srcdir}/src/backend/file/gnc-budget-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-lot-xml-v2.c \
+ ${top_srcdir}/src/backend/file/gnc-recurrence-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-schedxaction-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-freqspec-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-transaction-xml-v2.c \
@@ -124,9 +126,11 @@ test_xml_transaction_SOURCES = \
${top_srcdir}/src/backend/file/sixtp-to-dom-parser.c \
${top_srcdir}/src/backend/file/io-gncxml-gen.c \
${top_srcdir}/src/backend/file/gnc-account-xml-v2.c \
+ ${top_srcdir}/src/backend/file/gnc-budget-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-lot-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-schedxaction-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-freqspec-xml-v2.c \
+ ${top_srcdir}/src/backend/file/gnc-recurrence-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-transaction-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-commodity-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-book-xml-v2.c \
@@ -143,7 +147,9 @@ test_xml2_is_file_SOURCES = \
${top_srcdir}/src/backend/file/sixtp-stack.c \
${top_srcdir}/src/backend/file/sixtp-to-dom-parser.c \
${top_srcdir}/src/backend/file/gnc-account-xml-v2.c \
+ ${top_srcdir}/src/backend/file/gnc-budget-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-lot-xml-v2.c \
+ ${top_srcdir}/src/backend/file/gnc-recurrence-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-schedxaction-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-freqspec-xml-v2.c \
${top_srcdir}/src/backend/file/gnc-transaction-xml-v2.c \
--
More information about the gnucash-patches
mailing list