From fad1d42f816de314ac41c4474aa7c3ade15aca13 Mon Sep 17 00:00:00 2001 From: Dave Peticolas Date: Tue, 13 Mar 2001 21:05:09 +0000 Subject: [PATCH] James LewisMoss's patch. * src/engine/io-gncxml-v2.c (gnc_counter_end_handler): complete func. (print_counter_data): new func. (gnc_book_load_from_xml_file_v2): call above func at end of parse. * src/engine/sixtp-dom-parsers.c (string_to_integer): move here from gnc-commodity-xml-v2.c * src/engine/io-gncxml-v2.c (gnc_book_write_to_xml_file_v2): add transaction number output. * src/engine/Group.c (xaccGroupForEachTransaction): actually make this work. (xaccGroupVisitUnvisitedTransactions): actually make this work. Don't get accounts from group. We already are looking at all of them by xaccGroupGetSubAccounts. (xaccGroupVisitUnvisitedTransactions_thunk): new func for xaccAccountForEachTransaction call. * src/test/test-string-converters.c (test_string_converters): add func to test some more difficult strings (including xml special characters) * src/engine/gnc-account-xml-v2.c (gnc_account_dom_tree_create): convert to use text_to_dom_tree. * src/engine/gnc-commodity-xml-v2.c (gnc_commodity_dom_tree_create): convert to use text_to_dom_tree. * src/engine/gnc-book.c (gnc_book_count_transactions): new func. * src/engine/io-gncxml-v2.c: (write_account_group)new func. extract out stuff from write_accounts. Forgot to traverse down accounts so a bunch of the accounts weren't being written. (write_accounts): now just call the write_account_group func. (gnc_book_write_to_xml_file_v2): use xaccGroupNumSubAccounts to get the number of accounts. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3774 57a11ea4-9604-0410-9ed3-97b8803252fd --- ChangeLog | 41 +++++++++++++ src/engine/Group.c | 39 ++++++++++-- src/engine/gnc-account-xml-v2.c | 14 +++-- src/engine/gnc-book.c | 16 +++++ src/engine/gnc-book.h | 2 + src/engine/gnc-commodity-xml-v2.c | 29 ++++----- src/engine/io-gncxml-v2.c | 99 +++++++++++++++++++++++++++++-- src/engine/sixtp-dom-parsers.c | 13 ++++ src/engine/sixtp-dom-parsers.h | 1 + 9 files changed, 219 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index 43dc0bc694..cd42475dc9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,44 @@ +2001-03-13 James LewisMoss + + * src/engine/io-gncxml-v2.c (gnc_counter_end_handler): complete + func. + (print_counter_data): new func. + (gnc_book_load_from_xml_file_v2): call above func at end of + parse. + + * src/engine/sixtp-dom-parsers.c (string_to_integer): move here + from gnc-commodity-xml-v2.c + + * src/engine/io-gncxml-v2.c (gnc_book_write_to_xml_file_v2): add + transaction number output. + + * src/engine/Group.c (xaccGroupForEachTransaction): actually make + this work. + (xaccGroupVisitUnvisitedTransactions): actually make this work. + Don't get accounts from group. We already are looking at all of + them by xaccGroupGetSubAccounts. + (xaccGroupVisitUnvisitedTransactions_thunk): new func for + xaccAccountForEachTransaction call. + + * src/test/test-string-converters.c (test_string_converters): add + func to test some more difficult strings (including xml special + characters) + + * src/engine/gnc-account-xml-v2.c (gnc_account_dom_tree_create): + convert to use text_to_dom_tree. + + * src/engine/gnc-commodity-xml-v2.c + (gnc_commodity_dom_tree_create): convert to use text_to_dom_tree. + + * src/engine/gnc-book.c (gnc_book_count_transactions): new func. + + * src/engine/io-gncxml-v2.c: (write_account_group)new func. + extract out stuff from write_accounts. Forgot to traverse down + accounts so a bunch of the accounts weren't being written. + (write_accounts): now just call the write_account_group func. + (gnc_book_write_to_xml_file_v2): use xaccGroupNumSubAccounts to + get the number of accounts. + 2001-03-13 Dave Peticolas * src/engine/sixtp-utils.c (gnc_timegm): new func. define as diff --git a/src/engine/Group.c b/src/engine/Group.c index 3f7b7a87c3..01ea902356 100644 --- a/src/engine/Group.c +++ b/src/engine/Group.c @@ -1187,6 +1187,32 @@ xaccGroupStagedTransactionTraversal (AccountGroup *grp, /********************************************************************\ \********************************************************************/ +struct group_visit_data +{ + gboolean (*proc)(Transaction *t, void *data); + void *up_data; + GHashTable *visit_table; +}; + +static gboolean +xaccGroupVisitUnvisitedTransactions_thunk(Transaction *trn, + void *data) +{ + gpointer test_trn; + struct group_visit_data *grdata = (struct group_visit_data*)data; + + test_trn = g_hash_table_lookup(grdata->visit_table, trn); + + if(!test_trn) + { + g_hash_table_insert(grdata->visit_table, trn, ""); + + grdata->proc(trn, grdata->up_data); + } + + return TRUE; +} + gboolean xaccGroupVisitUnvisitedTransactions (AccountGroup *g, gboolean (*proc)(Transaction *t, @@ -1197,19 +1223,24 @@ xaccGroupVisitUnvisitedTransactions (AccountGroup *g, gboolean keep_going = TRUE; GList *list; GList *node; - + struct group_visit_data grdata; + if (!g) return(FALSE); if (!proc) return(FALSE); if (!visited_txns) return(FALSE); list = xaccGroupGetSubAccounts (g); + grdata.proc = proc; + grdata.up_data = data; + grdata.visit_table = visited_txns; + for (node = list; node && keep_going; node = node->next) { Account *account = node->data; - - keep_going = xaccAccountVisitUnvisitedTransactions (account, proc, - data, visited_txns); + + keep_going = xaccAccountForEachTransaction( + account, xaccGroupVisitUnvisitedTransactions_thunk, (void*)&grdata); } g_list_free (list); diff --git a/src/engine/gnc-account-xml-v2.c b/src/engine/gnc-account-xml-v2.c index 0ba4e84f95..c87500c560 100644 --- a/src/engine/gnc-account-xml-v2.c +++ b/src/engine/gnc-account-xml-v2.c @@ -42,12 +42,13 @@ gnc_account_dom_tree_create(Account *act) ret = xmlNewNode(NULL, gnc_account_string); xmlSetProp(ret, "version", account_version_string); - xmlNewChild(ret, NULL, act_name_string, xaccAccountGetName(act)); + xmlAddChild(ret, text_to_dom_tree(act_name_string, xaccAccountGetName(act))); xmlAddChild(ret, guid_to_dom_tree(act_id_string, xaccAccountGetGUID(act))); - xmlNewChild(ret, NULL, act_type_string, - xaccAccountTypeEnumAsString(xaccAccountGetType(act))); + xmlAddChild(ret, text_to_dom_tree( + act_type_string, + xaccAccountTypeEnumAsString(xaccAccountGetType(act)))); xmlAddChild(ret, commodity_ref_to_dom_tree(act_currency_string, xaccAccountGetCurrency(act))); @@ -55,14 +56,15 @@ gnc_account_dom_tree_create(Account *act) if(xaccAccountGetCode(act) && strlen(xaccAccountGetCode(act)) > 0) { - xmlNewChild(ret, NULL, act_code_string, xaccAccountGetCode(act)); + xmlAddChild(ret, text_to_dom_tree(act_code_string, + xaccAccountGetCode(act))); } if(xaccAccountGetDescription(act) && strlen(xaccAccountGetDescription(act)) > 0) { - xmlNewChild(ret, NULL, act_description_string, - xaccAccountGetDescription(act)); + xmlAddChild(ret, text_to_dom_tree(act_description_string, + xaccAccountGetDescription(act))); } if(xaccAccountGetSecurity(act)) diff --git a/src/engine/gnc-book.c b/src/engine/gnc-book.c index b5b04bf5e2..daee82814d 100644 --- a/src/engine/gnc-book.c +++ b/src/engine/gnc-book.c @@ -174,6 +174,22 @@ gnc_book_set_group (GNCBook *book, AccountGroup *grp) book->topgroup = grp; } +static int +counter_thunk(Transaction *t, void *data) +{ + (*((guint*)data))++; + return 0; +} + +guint +gnc_book_count_transactions(GNCBook *book) +{ + guint count = 0; + xaccGroupForEachTransaction(gnc_book_get_group(book), + counter_thunk, (void*)&count); + return count; +} + /* ---------------------------------------------------------------------- */ GNCPriceDB * diff --git a/src/engine/gnc-book.h b/src/engine/gnc-book.h index cc7523c122..f693626949 100644 --- a/src/engine/gnc-book.h +++ b/src/engine/gnc-book.h @@ -121,6 +121,8 @@ GNCBackendError gnc_book_pop_error (GNCBook *book); AccountGroup *gnc_book_get_group (GNCBook *book); GNCPriceDB *gnc_book_get_pricedb (GNCBook *book); +guint gnc_book_count_transactions(GNCBook *book); + /* * gnc_book_get_commodity_table returns the commodity table associated with * the BOOK. At the moment this just returns the global commodity table, diff --git a/src/engine/gnc-commodity-xml-v2.c b/src/engine/gnc-commodity-xml-v2.c index da46406a94..6adf209936 100644 --- a/src/engine/gnc-commodity-xml-v2.c +++ b/src/engine/gnc-commodity-xml-v2.c @@ -32,25 +32,29 @@ gnc_commodity_dom_tree_create(const gnc_commodity *com) xmlSetProp(ret, "version", commodity_version_string); - xmlNewChild(ret, NULL, "cmdty:space", gnc_commodity_get_namespace(com)); - xmlNewChild(ret, NULL, "cmdty:id", gnc_commodity_get_mnemonic(com)); + xmlAddChild(ret, text_to_dom_tree("cmdty:space", + gnc_commodity_get_namespace(com))); + xmlAddChild(ret, text_to_dom_tree("cmdty:id", + gnc_commodity_get_mnemonic(com))); if(gnc_commodity_get_fullname(com)) { - xmlNewChild(ret, NULL, "cmdty:name", gnc_commodity_get_fullname(com)); + xmlAddChild(ret, text_to_dom_tree("cmdty:name", + gnc_commodity_get_fullname(com))); } if(gnc_commodity_get_exchange_code(com) && strlen(gnc_commodity_get_exchange_code(com)) > 0) { - xmlNewChild(ret, NULL, "cmdty:xcode", - gnc_commodity_get_exchange_code(com)); + xmlAddChild(ret, text_to_dom_tree( + "cmdty:xcode", + gnc_commodity_get_exchange_code(com))); } { gchar *text; text = g_strdup_printf("%d", gnc_commodity_get_fraction(com)); - xmlNewChild(ret, NULL, "cmdty:fraction", text); + xmlAddChild(ret, text_to_dom_tree("cmdty:fraction", text)); g_free(text); } @@ -73,19 +77,6 @@ struct com_char_handler com_handlers[] = { { 0, 0 } }; -static gboolean -string_to_integer(const char *content, gint64 *to) -{ - if(sscanf(content, "%lld", to) == 1) - { - return TRUE; - } - else - { - return FALSE; - } -} - static void set_commodity_value(xmlNodePtr node, gnc_commodity* com) { diff --git a/src/engine/io-gncxml-v2.c b/src/engine/io-gncxml-v2.c index fda7016c99..36e2ce48c7 100644 --- a/src/engine/io-gncxml-v2.c +++ b/src/engine/io-gncxml-v2.c @@ -5,8 +5,10 @@ #include "gnc-engine.h" #include "gnc-engine-util.h" +#include "sixtp-dom-parsers.h" #include "io-gncxml-v2.h" #include "sixtp.h" +#include "sixtp-parsers.h" #include "gnc-xml.h" #include "gnc-book-p.h" @@ -102,10 +104,76 @@ add_pricedb_local(sixtp_gdv2 *data, GNCPriceDB *db) return TRUE; } +static gboolean +gnc_counter_end_handler(gpointer data_for_children, + GSList* data_from_children, GSList* sibling_data, + gpointer parent_data, gpointer global_data, + gpointer *result, const gchar *tag) +{ + char *strval; + gint64 val; + char *type; + xmlNodePtr tree = (xmlNodePtr)data_for_children; + sixtp_gdv2 *gdata = (sixtp_gdv2*)global_data; + + 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); + + type = xmlGetProp(tree, "cd:type"); + strval = dom_tree_to_text(tree); + if(!string_to_integer(strval, &val)) + { + g_warning("string_to_integer failed with input: %s", strval); + return FALSE; + } + + if(safe_strcmp(type, "transaction") == 0) + { + gdata->counter.transactions_total = val; + } + else if(safe_strcmp(type, "account") == 0) + { + gdata->counter.accounts_total = val; + } + else if(safe_strcmp(type, "commodity") == 0) + { + gdata->counter.commodities_total = val; + } + else + { + g_warning("Unknown type: %s", type); + return FALSE; + } + + return TRUE; +} + static sixtp* gnc_counter_sixtp_parser_create(void) { - return NULL; + return sixtp_dom_parser_new(gnc_counter_end_handler, NULL, NULL); +} + +static void +print_counter_data(struct _load_counter_struct data) +{ + printf("Transactions: Total: %d, Loaded: %d\n", + data.transactions_total, data.transactions_loaded); + printf("Accounts: Total: %d, Loaded: %d\n", + data.accounts_total, data.accounts_loaded); + printf("Commodities: Total: %d, Loaded: %d\n", + data.commodities_total, data.commodities_loaded); } gboolean @@ -141,7 +209,7 @@ gnc_book_load_from_xml_file_v2(GNCBook *book) { return FALSE; } - + if(!sixtp_parse_file(parser, gnc_book_get_file_path(book), NULL, &gd, &parse_result)) { @@ -152,6 +220,9 @@ gnc_book_load_from_xml_file_v2(GNCBook *book) { } + /* DEBUG */ + print_counter_data(gd.counter); + return TRUE; } @@ -270,25 +341,39 @@ write_pricedb(FILE *out, GNCBook *book) } static void -write_accounts(FILE *out, GNCBook *book) +write_account_group(FILE *out, AccountGroup *grp) { GList *list; GList *node; - list = xaccGroupGetAccountList (gnc_book_get_group(book)); + list = xaccGroupGetAccountList(grp); for (node = list; node; node = node->next) { xmlNodePtr accnode; - + AccountGroup *newgrp; + accnode = gnc_account_dom_tree_create((Account*)(node->data)); xmlElemDump(out, NULL, accnode); fprintf(out, "\n"); xmlFreeNode(accnode); + + newgrp = xaccAccountGetChildren((Account*)(node->data)); + + if(grp) + { + write_account_group(out, newgrp); + } } } +static void +write_accounts(FILE *out, GNCBook *book) +{ + write_account_group(out, gnc_book_get_group(book)); +} + static gboolean xml_add_trn_data(Transaction *t, gpointer data) { xmlNodePtr node; @@ -325,7 +410,9 @@ gnc_book_write_to_xml_file_v2(GNCBook *book, const char *filename) gnc_commodity_table_get_size( gnc_book_get_commodity_table(book)), "account", - xaccGroupGetNumAccounts(gnc_book_get_group(book)), + xaccGroupGetNumSubAccounts(gnc_book_get_group(book)), + "transaction", + gnc_book_count_transactions(book), NULL); write_commodities(out, book); diff --git a/src/engine/sixtp-dom-parsers.c b/src/engine/sixtp-dom-parsers.c index 30dd84eb21..580025b00b 100644 --- a/src/engine/sixtp-dom-parsers.c +++ b/src/engine/sixtp-dom-parsers.c @@ -723,3 +723,16 @@ dom_tree_generic_parse(xmlNodePtr node, struct dom_tree_handler *handlers, return successful; } + +gboolean +string_to_integer(const char *content, gint64 *to) +{ + if(sscanf(content, "%lld", to) == 1) + { + return TRUE; + } + else + { + return FALSE; + } +} diff --git a/src/engine/sixtp-dom-parsers.h b/src/engine/sixtp-dom-parsers.h index 2edfa71d6c..0ee222b7a2 100644 --- a/src/engine/sixtp-dom-parsers.h +++ b/src/engine/sixtp-dom-parsers.h @@ -48,6 +48,7 @@ Timespec* dom_tree_to_timespec(xmlNodePtr node); gnc_numeric* dom_tree_to_gnc_numeric(xmlNodePtr node); gchar * dom_tree_to_text(xmlNodePtr tree); gboolean string_to_binary(const gchar *str, void **v, guint64 *data_len); +gboolean string_to_integer(const char *content, gint64 *to); kvp_frame* dom_tree_to_kvp_frame(xmlNodePtr node); kvp_value* dom_tree_to_kvp_value(xmlNodePtr node);