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
This commit is contained in:
Dave Peticolas 2001-03-22 08:02:48 +00:00
parent d72f8ed668
commit 96372a16ed
19 changed files with 468 additions and 214 deletions

130
ChangeLog
View File

@ -49,6 +49,71 @@
* src/gnome/window-register.c: add arguments to report window * src/gnome/window-register.c: add arguments to report window
for title & debit/credit strings for title & debit/credit strings
2001-03-21 James LewisMoss <jimdres@mindspring.com>
* 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 <stimming@tuhh.de> 2001-03-20 Christian Stimming <stimming@tuhh.de>
* src/scm/report/income-expense-graph.scm, * src/scm/report/income-expense-graph.scm,
@ -94,6 +159,51 @@
* src/scm/html-utilities.scm: add function for assigning colors * src/scm/html-utilities.scm: add function for assigning colors
2001-03-20 James LewisMoss <jimdres@mindspring.com>
* 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 <dave@krondo.com> 2001-03-19 Dave Peticolas <dave@krondo.com>
* src/gnome/gnc-html-guppi.c: fix callback pointer * 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 * src/engine/Query.c: handle NULL pointers, add api to get list
of splits with unique transactions of splits with unique transactions
2001-03-15 James LewisMoss <jimdres@mindspring.com>
* 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 <dave@krondo.com> 2001-03-14 Dave Peticolas <dave@krondo.com>
* rpm/gnucash.spec.in: simplify * rpm/gnucash.spec.in: simplify
@ -350,6 +467,14 @@
* doc/sgml/C/xacc-dochack.sgml: remove and fix broken links * doc/sgml/C/xacc-dochack.sgml: remove and fix broken links
2001-03-14 James LewisMoss <jimdres@mindspring.com>
* 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 <dave@krondo.com> 2001-03-13 Dave Peticolas <dave@krondo.com>
* src/engine/io-gncxml-r.c (gnc_is_xml_data_file): don't print * src/engine/io-gncxml-r.c (gnc_is_xml_data_file): don't print
@ -384,6 +509,11 @@
2001-03-13 James LewisMoss <jimdres@mindspring.com> 2001-03-13 James LewisMoss <jimdres@mindspring.com>
* 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 * src/engine/io-gncxml-v2.c (gnc_counter_end_handler): complete
func. func.
(print_counter_data): new func. (print_counter_data): new func.

View File

@ -116,6 +116,12 @@ show_book_error (GNCBackendError io_error, const char *newfile)
if (gnc_verify_dialog (fmt, TRUE)) { uh_oh = FALSE; } if (gnc_verify_dialog (fmt, TRUE)) { uh_oh = FALSE; }
break; 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: case ERR_SQL_BAD_LOCATION:
fmt = _("Can't parse the database URL\n %s\n"); fmt = _("Can't parse the database URL\n %s\n");
buf = g_strdup_printf (fmt, newfile); buf = g_strdup_printf (fmt, newfile);

View File

@ -336,7 +336,7 @@ xaccAccountCommitEdit (Account *acc)
/* final stages of freeing the account */ /* final stages of freeing the account */
if (acc->do_free) if (acc->do_free)
{ {
xaccRemoveAccount(acc); xaccGroupRemoveAccount(acc->parent, acc);
xaccFreeAccount(acc); xaccFreeAccount(acc);
} }
} }
@ -642,13 +642,17 @@ xaccAccountInsertSplit (Account *acc, Split *split)
* first. We don't want to ever leave the system in an inconsistent * 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 * state. Note that it might belong to the current account if we're
* just using this call to re-order. */ * just using this call to re-order. */
if (xaccSplitGetAccount(split)) if (xaccSplitGetAccount(split) &&
xaccSplitGetAccount(split) != acc)
xaccAccountRemoveSplit (xaccSplitGetAccount(split), split); xaccAccountRemoveSplit (xaccSplitGetAccount(split), split);
xaccSplitSetAccount(split, acc); xaccSplitSetAccount(split, acc);
if(g_list_index(acc->splits, split) == -1)
{
if (acc->editlevel == 1) if (acc->editlevel == 1)
{ {
acc->splits = g_list_insert_sorted(acc->splits, split, split_sort_func); acc->splits = g_list_insert_sorted(acc->splits, split,
split_sort_func);
acc->sort_dirty = FALSE; acc->sort_dirty = FALSE;
} }
else else
@ -657,6 +661,7 @@ xaccAccountInsertSplit (Account *acc, Split *split)
mark_account (acc); mark_account (acc);
if (split->parent) if (split->parent)
gnc_engine_generate_event (&split->parent->guid, GNC_EVENT_MODIFY); gnc_engine_generate_event (&split->parent->guid, GNC_EVENT_MODIFY);
}
xaccAccountCommitEdit(acc); xaccAccountCommitEdit(acc);
} }

View File

@ -35,6 +35,7 @@ typedef enum {
ERR_FILEIO_FILE_NOT_FOUND, /* not found / no such file */ 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_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_FILE_TOO_OLD, /* file version so old we can't read it */
ERR_FILEIO_UNKNOWN_FILE_TYPE,
/* network errors */ /* network errors */
ERR_NETIO_NO_CONNECTION, /* network failure, can't connect to server */ ERR_NETIO_NO_CONNECTION, /* network failure, can't connect to server */

View File

@ -280,6 +280,9 @@ xaccStoreEntity(void * entity, const GUID * guid, GNCIdType entity_type)
e_node->entity = entity; e_node->entity = entity;
new_guid = xaccGUIDMalloc(); new_guid = xaccGUIDMalloc();
if(!new_guid) return;
*new_guid = *guid; *new_guid = *guid;
g_hash_table_insert(entity_table, new_guid, e_node); g_hash_table_insert(entity_table, new_guid, e_node);

View File

@ -528,17 +528,15 @@ xaccGetPeerAccountFromFullName (Account *acc, const char * name,
\********************************************************************/ \********************************************************************/
void void
xaccRemoveGroup (AccountGroup *grp) xaccAccountRemoveGroup (Account *acc)
{ {
Account *acc; AccountGroup *grp;
if (!grp) return;
acc = grp->parent;
/* if this group has no parent, it must be the topgroup */ /* if this group has no parent, it must be the topgroup */
if (!acc) return; if (!acc) return;
grp = acc->children;
acc->children = NULL; acc->children = NULL;
/* make sure that the parent of the group is marked /* make sure that the parent of the group is marked
@ -555,19 +553,15 @@ xaccRemoveGroup (AccountGroup *grp)
\********************************************************************/ \********************************************************************/
void void
xaccRemoveAccount (Account *acc) xaccGroupRemoveAccount (AccountGroup *grp, Account *acc)
{ {
AccountGroup *grp;
if (!acc) return; if (!acc) return;
grp = acc->parent;
acc->parent = NULL;
/* this routine might be called on accounts which /* this routine might be called on accounts which
* are not yet parented. */ * are not yet parented. */
if (!grp) return; if (!grp) return;
acc->parent = NULL;
grp->accounts = g_list_remove (grp->accounts, acc); grp->accounts = g_list_remove (grp->accounts, acc);
grp->saved = 0; grp->saved = 0;
@ -576,7 +570,7 @@ xaccRemoveAccount (Account *acc)
* the group as well (unless its a root group) */ * the group as well (unless its a root group) */
if ((grp->accounts == NULL) && (grp->parent)) if ((grp->accounts == NULL) && (grp->parent))
{ {
xaccRemoveGroup (grp); xaccAccountRemoveGroup (grp->parent);
xaccFreeAccountGroup (grp); xaccFreeAccountGroup (grp);
} }
@ -636,7 +630,7 @@ xaccGroupInsertAccount (AccountGroup *grp, Account *acc)
else else
{ {
if (acc->parent) if (acc->parent)
xaccRemoveAccount (acc); xaccGroupRemoveAccount (acc->parent, acc);
/* set back-pointer to the account's parent */ /* set back-pointer to the account's parent */
acc->parent = grp; acc->parent = grp;

View File

@ -74,14 +74,14 @@ void xaccGroupMarkNotSaved (AccountGroup *grp);
void xaccGroupMarkDoFree (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 * account from its parent account group. It will NOT free the
* associated memory or otherwise alter the account: the account * associated memory or otherwise alter the account: the account
* can now be reparented to a new location. * can now be reparented to a new location.
* Note, however, that it will mark the old parents as having * Note, however, that it will mark the old parents as having
* been modified. * 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 * account group from its parent account. It will NOT free the
* associated memory or otherwise alter the account group: the * associated memory or otherwise alter the account group: the
* account group can now be reparented to a new location. * account group can now be reparented to a new location.
@ -89,8 +89,8 @@ void xaccGroupMarkDoFree (AccountGroup *grp);
* been modified. * been modified.
*/ */
void xaccRemoveAccount (Account *account); void xaccGroupRemoveAccount (AccountGroup *grp, Account *account);
void xaccRemoveGroup (AccountGroup *group); void xaccAccountRemoveGroup (Account *acc);
void xaccGroupInsertAccount (AccountGroup *grp, Account *acc); void xaccGroupInsertAccount (AccountGroup *grp, Account *acc);
void xaccAccountInsertSubAccount (Account *parent, Account *child); void xaccAccountInsertSubAccount (Account *parent, Account *child);

View File

@ -176,11 +176,15 @@ account_parent_handler (xmlNodePtr node, gpointer act)
Account *parent; Account *parent;
GUID *gid = dom_tree_to_guid(node); GUID *gid = dom_tree_to_guid(node);
g_return_val_if_fail(gid, FALSE);
parent = xaccAccountLookup(gid); parent = xaccAccountLookup(gid);
g_return_val_if_fail(parent, FALSE);
xaccAccountInsertSubAccount(parent, (Account*)act); xaccAccountInsertSubAccount(parent, (Account*)act);
xaccGUIDFree(gid); /* xaccGUIDFree(gid); */
return TRUE; return TRUE;
} }
@ -201,8 +205,8 @@ static struct dom_tree_handler account_handlers_v2[] = {
{ "act:id", account_id_handler, 1, 0 }, { "act:id", account_id_handler, 1, 0 },
{ "act:type", account_type_handler, 1, 0 }, { "act:type", account_type_handler, 1, 0 },
{ "act:currency", account_currency_handler, 1, 0 }, { "act:currency", account_currency_handler, 1, 0 },
{ "act:code", account_code_handler, 1, 0 }, { "act:code", account_code_handler, 0, 0 },
{ "act:description", account_description_handler, 1, 0}, { "act:description", account_description_handler, 0, 0},
{ "act:security", account_security_handler, 0, 0 }, { "act:security", account_security_handler, 0, 0 },
{ "act:slots", account_slots_handler, 0, 0 }, { "act:slots", account_slots_handler, 0, 0 },
{ "act:parent", account_parent_handler, 0, 0 }, { "act:parent", account_parent_handler, 0, 0 },

View File

@ -55,7 +55,7 @@
#include "DateUtils.h" #include "DateUtils.h"
#include "io-gncxml.h" #include "io-gncxml.h"
#include "io-gncbin.h" #include "io-gncbin.h"
#include "io-gncxml-v2.h"
#include "gnc-book.h" #include "gnc-book.h"
#include "gnc-book-p.h" #include "gnc-book-p.h"
@ -81,6 +81,7 @@ struct _gnc_book
* global vars. This may be a temp fix if we decide to integrate * global vars. This may be a temp fix if we decide to integrate
* FileIO errors into GNCBook errors. */ * FileIO errors into GNCBook errors. */
GNCBackendError last_err; GNCBackendError last_err;
char *error_message;
/* ---------------------------------------------------- */ /* ---------------------------------------------------- */
/* the following struct members apply only for file-io */ /* the following struct members apply only for file-io */
@ -104,12 +105,18 @@ static void
gnc_book_clear_error (GNCBook *book) gnc_book_clear_error (GNCBook *book)
{ {
book->last_err = ERR_BACKEND_NO_ERR; book->last_err = ERR_BACKEND_NO_ERR;
if(book->error_message)
{
g_free(book->error_message);
book->error_message = NULL;
}
} }
static void 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->last_err = err;
book->error_message = message;
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -121,13 +128,27 @@ gnc_book_get_error (GNCBook * book)
return book->last_err; 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 GNCBackendError
gnc_book_pop_error (GNCBook * book) gnc_book_pop_error (GNCBook * book)
{ {
GNCBackendError err; GNCBackendError err;
if (!book) return ERR_BACKEND_NO_BACKEND; if (!book) return ERR_BACKEND_NO_BACKEND;
err = book->last_err; err = book->last_err;
book->last_err = ERR_BACKEND_NO_ERR; gnc_book_clear_error(book);
return err; return err;
} }
@ -262,7 +283,7 @@ gnc_book_get_file_lock (GNCBook *book)
if (!rc) if (!rc)
{ {
/* oops .. file is all locked up .. */ /* 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; return FALSE;
} }
@ -270,7 +291,7 @@ gnc_book_get_file_lock (GNCBook *book)
if (book->lockfd < 0) if (book->lockfd < 0)
{ {
/* oops .. file is all locked up .. */ /* 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; return FALSE;
} }
@ -298,7 +319,7 @@ gnc_book_get_file_lock (GNCBook *book)
if (rc) if (rc)
{ {
/* oops .. stat failed! This can't happen! */ /* 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); unlink (pathbuf);
close (book->lockfd); close (book->lockfd);
unlink (book->lockfile); unlink (book->lockfile);
@ -308,7 +329,7 @@ gnc_book_get_file_lock (GNCBook *book)
if (statbuf.st_nlink != 2) if (statbuf.st_nlink != 2)
{ {
/* oops .. stat failed! This can't happen! */ /* 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); unlink (pathbuf);
close (book->lockfd); close (book->lockfd);
unlink (book->lockfile); 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 /* Load financial data from a file into the book, automtically
detecting the format of the file, if possible. Return FALSE on detecting the format of the file, if possible. Return FALSE on
error, and set the error parameter to indicate what went wrong if 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 it's not NULL. This function does not manage file locks in any
way. */ 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 static gboolean
gnc_book_load_from_file(GNCBook *book) gnc_book_load_from_file(GNCBook *book)
{ {
const gchar *name = gnc_book_get_file_path(book); const gchar *name = gnc_book_get_file_path(book);
if(!name) return FALSE; if(!name) return FALSE;
if(gnc_is_xml_data_file(name)) { switch (gnc_book_determine_file_type(book))
if(gnc_book_load_from_xml_file(book)) { {
return TRUE; case GNC_BOOK_XML2_FILE:
} else { return happy_or_push_error(book,
gnc_book_push_error(book, ERR_BACKEND_MISC); gnc_book_load_from_xml_file_v2(book, NULL),
return FALSE; ERR_BACKEND_MISC);
} case GNC_BOOK_XML1_FILE:
} else { 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 */ /* presume it's an old-style binary file */
GNCBackendError error; GNCBackendError error;
@ -351,13 +401,16 @@ gnc_book_load_from_file(GNCBook *book)
if(error == ERR_BACKEND_NO_ERR) { if(error == ERR_BACKEND_NO_ERR) {
return TRUE; return TRUE;
} else { } else {
gnc_book_push_error(book, error); gnc_book_push_error(book, error, NULL);
return FALSE; return FALSE;
} }
} }
/* Should never get here */ default:
gnc_book_push_error(book, ERR_BACKEND_MISC); g_warning("File not any known type");
gnc_book_push_error(book, ERR_FILEIO_UNKNOWN_FILE_TYPE, NULL);
return FALSE; return FALSE;
break;
}
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -379,7 +432,7 @@ gnc_book_write_to_file(GNCBook *book,
const gchar *datafile = gnc_book_get_file_path(book); const gchar *datafile = gnc_book_get_file_path(book);
if(!gnc_book_write_to_xml_file(book, datafile)) { 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; return FALSE;
} }
@ -407,13 +460,13 @@ gnc_book_write_to_file(GNCBook *book,
free (backup); free (backup);
return TRUE; return TRUE;
} else { } else {
gnc_book_push_error(book, ERR_BACKEND_MISC); gnc_book_push_error(book, ERR_BACKEND_MISC, NULL);
free (backup); free (backup);
return FALSE; return FALSE;
} }
} }
/* Should never get here */ /* Should never get here */
gnc_book_push_error(book, ERR_BACKEND_MISC); gnc_book_push_error(book, ERR_BACKEND_MISC, NULL);
return FALSE; return FALSE;
} }
@ -430,7 +483,7 @@ gnc_book_begin_file (GNCBook *book, const char * filefrag,
book->fullpath = xaccResolveFilePath (filefrag); book->fullpath = xaccResolveFilePath (filefrag);
if (!book->fullpath) 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 */ 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)) 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->book_id); book->book_id = NULL;
g_free (book->fullpath); book->fullpath = NULL; g_free (book->fullpath); book->fullpath = NULL;
g_free (book->lockfile); book->lockfile = 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 */ /* check to see if this session is already open */
if (book->book_id) if (book->book_id)
{ {
gnc_book_push_error (book, ERR_BACKEND_LOCKED); gnc_book_push_error (book, ERR_BACKEND_LOCKED, NULL);
return FALSE; return FALSE;
} }
/* seriously invalid */ /* seriously invalid */
if (!book_id) if (!book_id)
{ {
gnc_book_push_error (book, ERR_BACKEND_NO_BACKEND); gnc_book_push_error (book, ERR_BACKEND_NO_BACKEND, NULL);
return FALSE; return FALSE;
} }
@ -519,7 +572,7 @@ gnc_book_begin (GNCBook *book, const char * book_id,
g_free (filefrag); g_free (filefrag);
if (!book->fullpath) 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 */ return FALSE; /* ouch */
} }
PINFO ("filepath=%s\n", book->fullpath); PINFO ("filepath=%s\n", book->fullpath);
@ -550,7 +603,7 @@ gnc_book_begin (GNCBook *book, const char * book_id,
book->fullpath = NULL; book->fullpath = NULL;
g_free(book->book_id); g_free(book->book_id);
book->book_id = NULL; 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; return FALSE;
} }
@ -566,7 +619,7 @@ gnc_book_begin (GNCBook *book, const char * book_id,
book->fullpath = NULL; book->fullpath = NULL;
g_free(book->book_id); g_free(book->book_id);
book->book_id = NULL; 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; return FALSE;
} }
@ -589,7 +642,7 @@ gnc_book_begin (GNCBook *book, const char * book_id,
book->fullpath = NULL; book->fullpath = NULL;
g_free(book->book_id); g_free(book->book_id);
book->book_id = NULL; 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; return FALSE;
} }
@ -605,7 +658,7 @@ gnc_book_begin (GNCBook *book, const char * book_id,
book->fullpath = NULL; book->fullpath = NULL;
g_free(book->book_id); g_free(book->book_id);
book->book_id = NULL; 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; return FALSE;
} }
@ -627,7 +680,7 @@ gnc_book_begin (GNCBook *book, const char * book_id,
book->fullpath = NULL; book->fullpath = NULL;
g_free(book->book_id); g_free(book->book_id);
book->book_id = NULL; book->book_id = NULL;
gnc_book_push_error (book, err); gnc_book_push_error (book, err, NULL);
return FALSE; return FALSE;
} }
} }
@ -659,7 +712,7 @@ gnc_book_load (GNCBook *book)
if (!book->lockfile) if (!book->lockfile)
{ {
gnc_book_push_error (book, ERR_BACKEND_LOCKED); gnc_book_push_error (book, ERR_BACKEND_LOCKED, NULL);
return FALSE; return FALSE;
} }
@ -723,7 +776,7 @@ gnc_book_load (GNCBook *book)
xaccGroupSetBackend (book->topgroup, be); xaccGroupSetBackend (book->topgroup, be);
gnc_book_push_error(book, xaccBackendGetError(be)); gnc_book_push_error(book, xaccBackendGetError(be), NULL);
xaccLogEnable(); xaccLogEnable();
} }
@ -732,7 +785,7 @@ gnc_book_load (GNCBook *book)
} }
else else
{ {
gnc_book_push_error (book, ERR_BACKEND_NO_BACKEND); gnc_book_push_error (book, ERR_BACKEND_NO_BACKEND, NULL);
return FALSE; return FALSE;
} }
} }
@ -792,7 +845,7 @@ gnc_book_save (GNCBook *book)
err = xaccBackendGetError(be); err = xaccBackendGetError(be);
if (ERR_BACKEND_NO_ERR != err) { 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 ??? */ /* we close the backend here ... isn't this a bit harsh ??? */
if (be->book_end) { if (be->book_end) {
@ -808,13 +861,13 @@ gnc_book_save (GNCBook *book)
if (!book->fullpath) if (!book->fullpath)
{ {
gnc_book_push_error (book, ERR_BACKEND_MISC); gnc_book_push_error (book, ERR_BACKEND_MISC, NULL);
return; return;
} }
if (book->topgroup) { if (book->topgroup) {
if(!gnc_book_write_to_file(book, TRUE)) { 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(" "); LEAVE(" ");

View File

@ -115,6 +115,7 @@ gboolean gnc_book_load (GNCBook *book);
* See Backend.h for a listing of returned errors. * See Backend.h for a listing of returned errors.
*/ */
GNCBackendError gnc_book_get_error (GNCBook *book); GNCBackendError gnc_book_get_error (GNCBook *book);
const char * gnc_book_get_error_message(GNCBook *book);
GNCBackendError gnc_book_pop_error (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 * xaccResolveFilePath (const char * filefrag);
char * xaccResolveURL (const char * pathfrag); 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 */ /* Run the RPC Server */
void gnc_run_rpc_server (void); void gnc_run_rpc_server (void);

View File

@ -277,6 +277,16 @@ pricedb_v2_end_handler(
GNCPriceDB *db = (GNCPriceDB*)result; GNCPriceDB *db = (GNCPriceDB*)result;
sixtp_gdv2* globaldata = (sixtp_gdv2*)global_data; sixtp_gdv2* globaldata = (sixtp_gdv2*)global_data;
if(parent_data)
{
return TRUE;
}
if(!tag)
{
return TRUE;
}
globaldata->addPriceDBFunc(globaldata, db); globaldata->addPriceDBFunc(globaldata, db);
return TRUE; return TRUE;

View File

@ -70,9 +70,13 @@ split_to_dom_tree(const gchar *tag, Split *spl)
xmlAddChild(ret, guid_to_dom_tree("split:id", xaccSplitGetGUID(spl))); 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-posted", trn_date_posted_handler, 1, 0 },
{ "trn:date-entered", trn_date_entered_handler, 1, 0 }, { "trn:date-entered", trn_date_entered_handler, 1, 0 },
{ "trn:description", trn_description_handler, 0, 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 }, { "trn:splits", trn_splits_handler, 1, 0 },
{ NULL, NULL, 0, 0 }, { NULL, NULL, 0, 0 },
}; };

View File

@ -351,32 +351,7 @@ gnc_book_load_from_xml_file(GNCBook *book)
gboolean gboolean
gnc_is_xml_data_file(const gchar *filename) gnc_is_xml_data_file(const gchar *filename)
{ {
FILE *f = NULL; return gnc_is_our_xml_file(filename, "gnc");
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, "<?xml", 5) == 0) {
result = TRUE;
}
cleanup_and_exit:
if(f) fclose(f);
return(result);
} }
/* ================================================================== */ /* ================================================================== */

View File

@ -14,6 +14,15 @@
#include "Group.h" #include "Group.h"
static void
run_callback(sixtp_gdv2 *data, const char *type)
{
if(data->countCallback)
{
data->countCallback(type, data->counter);
}
}
static void static void
clear_up_account_commodity( clear_up_account_commodity(
GNCBook *book, Account *act, gnc_commodity * (*getter) (Account *account), 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); xaccGroupInsertAccount(gnc_book_get_group(data->book), act);
} }
data->counter.accounts_loaded++; data->counter.accounts_loaded++;
run_callback(data, "account");
return FALSE; 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); gnc_commodity_table_insert(gnc_book_get_commodity_table(data->book), com);
data->counter.commodities_loaded++; data->counter.commodities_loaded++;
run_callback(data, "commodities");
return TRUE; return TRUE;
} }
@ -83,17 +95,14 @@ add_transaction_local(sixtp_gdv2 *data, Transaction *trn)
} }
data->counter.transactions_loaded++; data->counter.transactions_loaded++;
run_callback(data, "transaction");
return TRUE; return TRUE;
} }
static gboolean static gboolean
add_pricedb_local(sixtp_gdv2 *data, GNCPriceDB *db) add_pricedb_local(sixtp_gdv2 *data, GNCPriceDB *db)
{ {
if(!db)
{
db = gnc_pricedb_create();
}
if(gnc_book_get_pricedb(data->book)) if(gnc_book_get_pricedb(data->book))
{ {
gnc_pricedb_destroy(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 static void
print_counter_data(struct _load_counter_struct data) print_counter_data(load_counter data)
{ {
printf("Transactions: Total: %d, Loaded: %d\n", printf("Transactions: Total: %d, Loaded: %d\n",
data.transactions_total, data.transactions_loaded); data.transactions_total, data.transactions_loaded);
@ -177,13 +186,24 @@ print_counter_data(struct _load_counter_struct data)
} }
gboolean 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_gdv2 gd;
sixtp *parser; sixtp *top_parser;
sixtp *main_parser;
gpointer parse_result = NULL; gpointer parse_result = NULL;
gd.book = book; 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); AccountGroup *g = gnc_book_get_group(book);
@ -195,25 +215,35 @@ gnc_book_load_from_xml_file_v2(GNCBook *book)
gd.addCommodityFunc = add_commodity_local; gd.addCommodityFunc = add_commodity_local;
gd.addTransactionFunc = add_transaction_local; gd.addTransactionFunc = add_transaction_local;
gd.addPriceDBFunc = add_pricedb_local; gd.addPriceDBFunc = add_pricedb_local;
gd.countCallback = countcallback;
parser = sixtp_new(); top_parser = sixtp_new();
main_parser = sixtp_new();
if(!sixtp_add_some_sub_parsers( if(!sixtp_add_some_sub_parsers(
parser, TRUE, top_parser, TRUE,
"gnc:count-data", gnc_counter_sixtp_parser_create(), "gnc-v2", main_parser,
"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(),
NULL, NULL)) NULL, NULL))
{ {
return FALSE; return FALSE;
} }
if(!sixtp_parse_file(parser, gnc_book_get_file_path(book), 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:account", gnc_account_sixtp_parser_create(),
"gnc:transaction", gnc_transaction_sixtp_parser_create(),
NULL, NULL))
{
return FALSE;
}
if(!sixtp_parse_file(top_parser, gnc_book_get_file_path(book),
NULL, &gd, &parse_result)) NULL, &gd, &parse_result))
{ {
sixtp_destroy(parser); sixtp_destroy(top_parser);
return FALSE; return FALSE;
} }
else 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 gboolean
gnc_is_xml_data_file_v2(const gchar *name) gnc_is_xml_data_file_v2(const gchar *name)
{ {
FILE *f = NULL; return gnc_is_our_xml_file(name, "gnc-v2");
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, "<?xml", 5) == 0)
{
if(!search_for('>', &cursor))
{
return FALSE;
}
if(!eat_whitespace(&cursor))
{
return FALSE;
}
if(strncmp(cursor, "<gnc-v2", 7) == 0)
{
return TRUE;
}
else
{
return FALSE;
}
}
else
{
return FALSE;
}
return FALSE;
} }

View File

@ -43,6 +43,7 @@ struct sixtp_global_data_v2_struct
char *tag; char *tag;
load_counter counter; load_counter counter;
void (*countCallback)(const char *type, load_counter counter);
gboolean (*addAccountFunc)(struct sixtp_global_data_v2_struct *data, gboolean (*addAccountFunc)(struct sixtp_global_data_v2_struct *data,
Account *act); Account *act);
@ -57,7 +58,9 @@ struct sixtp_global_data_v2_struct
typedef struct sixtp_global_data_v2_struct sixtp_gdv2; typedef struct sixtp_global_data_v2_struct sixtp_gdv2;
/* read in an account group from a file */ /* read in an account group from a file */
gboolean gnc_book_load_from_xml_file_v2(GNCBook *book); gboolean gnc_book_load_from_xml_file_v2(
GNCBook *book,
void (*countcallback)(const char *type, load_counter count));
/* write all account info to a file */ /* write all account info to a file */
gboolean gnc_book_write_to_xml_file_v2(GNCBook *book, const char *filename); gboolean gnc_book_write_to_xml_file_v2(GNCBook *book, const char *filename);

View File

@ -409,7 +409,11 @@ dom_tree_to_text(xmlNodePtr tree)
gchar *temp; gchar *temp;
g_return_val_if_fail(tree, NULL); g_return_val_if_fail(tree, NULL);
g_return_val_if_fail(tree->xmlChildrenNode, NULL); /* no nodes means it's an empty string text */
if(!tree->xmlChildrenNode)
{
return g_strdup("");
}
result = g_strdup(""); result = g_strdup("");

View File

@ -24,7 +24,8 @@
#include "config.h" #include "config.h"
#include <glib.h> #include <glib.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h> #include <stdarg.h>
#include "sixtp.h" #include "sixtp.h"
@ -697,3 +698,103 @@ sixtp_parse_buffer(sixtp *sixtp,
return FALSE; 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, "<?xml", 5) == 0)
{
if(!search_for('>', &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;
}

View File

@ -194,5 +194,7 @@ sixtp* sixtp_add_some_sub_parsers(sixtp *tochange, gboolean cleanup, ...);
gboolean sixtp_add_sub_parser(sixtp *parser, const gchar* tag, gboolean sixtp_add_sub_parser(sixtp *parser, const gchar* tag,
sixtp *sub_parser); sixtp *sub_parser);
gboolean gnc_is_our_xml_file(const char *filename, const char *first_tag);
#endif /* _SIXTP_H_ */ #endif /* _SIXTP_H_ */

View File

@ -74,6 +74,11 @@ set_cursor_helper (gpointer window, gpointer data)
GtkWidget *widget = GTK_WIDGET(window); GtkWidget *widget = GTK_WIDGET(window);
int type = GPOINTER_TO_INT(data); int type = GPOINTER_TO_INT(data);
if(!window)
{
return;
}
gnc_ui_set_cursor (widget->window, type); gnc_ui_set_cursor (widget->window, type);
} }