mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
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:
parent
d72f8ed668
commit
96372a16ed
130
ChangeLog
130
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 <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.
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 },
|
||||
|
@ -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(" ");
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 },
|
||||
};
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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("");
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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_ */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user