From 96372a16ed19fa3fff99f206c4b795734dbcf2fc Mon Sep 17 00:00:00 2001 From: Dave Peticolas Date: Thu, 22 Mar 2001 08:02:48 +0000 Subject: [PATCH] James LewisMoss's big patch. XML v2 stuff, testing, and misc changes. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3818 57a11ea4-9604-0410-9ed3-97b8803252fd --- ChangeLog | 130 +++++++++++++++++++++++ src/FileDialog.c | 6 ++ src/engine/Account.c | 29 +++--- src/engine/Backend.h | 3 +- src/engine/GNCId.c | 3 + src/engine/Group.c | 24 ++--- src/engine/Group.h | 8 +- src/engine/gnc-account-xml-v2.c | 10 +- src/engine/gnc-book.c | 131 ++++++++++++++++------- src/engine/gnc-book.h | 13 +++ src/engine/gnc-pricedb-xml-v1.c | 10 ++ src/engine/gnc-transaction-xml-v2.c | 12 ++- src/engine/io-gncxml-r.c | 27 +---- src/engine/io-gncxml-v2.c | 155 +++++++++------------------- src/engine/io-gncxml-v2.h | 5 +- src/engine/sixtp-dom-parsers.c | 6 +- src/engine/sixtp.c | 103 +++++++++++++++++- src/engine/sixtp.h | 2 + src/gnome/cursors.c | 5 + 19 files changed, 468 insertions(+), 214 deletions(-) diff --git a/ChangeLog b/ChangeLog index 941587517a..3bd7194cac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -49,6 +49,71 @@ * src/gnome/window-register.c: add arguments to report window for title & debit/credit strings +2001-03-21 James LewisMoss + + * src/engine/Account.c (xaccAccountInsertSplit): add test to not + remove if the account is the same. + (xaccAccountInsertSplit): add check to see if the split already + exists in the account. + + * src/test/test-xml2-is-file.c (main): use simple_success_test. + + * src/test/test-xml-transaction.c (test_add_transaction): + cleanup. use simple_success_test. + + * src/test/test-xml-commodity.c (test_add_commodity): use + simple_success_test. + + * src/test/test-xml-account.c (test_add_account): use + simple_success_test. + + * src/test/test-string-converters.c (test_string_converters): use + success_with_error_args. + + * src/test/test-kvp-frames.c (test_kvp_copy_compare): use + simple_success_test. + + * src/test/test-dom-converters1.c + (test_dom_tree_to_commodity_ref): user simple_success_test + + * src/test/test-load-xml2.c (main): use success_test_with_error_args + + * src/test/test-stuff.c (get_random_string_in_array): new func to + get a random string from a string array. + (get_random_commodity): move func here from test-xml-commodity.c + (success_test_with_error_args): new func. + (vfailure_args): new func. make failure_args call this. + (vsuccess_args): new func. make success_args call this. + + * src/engine/io-gncxml-v2.c (gnc_book_load_from_xml_file_v2): zero + out totals as well. + + * src/engine/gnc-book.c (gnc_book_push_error): add new parameter + the message string. + (gnc_book_push_error): Change everything to use it (adding NULL + everywhere) + (get_default_error_message): new func to return a message based on + type of error. + (gnc_book_get_error_message): new func to return error message. + (gnc_book_pop_error): change to use clear error so the freeing + behavior of the error message doesn't have to be copied. + (gnc_book_clear_error): free the error message. + + * src/engine/io-gncxml-v2.c (gnc_is_xml_data_file_v2): use new + func from sixtp.h + + * src/engine/sixtp.c (gnc_is_our_xml_file): extract out v2 xml is + ours test code and create new func. + (search_for): move here from io-gncxml-v2.c + (eat_whitespace): likewise. + + * src/engine/io-gncxml-v2.c (gnc_book_load_from_xml_file_v2): set + count totals to 0. + + * src/gnome/cursors.c (set_cursor_helper): add NULL test for + window. I think this is a timing thing found by not having the + window come up quickly enough. + 2001-03-20 Christian Stimming * src/scm/report/income-expense-graph.scm, @@ -94,6 +159,51 @@ * src/scm/html-utilities.scm: add function for assigning colors +2001-03-20 James LewisMoss + + * src/engine/Group.c (xaccGroupRemoveAccount): rename function + from xaccRemoveAccount and add Group parameter to make it fit with + the rest better. + (xaccAccountRemoveGroup): rename function from xaccRemoveGroup to + better fit naming conventions and add Account parameter. Actually + make the parameter just an Account. + + * src/test/test-xml2-is-file.c (main): same as below. + + * src/test/test-xml-transaction.c (main): same as below. + + * src/test/test-split-vs-account.c (main): same as below. + + * src/test/test-string-converters.c (main): add print_test_stats + call. + + * src/test/Makefile.am (STUFF): remove test-dom-parser1 because + it's not automated. + + * src/test/test-dom-converters1.c (main): same as below. + + * src/test/test-date-converting.c (main): add print_test_stats + call. + + * src/test/test-stuff.c (print_stats): new func. + (success_args): print success only if set. + (success_args): increment successes. + (failure_args): increment failures. + + * src/engine/gnc-transaction-xml-v2.c (split_to_dom_tree): don't + add a memo field with an empty string as the value. + + * src/engine/sixtp-dom-parsers.c (dom_tree_to_text): don't return + NULL if no children. This just means there is no text and we + should return a strduped "". + + * src/engine/gnc-transaction-xml-v2.c (trn_dom_handlers): make + slots not required transaction item. + + * src/engine/gnc-account-xml-v2.c: make code and description not + necessary. + (account_parent_handler): Add tests for NULL data. + 2001-03-19 Dave Peticolas * src/gnome/gnc-html-guppi.c: fix callback pointer @@ -321,6 +431,13 @@ * src/engine/Query.c: handle NULL pointers, add api to get list of splits with unique transactions +2001-03-15 James LewisMoss + + * src/engine/gnc-book.c (gnc_book_load_from_file): add xml v2 + loading. Make use new funcs (below) + (happy_or_push_error): new func. + (gnc_book_determine_file_type): new func. + 2001-03-14 Dave Peticolas * rpm/gnucash.spec.in: simplify @@ -350,6 +467,14 @@ * doc/sgml/C/xacc-dochack.sgml: remove and fix broken links +2001-03-14 James LewisMoss + + * src/engine/io-gncxml-v2.c (gnc_book_load_from_xml_file_v2): Add + counter callback. + (add_account_local): add call to countCallback + (add_commodity_local): same + (add_transaction_local): same. + 2001-03-13 Dave Peticolas * src/engine/io-gncxml-r.c (gnc_is_xml_data_file): don't print @@ -384,6 +509,11 @@ 2001-03-13 James LewisMoss + * src/test/test-stuff.c (get_random_string): sometimes generate + empty strings and NULL (10% each). + (get_random_string): and 10% of the time generate a larger string. + (get_random_character): Generate better characters. + * src/engine/io-gncxml-v2.c (gnc_counter_end_handler): complete func. (print_counter_data): new func. diff --git a/src/FileDialog.c b/src/FileDialog.c index 7de7a2c8c5..0b0359167c 100644 --- a/src/FileDialog.c +++ b/src/FileDialog.c @@ -116,6 +116,12 @@ show_book_error (GNCBackendError io_error, const char *newfile) if (gnc_verify_dialog (fmt, TRUE)) { uh_oh = FALSE; } break; + case ERR_FILEIO_UNKNOWN_FILE_TYPE: + fmt = _("Unknown file type"); + buf = g_strdup_printf (fmt, newfile); + gnc_error_dialog(buf); + break; + case ERR_SQL_BAD_LOCATION: fmt = _("Can't parse the database URL\n %s\n"); buf = g_strdup_printf (fmt, newfile); diff --git a/src/engine/Account.c b/src/engine/Account.c index b0b286ff91..7c39b73972 100644 --- a/src/engine/Account.c +++ b/src/engine/Account.c @@ -336,7 +336,7 @@ xaccAccountCommitEdit (Account *acc) /* final stages of freeing the account */ if (acc->do_free) { - xaccRemoveAccount(acc); + xaccGroupRemoveAccount(acc->parent, acc); xaccFreeAccount(acc); } } @@ -642,22 +642,27 @@ xaccAccountInsertSplit (Account *acc, Split *split) * first. We don't want to ever leave the system in an inconsistent * state. Note that it might belong to the current account if we're * just using this call to re-order. */ - if (xaccSplitGetAccount(split)) + if (xaccSplitGetAccount(split) && + xaccSplitGetAccount(split) != acc) xaccAccountRemoveSplit (xaccSplitGetAccount(split), split); xaccSplitSetAccount(split, acc); - if (acc->editlevel == 1) + if(g_list_index(acc->splits, split) == -1) { - acc->splits = g_list_insert_sorted(acc->splits, split, split_sort_func); - acc->sort_dirty = FALSE; + if (acc->editlevel == 1) + { + acc->splits = g_list_insert_sorted(acc->splits, split, + split_sort_func); + acc->sort_dirty = FALSE; + } + else + acc->splits = g_list_prepend(acc->splits, split); + + mark_account (acc); + if (split->parent) + gnc_engine_generate_event (&split->parent->guid, GNC_EVENT_MODIFY); } - else - acc->splits = g_list_prepend(acc->splits, split); - - mark_account (acc); - if (split->parent) - gnc_engine_generate_event (&split->parent->guid, GNC_EVENT_MODIFY); - + xaccAccountCommitEdit(acc); } diff --git a/src/engine/Backend.h b/src/engine/Backend.h index e3caafca5b..208367181c 100644 --- a/src/engine/Backend.h +++ b/src/engine/Backend.h @@ -35,7 +35,8 @@ typedef enum { ERR_FILEIO_FILE_NOT_FOUND, /* not found / no such file */ ERR_FILEIO_FILE_TOO_NEW, /* file version newer than what we can read */ ERR_FILEIO_FILE_TOO_OLD, /* file version so old we can't read it */ - + ERR_FILEIO_UNKNOWN_FILE_TYPE, + /* network errors */ ERR_NETIO_NO_CONNECTION, /* network failure, can't connect to server */ ERR_NETIO_SHORT_READ, /* not enough bytes received */ diff --git a/src/engine/GNCId.c b/src/engine/GNCId.c index 8558687cab..64c5484536 100644 --- a/src/engine/GNCId.c +++ b/src/engine/GNCId.c @@ -280,6 +280,9 @@ xaccStoreEntity(void * entity, const GUID * guid, GNCIdType entity_type) e_node->entity = entity; new_guid = xaccGUIDMalloc(); + + if(!new_guid) return; + *new_guid = *guid; g_hash_table_insert(entity_table, new_guid, e_node); diff --git a/src/engine/Group.c b/src/engine/Group.c index 01ea902356..16cc07e7f2 100644 --- a/src/engine/Group.c +++ b/src/engine/Group.c @@ -528,17 +528,15 @@ xaccGetPeerAccountFromFullName (Account *acc, const char * name, \********************************************************************/ void -xaccRemoveGroup (AccountGroup *grp) +xaccAccountRemoveGroup (Account *acc) { - Account *acc; - - if (!grp) return; - - acc = grp->parent; + AccountGroup *grp; /* if this group has no parent, it must be the topgroup */ if (!acc) return; + grp = acc->children; + acc->children = NULL; /* make sure that the parent of the group is marked @@ -555,19 +553,15 @@ xaccRemoveGroup (AccountGroup *grp) \********************************************************************/ void -xaccRemoveAccount (Account *acc) +xaccGroupRemoveAccount (AccountGroup *grp, Account *acc) { - AccountGroup *grp; - if (!acc) return; - - grp = acc->parent; - acc->parent = NULL; - /* this routine might be called on accounts which * are not yet parented. */ if (!grp) return; + acc->parent = NULL; + grp->accounts = g_list_remove (grp->accounts, acc); grp->saved = 0; @@ -576,7 +570,7 @@ xaccRemoveAccount (Account *acc) * the group as well (unless its a root group) */ if ((grp->accounts == NULL) && (grp->parent)) { - xaccRemoveGroup (grp); + xaccAccountRemoveGroup (grp->parent); xaccFreeAccountGroup (grp); } @@ -636,7 +630,7 @@ xaccGroupInsertAccount (AccountGroup *grp, Account *acc) else { if (acc->parent) - xaccRemoveAccount (acc); + xaccGroupRemoveAccount (acc->parent, acc); /* set back-pointer to the account's parent */ acc->parent = grp; diff --git a/src/engine/Group.h b/src/engine/Group.h index 85cc152679..ca26792811 100644 --- a/src/engine/Group.h +++ b/src/engine/Group.h @@ -74,14 +74,14 @@ void xaccGroupMarkNotSaved (AccountGroup *grp); void xaccGroupMarkDoFree (AccountGroup *grp); /* - * The xaccRemoveAccount() subroutine will remove the indicated + * The xaccGroupRemoveAccount() subroutine will remove the indicated * account from its parent account group. It will NOT free the * associated memory or otherwise alter the account: the account * can now be reparented to a new location. * Note, however, that it will mark the old parents as having * been modified. * - * The xaccRemoveGroup() subroutine will remove the indicated + * The xaccAccountRemoveGroup() subroutine will remove the indicated * account group from its parent account. It will NOT free the * associated memory or otherwise alter the account group: the * account group can now be reparented to a new location. @@ -89,8 +89,8 @@ void xaccGroupMarkDoFree (AccountGroup *grp); * been modified. */ -void xaccRemoveAccount (Account *account); -void xaccRemoveGroup (AccountGroup *group); +void xaccGroupRemoveAccount (AccountGroup *grp, Account *account); +void xaccAccountRemoveGroup (Account *acc); void xaccGroupInsertAccount (AccountGroup *grp, Account *acc); void xaccAccountInsertSubAccount (Account *parent, Account *child); diff --git a/src/engine/gnc-account-xml-v2.c b/src/engine/gnc-account-xml-v2.c index c87500c560..d1109f316c 100644 --- a/src/engine/gnc-account-xml-v2.c +++ b/src/engine/gnc-account-xml-v2.c @@ -176,11 +176,15 @@ account_parent_handler (xmlNodePtr node, gpointer act) Account *parent; GUID *gid = dom_tree_to_guid(node); + g_return_val_if_fail(gid, FALSE); + parent = xaccAccountLookup(gid); + g_return_val_if_fail(parent, FALSE); + xaccAccountInsertSubAccount(parent, (Account*)act); - xaccGUIDFree(gid); + /* xaccGUIDFree(gid); */ return TRUE; } @@ -201,8 +205,8 @@ static struct dom_tree_handler account_handlers_v2[] = { { "act:id", account_id_handler, 1, 0 }, { "act:type", account_type_handler, 1, 0 }, { "act:currency", account_currency_handler, 1, 0 }, - { "act:code", account_code_handler, 1, 0 }, - { "act:description", account_description_handler, 1, 0}, + { "act:code", account_code_handler, 0, 0 }, + { "act:description", account_description_handler, 0, 0}, { "act:security", account_security_handler, 0, 0 }, { "act:slots", account_slots_handler, 0, 0 }, { "act:parent", account_parent_handler, 0, 0 }, diff --git a/src/engine/gnc-book.c b/src/engine/gnc-book.c index 9811994502..ea5bd77d35 100644 --- a/src/engine/gnc-book.c +++ b/src/engine/gnc-book.c @@ -55,7 +55,7 @@ #include "DateUtils.h" #include "io-gncxml.h" #include "io-gncbin.h" - +#include "io-gncxml-v2.h" #include "gnc-book.h" #include "gnc-book-p.h" @@ -81,7 +81,8 @@ struct _gnc_book * global vars. This may be a temp fix if we decide to integrate * FileIO errors into GNCBook errors. */ GNCBackendError last_err; - + char *error_message; + /* ---------------------------------------------------- */ /* the following struct members apply only for file-io */ /* the fully-resolved path to the file */ @@ -104,12 +105,18 @@ static void gnc_book_clear_error (GNCBook *book) { book->last_err = ERR_BACKEND_NO_ERR; + if(book->error_message) + { + g_free(book->error_message); + book->error_message = NULL; + } } static void -gnc_book_push_error (GNCBook *book, GNCBackendError err) +gnc_book_push_error (GNCBook *book, GNCBackendError err, char *message) { book->last_err = err; + book->error_message = message; } /* ---------------------------------------------------------------------- */ @@ -121,13 +128,27 @@ gnc_book_get_error (GNCBook * book) return book->last_err; } +static const char * +get_default_error_message(GNCBackendError err) +{ + return ""; +} + +const char * +gnc_book_get_error_message(GNCBook *book) +{ + if(!book) return ""; + if(!book->error_message) return get_default_error_message(book->last_err); + return book->error_message; +} + GNCBackendError gnc_book_pop_error (GNCBook * book) { GNCBackendError err; if (!book) return ERR_BACKEND_NO_BACKEND; err = book->last_err; - book->last_err = ERR_BACKEND_NO_ERR; + gnc_book_clear_error(book); return err; } @@ -262,7 +283,7 @@ gnc_book_get_file_lock (GNCBook *book) if (!rc) { /* oops .. file is all locked up .. */ - gnc_book_push_error (book, ERR_BACKEND_LOCKED); + gnc_book_push_error (book, ERR_BACKEND_LOCKED, NULL); return FALSE; } @@ -270,7 +291,7 @@ gnc_book_get_file_lock (GNCBook *book) if (book->lockfd < 0) { /* oops .. file is all locked up .. */ - gnc_book_push_error (book, ERR_BACKEND_LOCKED); + gnc_book_push_error (book, ERR_BACKEND_LOCKED, NULL); return FALSE; } @@ -298,7 +319,7 @@ gnc_book_get_file_lock (GNCBook *book) if (rc) { /* oops .. stat failed! This can't happen! */ - gnc_book_push_error (book, ERR_BACKEND_LOCKED); + gnc_book_push_error (book, ERR_BACKEND_LOCKED, NULL); unlink (pathbuf); close (book->lockfd); unlink (book->lockfile); @@ -308,7 +329,7 @@ gnc_book_get_file_lock (GNCBook *book) if (statbuf.st_nlink != 2) { /* oops .. stat failed! This can't happen! */ - gnc_book_push_error (book, ERR_BACKEND_LOCKED); + gnc_book_push_error (book, ERR_BACKEND_LOCKED, NULL); unlink (pathbuf); close (book->lockfd); unlink (book->lockfile); @@ -322,26 +343,55 @@ gnc_book_get_file_lock (GNCBook *book) /* ---------------------------------------------------------------------- */ +GNCBookFileType +gnc_book_determine_file_type(GNCBook *book) +{ + const gchar *name = gnc_book_get_file_path(book); + if(gnc_is_xml_data_file_v2(name)) { + return GNC_BOOK_XML2_FILE; + } else if(gnc_is_xml_data_file(name)) { + return GNC_BOOK_XML1_FILE; + } else { + return GNC_BOOK_BIN_FILE; + } +} + + /* Load financial data from a file into the book, automtically detecting the format of the file, if possible. Return FALSE on error, and set the error parameter to indicate what went wrong if it's not NULL. This function does not manage file locks in any way. */ +static gboolean +happy_or_push_error(GNCBook *book, gboolean errret, GNCBackendError errcode) +{ + if(errret) { + return TRUE; + } else { + gnc_book_push_error(book, errcode, NULL); + return FALSE; + } +} + static gboolean gnc_book_load_from_file(GNCBook *book) { const gchar *name = gnc_book_get_file_path(book); if(!name) return FALSE; - if(gnc_is_xml_data_file(name)) { - if(gnc_book_load_from_xml_file(book)) { - return TRUE; - } else { - gnc_book_push_error(book, ERR_BACKEND_MISC); - return FALSE; - } - } else { + switch (gnc_book_determine_file_type(book)) + { + case GNC_BOOK_XML2_FILE: + return happy_or_push_error(book, + gnc_book_load_from_xml_file_v2(book, NULL), + ERR_BACKEND_MISC); + case GNC_BOOK_XML1_FILE: + return happy_or_push_error(book, + gnc_book_load_from_xml_file(book), + ERR_BACKEND_MISC); + case GNC_BOOK_BIN_FILE: + { /* presume it's an old-style binary file */ GNCBackendError error; @@ -351,13 +401,16 @@ gnc_book_load_from_file(GNCBook *book) if(error == ERR_BACKEND_NO_ERR) { return TRUE; } else { - gnc_book_push_error(book, error); + gnc_book_push_error(book, error, NULL); return FALSE; } } - /* Should never get here */ - gnc_book_push_error(book, ERR_BACKEND_MISC); - return FALSE; + default: + g_warning("File not any known type"); + gnc_book_push_error(book, ERR_FILEIO_UNKNOWN_FILE_TYPE, NULL); + return FALSE; + break; + } } /* ---------------------------------------------------------------------- */ @@ -379,7 +432,7 @@ gnc_book_write_to_file(GNCBook *book, const gchar *datafile = gnc_book_get_file_path(book); if(!gnc_book_write_to_xml_file(book, datafile)) { - gnc_book_push_error(book, ERR_BACKEND_MISC); + gnc_book_push_error(book, ERR_BACKEND_MISC, NULL); return FALSE; } @@ -407,13 +460,13 @@ gnc_book_write_to_file(GNCBook *book, free (backup); return TRUE; } else { - gnc_book_push_error(book, ERR_BACKEND_MISC); + gnc_book_push_error(book, ERR_BACKEND_MISC, NULL); free (backup); return FALSE; } } /* Should never get here */ - gnc_book_push_error(book, ERR_BACKEND_MISC); + gnc_book_push_error(book, ERR_BACKEND_MISC, NULL); return FALSE; } @@ -430,7 +483,7 @@ gnc_book_begin_file (GNCBook *book, const char * filefrag, book->fullpath = xaccResolveFilePath (filefrag); if (!book->fullpath) { - gnc_book_push_error (book, ERR_FILEIO_FILE_NOT_FOUND); + gnc_book_push_error (book, ERR_FILEIO_FILE_NOT_FOUND, NULL); return FALSE; /* ouch */ } @@ -445,7 +498,7 @@ gnc_book_begin_file (GNCBook *book, const char * filefrag, if (!ignore_lock && !gnc_book_get_file_lock (book)) { - gnc_book_push_error (book, ERR_BACKEND_LOCKED); + gnc_book_push_error (book, ERR_BACKEND_LOCKED, NULL); g_free (book->book_id); book->book_id = NULL; g_free (book->fullpath); book->fullpath = NULL; g_free (book->lockfile); book->lockfile = NULL; @@ -473,14 +526,14 @@ gnc_book_begin (GNCBook *book, const char * book_id, /* check to see if this session is already open */ if (book->book_id) { - gnc_book_push_error (book, ERR_BACKEND_LOCKED); + gnc_book_push_error (book, ERR_BACKEND_LOCKED, NULL); return FALSE; } /* seriously invalid */ if (!book_id) { - gnc_book_push_error (book, ERR_BACKEND_NO_BACKEND); + gnc_book_push_error (book, ERR_BACKEND_NO_BACKEND, NULL); return FALSE; } @@ -519,7 +572,7 @@ gnc_book_begin (GNCBook *book, const char * book_id, g_free (filefrag); if (!book->fullpath) { - gnc_book_push_error (book, ERR_FILEIO_FILE_NOT_FOUND); + gnc_book_push_error (book, ERR_FILEIO_FILE_NOT_FOUND, NULL); return FALSE; /* ouch */ } PINFO ("filepath=%s\n", book->fullpath); @@ -550,7 +603,7 @@ gnc_book_begin (GNCBook *book, const char * book_id, book->fullpath = NULL; g_free(book->book_id); book->book_id = NULL; - gnc_book_push_error (book, ERR_BACKEND_NO_BACKEND); + gnc_book_push_error (book, ERR_BACKEND_NO_BACKEND, NULL); return FALSE; } @@ -566,7 +619,7 @@ gnc_book_begin (GNCBook *book, const char * book_id, book->fullpath = NULL; g_free(book->book_id); book->book_id = NULL; - gnc_book_push_error (book, ERR_BACKEND_NO_BACKEND); + gnc_book_push_error (book, ERR_BACKEND_NO_BACKEND, NULL); return FALSE; } @@ -589,7 +642,7 @@ gnc_book_begin (GNCBook *book, const char * book_id, book->fullpath = NULL; g_free(book->book_id); book->book_id = NULL; - gnc_book_push_error (book, ERR_BACKEND_NO_BACKEND); + gnc_book_push_error (book, ERR_BACKEND_NO_BACKEND, NULL); return FALSE; } @@ -605,7 +658,7 @@ gnc_book_begin (GNCBook *book, const char * book_id, book->fullpath = NULL; g_free(book->book_id); book->book_id = NULL; - gnc_book_push_error (book, ERR_BACKEND_NO_BACKEND); + gnc_book_push_error (book, ERR_BACKEND_NO_BACKEND, NULL); return FALSE; } @@ -627,7 +680,7 @@ gnc_book_begin (GNCBook *book, const char * book_id, book->fullpath = NULL; g_free(book->book_id); book->book_id = NULL; - gnc_book_push_error (book, err); + gnc_book_push_error (book, err, NULL); return FALSE; } } @@ -659,7 +712,7 @@ gnc_book_load (GNCBook *book) if (!book->lockfile) { - gnc_book_push_error (book, ERR_BACKEND_LOCKED); + gnc_book_push_error (book, ERR_BACKEND_LOCKED, NULL); return FALSE; } @@ -723,7 +776,7 @@ gnc_book_load (GNCBook *book) xaccGroupSetBackend (book->topgroup, be); - gnc_book_push_error(book, xaccBackendGetError(be)); + gnc_book_push_error(book, xaccBackendGetError(be), NULL); xaccLogEnable(); } @@ -732,7 +785,7 @@ gnc_book_load (GNCBook *book) } else { - gnc_book_push_error (book, ERR_BACKEND_NO_BACKEND); + gnc_book_push_error (book, ERR_BACKEND_NO_BACKEND, NULL); return FALSE; } } @@ -792,7 +845,7 @@ gnc_book_save (GNCBook *book) err = xaccBackendGetError(be); if (ERR_BACKEND_NO_ERR != err) { - gnc_book_push_error (book, err); + gnc_book_push_error (book, err, NULL); /* we close the backend here ... isn't this a bit harsh ??? */ if (be->book_end) { @@ -808,13 +861,13 @@ gnc_book_save (GNCBook *book) if (!book->fullpath) { - gnc_book_push_error (book, ERR_BACKEND_MISC); + gnc_book_push_error (book, ERR_BACKEND_MISC, NULL); return; } if (book->topgroup) { if(!gnc_book_write_to_file(book, TRUE)) { - gnc_book_push_error (book, ERR_BACKEND_MISC); + gnc_book_push_error (book, ERR_BACKEND_MISC, NULL); } } LEAVE(" "); diff --git a/src/engine/gnc-book.h b/src/engine/gnc-book.h index c5d8541f41..423ae6d355 100644 --- a/src/engine/gnc-book.h +++ b/src/engine/gnc-book.h @@ -115,6 +115,7 @@ gboolean gnc_book_load (GNCBook *book); * See Backend.h for a listing of returned errors. */ GNCBackendError gnc_book_get_error (GNCBook *book); +const char * gnc_book_get_error_message(GNCBook *book); GNCBackendError gnc_book_pop_error (GNCBook *book); @@ -191,6 +192,18 @@ gboolean gnc_book_process_events (GNCBook *book); char * xaccResolveFilePath (const char * filefrag); char * xaccResolveURL (const char * pathfrag); +/* + * Determine the load file type + */ +typedef enum +{ + GNC_BOOK_NOT_OURS, + GNC_BOOK_BIN_FILE, + GNC_BOOK_XML1_FILE, + GNC_BOOK_XML2_FILE, +} GNCBookFileType; +GNCBookFileType gnc_book_determine_file_type(GNCBook *book); + /* Run the RPC Server */ void gnc_run_rpc_server (void); diff --git a/src/engine/gnc-pricedb-xml-v1.c b/src/engine/gnc-pricedb-xml-v1.c index 07aefac1bc..71114d9494 100644 --- a/src/engine/gnc-pricedb-xml-v1.c +++ b/src/engine/gnc-pricedb-xml-v1.c @@ -277,6 +277,16 @@ pricedb_v2_end_handler( GNCPriceDB *db = (GNCPriceDB*)result; sixtp_gdv2* globaldata = (sixtp_gdv2*)global_data; + if(parent_data) + { + return TRUE; + } + + if(!tag) + { + return TRUE; + } + globaldata->addPriceDBFunc(globaldata, db); return TRUE; diff --git a/src/engine/gnc-transaction-xml-v2.c b/src/engine/gnc-transaction-xml-v2.c index 20abd8dbd8..768c2c7d53 100644 --- a/src/engine/gnc-transaction-xml-v2.c +++ b/src/engine/gnc-transaction-xml-v2.c @@ -69,10 +69,14 @@ split_to_dom_tree(const gchar *tag, Split *spl) ret = xmlNewNode(NULL, tag); xmlAddChild(ret, guid_to_dom_tree("split:id", xaccSplitGetGUID(spl))); - - if(xaccSplitGetMemo(spl)) + { - xmlNewTextChild(ret, NULL, "split:memo", xaccSplitGetMemo(spl)); + const char *memo = xaccSplitGetMemo(spl); + + if(memo && safe_strcmp(memo, "") != 0) + { + xmlNewTextChild(ret, NULL, "split:memo", memo); + } } { @@ -433,7 +437,7 @@ struct dom_tree_handler trn_dom_handlers[] = { "trn:date-posted", trn_date_posted_handler, 1, 0 }, { "trn:date-entered", trn_date_entered_handler, 1, 0 }, { "trn:description", trn_description_handler, 0, 0 }, - { "trn:slots", trn_slots_handler, 1, 0 }, + { "trn:slots", trn_slots_handler, 0, 0 }, { "trn:splits", trn_splits_handler, 1, 0 }, { NULL, NULL, 0, 0 }, }; diff --git a/src/engine/io-gncxml-r.c b/src/engine/io-gncxml-r.c index 9e64fccd55..4abb68b9eb 100644 --- a/src/engine/io-gncxml-r.c +++ b/src/engine/io-gncxml-r.c @@ -351,32 +351,7 @@ gnc_book_load_from_xml_file(GNCBook *book) gboolean gnc_is_xml_data_file(const gchar *filename) { - FILE *f = NULL; - char first_chunk[256]; - const char* cursor = NULL; - ssize_t num_read; - gboolean result = FALSE; - - g_return_val_if_fail(filename, result); - - f = fopen(filename, "r"); - if (!f) - return result; - - num_read = fread(first_chunk, sizeof(char), sizeof(first_chunk) - 1, f); - if(num_read == 0) goto cleanup_and_exit; - first_chunk[num_read] = '\0'; - - cursor = first_chunk; - while(*cursor && isspace(*cursor)) cursor++; - - if(cursor && strncmp(cursor, "countCallback) + { + data->countCallback(type, data->counter); + } +} + static void clear_up_account_commodity( GNCBook *book, Account *act, gnc_commodity * (*getter) (Account *account), @@ -58,6 +67,8 @@ add_account_local(sixtp_gdv2 *data, Account *act) xaccGroupInsertAccount(gnc_book_get_group(data->book), act); } data->counter.accounts_loaded++; + run_callback(data, "account"); + return FALSE; } @@ -66,6 +77,7 @@ add_commodity_local(sixtp_gdv2 *data, gnc_commodity *com) { gnc_commodity_table_insert(gnc_book_get_commodity_table(data->book), com); data->counter.commodities_loaded++; + run_callback(data, "commodities"); return TRUE; } @@ -83,17 +95,14 @@ add_transaction_local(sixtp_gdv2 *data, Transaction *trn) } data->counter.transactions_loaded++; + run_callback(data, "transaction"); + return TRUE; } static gboolean add_pricedb_local(sixtp_gdv2 *data, GNCPriceDB *db) { - if(!db) - { - db = gnc_pricedb_create(); - } - if(gnc_book_get_pricedb(data->book)) { gnc_pricedb_destroy(gnc_book_get_pricedb(data->book)); @@ -166,7 +175,7 @@ gnc_counter_sixtp_parser_create(void) } static void -print_counter_data(struct _load_counter_struct data) +print_counter_data(load_counter data) { printf("Transactions: Total: %d, Loaded: %d\n", data.transactions_total, data.transactions_loaded); @@ -177,14 +186,25 @@ print_counter_data(struct _load_counter_struct data) } gboolean -gnc_book_load_from_xml_file_v2(GNCBook *book) +gnc_book_load_from_xml_file_v2( + GNCBook *book, + void (*countcallback)(const char *type, load_counter count)) { sixtp_gdv2 gd; - sixtp *parser; + sixtp *top_parser; + sixtp *main_parser; gpointer parse_result = NULL; - + gd.book = book; - + gd.counter.accounts_loaded = 0; + gd.counter.accounts_total = 0; + gd.counter.commodities_loaded = 0; + gd.counter.commodities_total = 0; + gd.counter.transactions_loaded = 0; + gd.counter.transactions_total = 0; + gd.counter.prices_loaded = 0; + gd.counter.prices_total = 0; + { AccountGroup *g = gnc_book_get_group(book); if(g) xaccFreeAccountGroup(g); @@ -195,25 +215,35 @@ gnc_book_load_from_xml_file_v2(GNCBook *book) gd.addCommodityFunc = add_commodity_local; gd.addTransactionFunc = add_transaction_local; gd.addPriceDBFunc = add_pricedb_local; + gd.countCallback = countcallback; + + top_parser = sixtp_new(); + main_parser = sixtp_new(); - parser = sixtp_new(); - if(!sixtp_add_some_sub_parsers( - parser, TRUE, + top_parser, TRUE, + "gnc-v2", main_parser, + NULL, NULL)) + { + return FALSE; + } + + if(!sixtp_add_some_sub_parsers( + main_parser, TRUE, "gnc:count-data", gnc_counter_sixtp_parser_create(), "gnc:pricedb", gnc_pricedb_sixtp_parser_create(), "gnc:commodity", gnc_commodity_sixtp_parser_create(), - "gnc:accout", gnc_account_sixtp_parser_create(), - "gnc:transactions", gnc_transaction_sixtp_parser_create(), + "gnc:account", gnc_account_sixtp_parser_create(), + "gnc:transaction", gnc_transaction_sixtp_parser_create(), NULL, NULL)) { return FALSE; } - if(!sixtp_parse_file(parser, gnc_book_get_file_path(book), + if(!sixtp_parse_file(top_parser, gnc_book_get_file_path(book), NULL, &gd, &parse_result)) { - sixtp_destroy(parser); + sixtp_destroy(top_parser); return FALSE; } else @@ -432,98 +462,9 @@ gnc_book_write_to_xml_file_v2(GNCBook *book, const char *filename) } /***********************************************************************/ - -static gboolean -eat_whitespace(char **cursor) -{ - while(**cursor && isspace(**cursor)) - { - *cursor++; - } - - if(**cursor == '\0') - { - return FALSE; - } - else - { - return TRUE; - } -} - -static gboolean -search_for(char marker, char **cursor) -{ - while(**cursor && **cursor != marker) - { - *cursor++; - } - - if(**cursor == '\0') - { - return FALSE; - } - else - { - return TRUE; - } -} - gboolean gnc_is_xml_data_file_v2(const gchar *name) { - FILE *f = NULL; - char first_chunk[256]; - char* cursor = NULL; - ssize_t num_read; - - g_return_val_if_fail(name, FALSE); - - f = fopen(name, "r"); - g_return_val_if_fail(f, FALSE); - - num_read = fread(first_chunk, sizeof(char), sizeof(first_chunk) - 1, f); - fclose(f); - - if(num_read == 0) - { - return FALSE; - } - - first_chunk[num_read] = '\0'; - - cursor = first_chunk; - - if(!eat_whitespace(&cursor)) - { - return FALSE; - } - - if(strncmp(cursor, "', &cursor)) - { - return FALSE; - } - - if(!eat_whitespace(&cursor)) - { - return FALSE; - } - - if(strncmp(cursor, "xmlChildrenNode, NULL); + /* no nodes means it's an empty string text */ + if(!tree->xmlChildrenNode) + { + return g_strdup(""); + } result = g_strdup(""); diff --git a/src/engine/sixtp.c b/src/engine/sixtp.c index 8d881d055d..bf50f605aa 100644 --- a/src/engine/sixtp.c +++ b/src/engine/sixtp.c @@ -24,7 +24,8 @@ #include "config.h" #include - +#include +#include #include #include "sixtp.h" @@ -697,3 +698,103 @@ sixtp_parse_buffer(sixtp *sixtp, return FALSE; } } + +/***********************************************************************/ +static gboolean +eat_whitespace(char **cursor) +{ + while(**cursor && isspace(**cursor)) + { + (*cursor)++; + } + + if(**cursor == '\0') + { + return FALSE; + } + else + { + return TRUE; + } +} + +static gboolean +search_for(char marker, char **cursor) +{ + while(**cursor && **cursor != marker) + { + (*cursor)++; + } + + if(**cursor == '\0') + { + return FALSE; + } + else + { + (*cursor)++; + return TRUE; + } +} + +gboolean +gnc_is_our_xml_file(const char *filename, const char *first_tag) +{ + FILE *f = NULL; + char first_chunk[256]; + char* cursor = NULL; + ssize_t num_read; + char *tag_compare; + + g_return_val_if_fail(filename, FALSE); + g_return_val_if_fail(first_tag, FALSE); + + f = fopen(filename, "r"); + g_return_val_if_fail(f, FALSE); + + tag_compare = g_strdup_printf("<%s>", first_tag); + + num_read = fread(first_chunk, sizeof(char), sizeof(first_chunk) - 1, f); + fclose(f); + + if(num_read == 0) + { + return FALSE; + } + + first_chunk[num_read] = '\0'; + + cursor = first_chunk; + + if(!eat_whitespace(&cursor)) + { + return FALSE; + } + + if(strncmp(cursor, "', &cursor)) + { + return FALSE; + } + + if(!eat_whitespace(&cursor)) + { + return FALSE; + } + + if(strncmp(cursor, tag_compare, strlen(tag_compare)) == 0) + { + return TRUE; + } + else + { + return FALSE; + } + } + else + { + return FALSE; + } + return FALSE; +} diff --git a/src/engine/sixtp.h b/src/engine/sixtp.h index e76f8c362c..753de70d1b 100644 --- a/src/engine/sixtp.h +++ b/src/engine/sixtp.h @@ -194,5 +194,7 @@ sixtp* sixtp_add_some_sub_parsers(sixtp *tochange, gboolean cleanup, ...); gboolean sixtp_add_sub_parser(sixtp *parser, const gchar* tag, sixtp *sub_parser); +gboolean gnc_is_our_xml_file(const char *filename, const char *first_tag); + #endif /* _SIXTP_H_ */ diff --git a/src/gnome/cursors.c b/src/gnome/cursors.c index fd000f9233..2446760298 100644 --- a/src/gnome/cursors.c +++ b/src/gnome/cursors.c @@ -74,6 +74,11 @@ set_cursor_helper (gpointer window, gpointer data) GtkWidget *widget = GTK_WIDGET(window); int type = GPOINTER_TO_INT(data); + if(!window) + { + return; + } + gnc_ui_set_cursor (widget->window, type); }