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
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>
* 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 <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>
* 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 <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>
* 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 <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>
* 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>
* 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.

View File

@ -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);

View File

@ -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);
}

View File

@ -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 */

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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 },

View File

@ -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(" ");

View File

@ -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);

View File

@ -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;

View File

@ -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 },
};

View File

@ -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, "<?xml", 5) == 0) {
result = TRUE;
}
cleanup_and_exit:
if(f) fclose(f);
return(result);
return gnc_is_our_xml_file(filename, "gnc");
}
/* ================================================================== */

View File

@ -14,6 +14,15 @@
#include "Group.h"
static void
run_callback(sixtp_gdv2 *data, const char *type)
{
if(data->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, "<?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;
return gnc_is_our_xml_file(name, "gnc-v2");
}

View File

@ -43,6 +43,7 @@ struct sixtp_global_data_v2_struct
char *tag;
load_counter counter;
void (*countCallback)(const char *type, load_counter counter);
gboolean (*addAccountFunc)(struct sixtp_global_data_v2_struct *data,
Account *act);
@ -57,7 +58,9 @@ struct sixtp_global_data_v2_struct
typedef struct sixtp_global_data_v2_struct sixtp_gdv2;
/* 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 */
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;
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("");

View File

@ -24,7 +24,8 @@
#include "config.h"
#include <glib.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#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, "<?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,
sixtp *sub_parser);
gboolean gnc_is_our_xml_file(const char *filename, const char *first_tag);
#endif /* _SIXTP_H_ */

View File

@ -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);
}