James LewisMoss's patch.

* src/test/test-stuff.c (failure): don't print num if == -1.
	(success): same.
	(get_random_account): move here from test-xml-account.c
	(get_random_split): move here from test-xml-transaction.c
	(get_random_transaction): same.
	(success_args): New func.
	(success): Simplified version
	(failure_args): new func.
	(failure): Simplified version.

	* src/engine/io-gncbin-r.c: same as below.

	* src/engine/TransLog.c (xaccTransWriteLog): same as below.

	* src/engine/Group.c (xaccGroupMergeAccounts): same as below.

	* src/engine/Backend.c (xaccTransactionGetBackend): Convert to not
	use the split's acc part directly, but only to access through
	funcs

	* src/engine/sixtp-dom-parsers.c (dom_tree_generic_parse): Add
	generic parser.

	* src/engine/gnc-account-xml-v2.c (gnc_account_end_handler): use
	generic parser extracted from here and used here and
	gnc-transaction-iml-v2.c

	* src/engine/Transaction.c (xaccInitSplit): Add a split->acc_guid
	field that is set to the account's guid.  This way an Account is
	not required to exist yet when loading the split.  Later when
	xaccSplitGetAccount is called the account is looked up, cached and
	returned.  Make sure everything accesses ->acc through the helper
	function.

	* src/engine/AccountP.h: same as below.

	* src/engine/Account.c (xaccAccountSetGUID): mark guid argument
	const since it doesn't keep a pointer to it.

	* src/doc/xml/transactions-v2.dtd: change guid -> id.
	* src/engine/Transaction.c (get_denom_internal): New helper func.
	(get_currency_denom): use func.
	(get_security_denom): use func.

	* src/engine/sixtp.c: (sixtp_sax_end_handler,
	sixtp_sax_characters_handler, sixtp_sax_start_handler): don't use
	g_return_if_fail to test pdata->parsing_ok so we don't see the
	million CRITICAL warnings.  We'll print an error at the end
	anyway.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3762 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Dave Peticolas 2001-03-09 07:46:13 +00:00
parent cad90da64b
commit a14bf2bfab
22 changed files with 850 additions and 241 deletions

View File

@ -1,3 +1,58 @@
2001-03-08 James LewisMoss <jimdres@mindspring.com>
* src/test/test-stuff.c (failure): don't print num if == -1.
(success): same.
(get_random_account): move here from test-xml-account.c
(get_random_split): move here from test-xml-transaction.c
(get_random_transaction): same.
(success_args): New func.
(success): Simplified version
(failure_args): new func.
(failure): Simplified version.
* src/engine/io-gncbin-r.c: same as below.
* src/engine/TransLog.c (xaccTransWriteLog): same as below.
* src/engine/Group.c (xaccGroupMergeAccounts): same as below.
* src/engine/Backend.c (xaccTransactionGetBackend): Convert to not
use the split's acc part directly, but only to access through
funcs
* src/engine/sixtp-dom-parsers.c (dom_tree_generic_parse): Add
generic parser.
* src/engine/gnc-account-xml-v2.c (gnc_account_end_handler): use
generic parser extracted from here and used here and
gnc-transaction-iml-v2.c
* src/engine/Transaction.c (xaccInitSplit): Add a split->acc_guid
field that is set to the account's guid. This way an Account is
not required to exist yet when loading the split. Later when
xaccSplitGetAccount is called the account is looked up, cached and
returned. Make sure everything accesses ->acc through the helper
function.
* src/engine/AccountP.h: same as below.
* src/engine/Account.c (xaccAccountSetGUID): mark guid argument
const since it doesn't keep a pointer to it.
* src/doc/xml/transactions-v2.dtd: change guid -> id.
2001-03-07 James LewisMoss <jimdres@mindspring.com>
* src/engine/Transaction.c (get_denom_internal): New helper func.
(get_currency_denom): use func.
(get_security_denom): use func.
* src/engine/sixtp.c: (sixtp_sax_end_handler,
sixtp_sax_characters_handler, sixtp_sax_start_handler): don't use
g_return_if_fail to test pdata->parsing_ok so we don't see the
million CRITICAL warnings. We'll print an error at the end
anyway.
2001-03-08 Dave Peticolas <dave@krondo.com>
* src/scm/report/report-list.scm: load tax report if possibly in
@ -126,6 +181,13 @@
reports: subtotals are now printed *below* the subaccounts instead
of above.
2001-03-05 James LewisMoss <jimdres@mindspring.com>
* src/engine/Transaction.c (xaccSplitSetAccount): new func.
* src/doc/xml/transactions-v2.dtd: move splits to an array type
structure.
2001-03-04 Dave Peticolas <dave@krondo.com>
* configure.in: define a new substitution GNC_PIXMAP_DIR for
@ -211,6 +273,28 @@
* src/gnome/dialog-utils.c (gnc_build_option_menu): destroy
tooltips when menu is destroyed
2001-03-02 James LewisMoss <jimdres@mindspring.com>
* src/test/test-xml-transaction.c (test_generation): add success
call for creation accuracy.
* src/test/test-xml-commodity.c (test_generation): Add success
call for creation accuracy.
* src/test/test-xml-account.c (test_generation): Add call to
xaccGUIDinit. Don't know how this was working before without this
call. Maybe hit good memory spots before.
(test_generation): add success call for creation accuracy.
* src/engine/Transaction.c (xaccSplitSetSlots_nc): New func.
(xaccTransSetSlots_nc): new func.
2001-03-01 James LewisMoss <jimdres@mindspring.com>
* src/engine/gnc-account-xml-v2.c (account_id_handler): fix mem
leak because xaccAccountSetGUID doesn't keep pointer to guid
passed in.
2001-03-01 Dave Peticolas <dave@krondo.com>
* src/gnome/dialog-transfer.c: destroy tooltips object

4
debian/changelog vendored
View File

@ -1,8 +1,8 @@
gnucash (1.5.2.cvs20010212-0.1) unstable; urgency=low
gnucash (1.5.3.cvs20010308-0.1) unstable; urgency=low
* local cvs compile
-- James LewisMoss <dres@debian.org> Mon, 22 Jan 2001 12:57:31 -0500
-- James LewisMoss <jimdres@mindspring.com> Thu, 15 Feb 2001 00:19:03 -0500
gnucash (1.5.2.cvs20001105-0.1) unstable; urgency=low

1
debian/rules vendored
View File

@ -25,6 +25,7 @@ Makefile: Makefile.in configure
--mandir=/usr/share/man \
--enable-error-on-warnings
# --enable-efence \
# --enable-profile \
build: build-stamp

View File

@ -3,11 +3,11 @@
<!ELEMENT gnc:transaction (trn:guid, trn:num?, trn:date-posted,
trn:date-entered, trn:description?,
trn:slots?, trn:split+)>
trn:slots?, trn:splits)>
<!ATTLIST gnc:transaction version CDATA #REQUIRED>
<!ELEMENT trn:guid (#PCDATA)>
<!ATTLIST trn:guid type %id-type; %default-id-type;>
<!ELEMENT trn:id (#PCDATA)>
<!ATTLIST trn:id type %id-type; %default-id-type;>
<!ELEMENT trn:num (#PCDATA)>
@ -19,12 +19,15 @@
<!ELEMENT trn:slots %slot-type;>
<!ELEMENT trn:split (split:guid, split:memo?, split:reconciled-state,
split:reconcile-date?, split:value,
split:quantity, split:account)>
<!ELEMENT trn:splits (trn:split+)>
<!ELEMENT split:guid (#PCDATA)>
<!ATTLIST split:guid type %id-type; %default-id-type;>
<!ELEMENT trn:split (split:id, split:memo?, split:reconciled-state,
split:reconcile-date?, split:value,
split:quantity, split:account,
split:slots?)>
<!ELEMENT split:id (#PCDATA)>
<!ATTLIST split:id type %id-type; %default-id-type;>
<!ELEMENT split:memo (#PCDATA)>
@ -39,4 +42,4 @@
<!ELEMENT split:account (#PCDATA)>
<!ATTLIST split:account type %id-type; %default-id-type;>
<!ELEMENT split:slots %slot-type;>

View File

@ -172,8 +172,7 @@ xaccFreeAccount (Account *acc)
/* any split pointing at this account needs to be unmarked */
for(lp = acc->splits; lp; lp = lp->next)
{
Split *s = (Split *) lp->data;
s->acc = NULL;
xaccSplitSetAccount((Split *) lp->data, NULL);
}
acc->editlevel = 0;
@ -294,8 +293,7 @@ xaccAccountCommitEdit (Account *acc)
/* any split pointing at this account needs to be unmarked */
for(lp = acc->splits; lp; lp = lp->next)
{
Split *s = (Split *) lp->data;
s->acc = NULL;
xaccSplitSetAccount((Split *) lp->data, NULL);
}
for(lp = acc->splits; lp; lp = lp->next)
@ -491,7 +489,7 @@ xaccAccountGetGUID (Account *account)
\********************************************************************/
void
xaccAccountSetGUID (Account *account, GUID *guid)
xaccAccountSetGUID (Account *account, const GUID *guid)
{
if (!account || !guid) return;
@ -646,9 +644,10 @@ 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. */
oldacc = split->acc;
if (split->acc) xaccAccountRemoveSplit (split->acc, split);
split->acc = acc;
oldacc = xaccSplitGetAccount(split);
if (xaccSplitGetAccount(split))
xaccAccountRemoveSplit (xaccSplitGetAccount(split), split);
xaccSplitSetAccount(split, acc);
if (acc->editlevel == 1)
{
@ -689,7 +688,7 @@ xaccAccountRemoveSplit (Account *acc, Split *split)
g_list_free_1 (node);
acc->balance_dirty = TRUE;
split->acc = NULL;
xaccSplitSetAccount(split, NULL);
mark_account (acc);
if (split->parent)
@ -935,7 +934,7 @@ xaccTransFixSplitDateOrder (Transaction *trans)
for (node = trans->splits; node; node = node->next)
{
Split *s = node->data;
xaccAccountFixSplitDateOrder (s->acc, s);
xaccAccountFixSplitDateOrder (xaccSplitGetAccount(s), s);
}
}

View File

@ -175,7 +175,7 @@ void xaccAccountRecomputeBalance (Account *);
/* Set the account's GUID. This should only be done when reading
* an account from a datafile, or some other external source. Never
* call this on an existing account! */
void xaccAccountSetGUID (Account *account, GUID *guid);
void xaccAccountSetGUID (Account *account, const GUID *guid);
/* The xaccAccountSetStartingBalance() routine will set the starting
* commodity balance for this account. This routine is intended for

View File

@ -99,7 +99,7 @@ xaccTransactionGetBackend (Transaction *trans)
for (node = snode; node; node=node->next)
{
s = node->data;
if (s->acc) break;
if (xaccSplitGetAccount(s)) break;
s = NULL;
}
@ -111,7 +111,7 @@ xaccTransactionGetBackend (Transaction *trans)
for (node = snode; node; node=node->next)
{
s = node->data;
if (s->acc) break;
if (xaccSplitGetAccount(s)) break;
s = NULL;
}
}
@ -122,7 +122,7 @@ xaccTransactionGetBackend (Transaction *trans)
* don't. However, at this point, it seems quite unlikely, so we'll
* just use the first backend we find.
*/
return xaccAccountGetBackend (s->acc);
return xaccAccountGetBackend (xaccSplitGetAccount(s));
}
/********************************************************************\

View File

@ -951,9 +951,9 @@ xaccGroupMergeAccounts (AccountGroup *grp)
{
Split *split = lp->data;
gnc_engine_generate_event (&split->acc->guid, GNC_EVENT_MODIFY);
split->acc = NULL;
gnc_engine_generate_event (&xaccSplitGetAccount(split)->guid,
GNC_EVENT_MODIFY);
xaccSplitSetAccount(split, NULL);
xaccAccountInsertSplit (acc_a, split);
}

View File

@ -38,6 +38,7 @@ libgncengine_la_SOURCES = \
gnc-numeric.c \
gnc-pricedb-xml-v1.c \
gnc-pricedb.c \
gnc-transaction-xml-v2.c \
guid.c \
io-gncbin-r.c \
io-gncxml-r.c \

View File

@ -207,8 +207,8 @@ xaccTransWriteLog (Transaction *trans, char flag)
Split *split = node->data;
char * accname = "";
if (split->acc)
accname = split->acc->accountName;
if (xaccSplitGetAccount(split))
accname = xaccSplitGetAccount(split)->accountName;
drecn = xaccDateUtilGetStamp (split->date_reconciled.tv_sec);

View File

@ -91,7 +91,7 @@ static void
xaccInitSplit(Split * split)
{
/* fill in some sane defaults */
split->acc = NULL;
xaccSplitSetAccount(split, NULL);
split->parent = NULL;
split->action = g_cache_insert(gnc_engine_get_string_cache(), "");
@ -144,7 +144,7 @@ xaccCloneSplit (Split *s)
* is a sick twisted clone that holds 'undo' information. */
split->guid = s->guid;
split->acc = s->acc;
xaccSplitSetAccountGUID(split, s->acc_guid);
split->parent = s->parent;
split->memo = g_cache_insert (gnc_engine_get_string_cache(), s->memo);
@ -191,8 +191,8 @@ xaccFreeSplit (Split *split)
split->damount = gnc_numeric_zero();
split->value = gnc_numeric_zero();
split->parent = NULL;
split->acc = NULL;
xaccSplitSetAccount(split, NULL);
split->date_reconciled.tv_sec = 0;
split->date_reconciled.tv_nsec = 0;
@ -247,6 +247,68 @@ xaccSplitGetSlots(Split * s) {
return(s->kvp_data);
}
void
xaccSplitSetSlots_nc(Split *s, kvp_frame *frm)
{
g_return_if_fail(s);
g_return_if_fail(frm);
if(s->kvp_data)
{
kvp_frame_delete(s->kvp_data);
}
s->kvp_data = frm;
}
/********************************************************************
* Account funcs
********************************************************************/
Account*
xaccSplitGetAccount(Split *s)
{
if(!s) return NULL;
if(!s->acc)
{
xaccSplitSetAccount(s, xaccAccountLookup(&s->acc_guid));
}
return s->acc;
}
const GUID *
xaccSplitGetAccountGUID(Split *split)
{
return (const GUID*) &split->acc_guid;
}
void
xaccSplitSetAccount(Split *s, Account *act)
{
int i;
if(!act)
{
for(i = 0; i < 16; i++)
s->acc_guid.data[i] = '\0';
}
else
{
const GUID *id = xaccAccountGetGUID(act);
s->acc_guid = *id;
}
s->acc = act;
}
void
xaccSplitSetAccountGUID(Split *s, GUID id)
{
s->acc_guid = id;
s->acc = NULL;
}
/********************************************************************\
\********************************************************************/
@ -261,7 +323,7 @@ xaccSplitGetGUID (Split *split)
\********************************************************************/
void
xaccSplitSetGUID (Split *split, GUID *guid)
xaccSplitSetGUID (Split *split, const GUID *guid)
{
if (!split || !guid) return;
check_open (split->parent);
@ -303,7 +365,7 @@ G_INLINE_FUNC void mark_split_internal (Split *split,
G_INLINE_FUNC void
mark_split_internal (Split *split, gboolean generate_events)
{
Account *account = split->acc;
Account *account = xaccSplitGetAccount(split);
Transaction *trans;
if (account)
@ -345,26 +407,32 @@ mark_trans (Transaction *trans)
\********************************************************************/
static int
get_currency_denom(Split * s) {
if(!s) return 0;
else if(!(s->acc)) {
return 100000;
}
else {
return xaccAccountGetCurrencySCU(s->acc);
}
get_denom_internal(Split *s, int (*func)(Account*))
{
if(!s)
{
return 0;
}
else if(!xaccSplitGetAccount(s))
{
return 100000;
}
else
{
return func(xaccSplitGetAccount(s));
}
}
static int
get_currency_denom(Split * s)
{
return get_denom_internal(s, xaccAccountGetCurrencySCU);
}
static int
get_security_denom(Split * s) {
if(!s) return 0;
else if(!(s->acc)) {
return 100000;
}
else {
return xaccAccountGetSecuritySCU(s->acc);
}
get_security_denom(Split * s)
{
return get_denom_internal(s, xaccAccountGetSecuritySCU);
}
/********************************************************************\
@ -770,6 +838,20 @@ xaccTransGetSlots(Transaction *t) {
return(t->kvp_data);
}
void
xaccTransSetSlots_nc(Transaction *t, kvp_frame *frm)
{
g_return_if_fail(t);
g_return_if_fail(frm);
if(t->kvp_data)
{
kvp_frame_delete(t->kvp_data);
}
t->kvp_data = frm;
}
/********************************************************************\
\********************************************************************/
@ -784,7 +866,7 @@ xaccTransGetGUID (Transaction *trans)
\********************************************************************/
void
xaccTransSetGUID (Transaction *trans, GUID *guid)
xaccTransSetGUID (Transaction *trans, const GUID *guid)
{
if (!trans || !guid) return;
xaccRemoveEntity(&trans->guid);
@ -830,10 +912,10 @@ xaccSplitSetBaseValue (Split *s, gnc_numeric value,
* features of this engine. So, in particular, there may be the
* occasional split without a parent account. Well, that's ok,
* we'll just go with the flow. */
if (!(s->acc)) {
if (!xaccSplitGetAccount(s)) {
if (force_double_entry) {
PERR ("split must have a parent\n");
assert (s->acc);
assert (xaccSplitGetAccount(s));
}
else {
/* this is a change in semantics. previously, calling
@ -847,8 +929,8 @@ xaccSplitSetBaseValue (Split *s, gnc_numeric value,
return;
}
currency = xaccAccountGetCurrency (s->acc);
security = xaccAccountGetEffectiveSecurity (s->acc);
currency = xaccAccountGetCurrency (xaccSplitGetAccount(s));
security = xaccAccountGetEffectiveSecurity (xaccSplitGetAccount(s));
/* if the base_currency is the account currency, set the
* value. If it's the account security, set the damount.
@ -905,17 +987,17 @@ xaccSplitGetBaseValue (Split *s, const gnc_commodity * base_currency)
* may be the occasional split without a parent account.
* Well, that's ok, we'll just go with the flow.
*/
if (!(s->acc)) {
if (!xaccSplitGetAccount(s)) {
if (force_double_entry) {
assert (s->acc);
assert (xaccSplitGetAccount(s));
}
else {
return s->value;
}
}
currency = xaccAccountGetCurrency (s->acc);
security = xaccAccountGetSecurity (s->acc);
currency = xaccAccountGetCurrency (xaccSplitGetAccount(s));
security = xaccAccountGetSecurity (xaccSplitGetAccount(s));
/* be more precise -- the value depends on the currency we want it
* expressed in. */
@ -963,9 +1045,9 @@ xaccSplitsComputeValue (GList *splits, Split * skip_me,
* this engine. So, in particular, there may be the occasional
* split without a parent account. Well, that's ok, we'll just
* go with the flow. */
if (!(s->acc)) {
if (!xaccSplitGetAccount(s)) {
if (force_double_entry) {
assert (s->acc);
assert (xaccSplitGetAccount(s));
}
else {
value = gnc_numeric_add(value, s->value,
@ -980,8 +1062,8 @@ xaccSplitsComputeValue (GList *splits, Split * skip_me,
const gnc_commodity *currency;
const gnc_commodity *security;
currency = xaccAccountGetCurrency (s->acc);
security = xaccAccountGetSecurity (s->acc);
currency = xaccAccountGetCurrency (xaccSplitGetAccount(s));
security = xaccAccountGetSecurity (xaccSplitGetAccount(s));
/* OK, we've got a parent account, we've got currency, lets
* behave like professionals now, instead of the shenanigans
@ -1077,12 +1159,12 @@ FindCommonExclSCurrency (GList *splits,
* Well, that's ok, we'll just go with the flow.
*/
if (force_double_entry)
assert (s->acc);
else if (s->acc == NULL)
assert (xaccSplitGetAccount(s));
else if (xaccSplitGetAccount(s) == NULL)
continue;
sa = xaccAccountGetCurrency (s->acc);
sb = xaccAccountGetSecurity (s->acc);
sa = xaccAccountGetCurrency (xaccSplitGetAccount(s));
sb = xaccAccountGetSecurity (xaccSplitGetAccount(s));
if (ra && rb) {
int aa = !gnc_commodity_equiv(ra,sa);
@ -1137,10 +1219,10 @@ xaccTransFindCommonCurrency (Transaction *trans)
split = trans->splits->data;
if (split->acc == NULL) return NULL;
if (xaccSplitGetAccount(split) == NULL) return NULL;
ra = xaccAccountGetCurrency (split->acc);
rb = xaccAccountGetSecurity (split->acc);
ra = xaccAccountGetCurrency (xaccSplitGetAccount(split));
rb = xaccAccountGetSecurity (xaccSplitGetAccount(split));
retval = FindCommonCurrency (trans->splits, ra, rb);
@ -1222,11 +1304,11 @@ xaccTransSetCurrency (Transaction *trans, gnc_commodity *curr)
const gnc_commodity *currency;
const gnc_commodity *security;
currency = xaccAccountGetCurrency (s->acc);
security = xaccAccountGetSecurity (s->acc);
currency = xaccAccountGetCurrency (xaccSplitGetAccount(s));
security = xaccAccountGetSecurity (xaccSplitGetAccount(s));
if (!currency && security)
{
xaccAccountSetCurrency (s->acc, curr);
xaccAccountSetCurrency (xaccSplitGetAccount(s), curr);
}
}
kimono = xaccTransFindCommonCurrency (trans);
@ -1323,7 +1405,7 @@ xaccTransCommitEdit (Transaction *trans)
(!gnc_numeric_zero_p(split->damount))) {
Split * s = xaccMallocSplit();
xaccTransAppendSplit (trans, s);
xaccAccountInsertSplit (split->acc, s);
xaccAccountInsertSplit (xaccSplitGetAccount(s), s);
xaccSplitSetMemo (s, split->memo);
xaccSplitSetAction (s, split->action);
xaccSplitSetShareAmount(s, gnc_numeric_neg(split->damount));
@ -1464,7 +1546,7 @@ xaccTransRollbackEdit (Transaction *trans)
s = node->data;
so = node_orig->data;
if (so->acc != s->acc)
if (xaccSplitGetAccount(so) != xaccSplitGetAccount(s))
{
force_it = 1;
mismatch = i;
@ -1494,8 +1576,8 @@ xaccTransRollbackEdit (Transaction *trans)
/* do NOT check date order until all of the other fields
* have been properly restored */
xaccAccountFixSplitDateOrder (s->acc, s);
xaccAccountRecomputeBalance (s->acc);
xaccAccountFixSplitDateOrder (xaccSplitGetAccount(s), s);
xaccAccountRecomputeBalance (xaccSplitGetAccount(s));
mark_split (s);
}
@ -1532,8 +1614,8 @@ xaccTransRollbackEdit (Transaction *trans)
Split *s = node->data;
mark_split (s);
xaccAccountRemoveSplit (s->acc, s);
xaccAccountRecomputeBalance (s->acc);
xaccAccountRemoveSplit (xaccSplitGetAccount(s), s);
xaccAccountRecomputeBalance (xaccSplitGetAccount(s));
xaccRemoveEntity(&s->guid);
xaccFreeSplit (s);
}
@ -1547,9 +1629,9 @@ xaccTransRollbackEdit (Transaction *trans)
node ; node = node->next)
{
Split *s = node->data;
Account *account = s->acc;
Account *account = xaccSplitGetAccount(s);
s->acc = NULL;
xaccSplitSetAccount(s, NULL);
xaccStoreEntity(s, &s->guid, GNC_ID_SPLIT);
xaccAccountInsertSplit (account, s);
xaccAccountRecomputeBalance (account);
@ -1609,8 +1691,8 @@ xaccTransDestroy (Transaction *trans)
mark_split (split);
xaccAccountRemoveSplit (split->acc, split);
xaccAccountRecomputeBalance (split->acc);
xaccAccountRemoveSplit (xaccSplitGetAccount(split), split);
xaccAccountRecomputeBalance (xaccSplitGetAccount(split));
xaccRemoveEntity(&split->guid);
xaccFreeSplit (split);
@ -1663,8 +1745,8 @@ xaccSplitDestroy (Split *split)
xaccTransRemoveSplit (trans, split);
}
xaccAccountRemoveSplit (split->acc, split);
xaccAccountRecomputeBalance (split->acc);
xaccAccountRemoveSplit (xaccSplitGetAccount(split), split);
xaccAccountRecomputeBalance (xaccSplitGetAccount(split));
xaccFreeSplit (split);
}
@ -2222,7 +2304,7 @@ xaccSplitSetReconcile (Split *split, char recn)
split->reconciled = recn;
xaccAccountRecomputeBalance (split->acc);
xaccAccountRecomputeBalance (xaccSplitGetAccount(split));
mark_split (split);
}
@ -2273,13 +2355,6 @@ xaccSplitGetParent (Split *split)
return (split->parent);
}
Account *
xaccSplitGetAccount (Split *split)
{
if (!split) return NULL;
return (split->acc);
}
const char *
xaccSplitGetMemo (Split *split)
{
@ -2392,7 +2467,7 @@ xaccGetAccountByName (Transaction *trans, const char * name)
{
Split *s = node->data;
acc = s->acc;
acc = xaccSplitGetAccount(s);
if (acc) break;
}
@ -2420,7 +2495,7 @@ xaccGetAccountByFullName (Transaction *trans, const char * name,
{
Split *s = node->data;
acc = s->acc;
acc = xaccSplitGetAccount(s);
if (acc) break;
}

View File

@ -135,6 +135,7 @@ Transaction * xaccTransLookup (const GUID *guid);
* structures which aren't members of the transaction struct. */
kvp_frame *xaccTransGetSlots(Transaction *trans);
void xaccTransSetSlots_nc(Transaction *t, kvp_frame *frm);
/* The xaccTransSetDateSecs() method will modify the posted date
* of the transaction. (Footnote: this shouldn't matter to a user,
@ -340,6 +341,7 @@ gboolean xaccSplitEqual(const Split *sa, const Split *sb,
* See kvp_doc.txt for reserved slot names.
*/
kvp_frame *xaccSplitGetSlots(Split *split);
void xaccSplitSetSlots_nc(Split *s, kvp_frame *frm);
/* The xaccSplitGetGUID() subroutine will return the
* globally unique id associated with that split.
@ -467,6 +469,9 @@ gnc_numeric xaccSplitGetSharePrice (Split * split);
gnc_numeric xaccSplitGetValue (Split * split);
Account * xaccSplitGetAccount (Split *split);
const GUID * xaccSplitGetAccountGUID(Split *split);
void xaccSplitSetAccount(Split *s, Account *act);
void xaccSplitSetAccountGUID(Split *s, GUID id);
/* split types: normal stock-split */
const char *xaccSplitGetType(const Split *s);

View File

@ -78,7 +78,9 @@ struct _split
{
GUID guid; /* globally unique id */
GUID acc_guid; /* the guid of the associated account */
Account *acc; /* back-pointer to debited/credited account */
Transaction *parent; /* parent of split */
/* The memo field is an arbitrary user-assiged value.
@ -195,12 +197,12 @@ struct _transaction
/* Set the transaction's GUID. This should only be done when reading
* a transaction from a datafile, or some other external source. Never
* call this on an existing transaction! */
void xaccTransSetGUID (Transaction *trans, GUID *guid);
void xaccTransSetGUID (Transaction *trans, const GUID *guid);
/* Set the split's GUID. This should only be done when reading
* a split from a datafile, or some other external source. Never
* call this on an existing split! */
void xaccSplitSetGUID (Split *split, GUID *guid);
void xaccSplitSetGUID (Split *split, const GUID *guid);
/* The xaccFreeSplit() method simply frees all memory associated
* with the split. It does not verify that the split isn't

View File

@ -86,15 +86,15 @@ gnc_account_dom_tree_create(Account *act)
}
/***********************************************************************/
static gboolean
account_name_handler (xmlNodePtr node, Account* act)
set_string(xmlNodePtr node, Account* act,
void (*func)(Account *act, const gchar *txt))
{
gchar* txt;
txt = dom_tree_to_text(node);
gchar* txt = dom_tree_to_text(node);
g_return_val_if_fail(txt, FALSE);
xaccAccountSetName(act, txt);
func(act, txt);
g_free(txt);
@ -102,12 +102,18 @@ account_name_handler (xmlNodePtr node, Account* act)
}
static gboolean
account_id_handler (xmlNodePtr node, Account* act)
account_name_handler (xmlNodePtr node, gpointer act)
{
return set_string(node, (Account*)act, xaccAccountSetName);
}
static gboolean
account_id_handler (xmlNodePtr node, gpointer act)
{
GUID *guid;
guid = dom_tree_to_guid(node);
xaccAccountSetGUID(act, guid);
xaccAccountSetGUID((Account*)act, guid);
g_free(guid);
@ -115,104 +121,74 @@ account_id_handler (xmlNodePtr node, Account* act)
}
static gboolean
account_type_handler (xmlNodePtr node, Account* act)
account_type_handler (xmlNodePtr node, gpointer act)
{
int type;
xaccAccountStringToType(node->xmlChildrenNode->content, &type);
xaccAccountSetType(act, type);
xaccAccountSetType((Account*)act, type);
return TRUE;
}
static gboolean
account_currency_handler (xmlNodePtr node, Account* act)
account_currency_handler (xmlNodePtr node, gpointer act)
{
gnc_commodity *ref;
ref = dom_tree_to_commodity_ref_no_engine(node);
xaccAccountSetCurrency(act, ref);
xaccAccountSetCurrency((Account*)act, ref);
return TRUE;
}
static gboolean
account_security_handler (xmlNodePtr node, Account* act)
account_security_handler (xmlNodePtr node, gpointer act)
{
gnc_commodity *ref;
ref = dom_tree_to_commodity_ref_no_engine(node);
xaccAccountSetSecurity(act, ref);
xaccAccountSetSecurity((Account*)act, ref);
return TRUE;
}
static gboolean
account_slots_handler (xmlNodePtr node, Account* act)
account_slots_handler (xmlNodePtr node, gpointer act)
{
kvp_frame *frm = dom_tree_to_kvp_frame(node);
g_return_val_if_fail(frm, FALSE);
xaccAccountSetSlots_nc(act, frm);
xaccAccountSetSlots_nc((Account*)act, frm);
return TRUE;
}
static gboolean
account_parent_handler (xmlNodePtr node, Account* act)
account_parent_handler (xmlNodePtr node, gpointer act)
{
Account *parent;
GUID *gid = dom_tree_to_guid(node);
parent = xaccAccountLookup(gid);
xaccAccountInsertSubAccount(parent, act);
xaccAccountInsertSubAccount(parent, (Account*)act);
xaccGUIDFree(gid);
return TRUE;
}
static gboolean
account_code_handler(xmlNodePtr node, Account* act)
account_code_handler(xmlNodePtr node, gpointer act)
{
gchar* txt;
txt = dom_tree_to_text(node);
g_return_val_if_fail(txt, FALSE);
xaccAccountSetCode(act, txt);
g_free(txt);
return TRUE;
return set_string(node, (Account*)act, xaccAccountSetCode);
}
static gboolean
account_description_handler(xmlNodePtr node, Account *act)
account_description_handler(xmlNodePtr node, gpointer act)
{
gchar* txt;
txt = dom_tree_to_text(node);
g_return_val_if_fail(txt, FALSE);
xaccAccountSetDescription(act, txt);
g_free(txt);
return TRUE;
return set_string(node, (Account*)act, xaccAccountSetDescription);
}
struct dom_handlers
{
const char *tag;
gboolean (*handler) (xmlNodePtr, Account*);
int required;
int gotten;
};
static struct dom_handlers account_handlers_v2[] = {
static struct dom_tree_handler account_handlers_v2[] = {
{ "act:name", account_name_handler, 1, 0 },
{ "act:id", account_id_handler, 1, 0 },
{ "act:type", account_type_handler, 1, 0 },
@ -225,57 +201,6 @@ static struct dom_handlers account_handlers_v2[] = {
{ NULL, 0, 0, 0 }
};
static void
set_handlers(struct dom_handlers *handler_ptr)
{
while(handler_ptr->tag != NULL)
{
handler_ptr->gotten = 0;
handler_ptr++;
}
}
static gboolean
all_required_gotten_p(struct dom_handlers *handler_ptr)
{
while(handler_ptr->tag != NULL)
{
if(handler_ptr->required && ! handler_ptr->gotten)
{
g_warning("Not defined and it should be: %s", handler_ptr->tag);
return FALSE;
}
handler_ptr++;
}
return TRUE;
}
static gboolean
gnc_xml_set_account_data(const gchar* tag, xmlNodePtr node, Account *acc,
struct dom_handlers *handler_ptr)
{
while(handler_ptr->tag)
{
if(strcmp(tag, handler_ptr->tag) == 0)
{
(handler_ptr->handler)(node, acc);
handler_ptr->gotten = TRUE;
break;
}
handler_ptr++;
}
if(!handler_ptr->tag)
{
g_warning("Unhandled account tag: %s\n", tag);
return FALSE;
}
return TRUE;
}
static gboolean
gnc_account_end_handler(gpointer data_for_children,
GSList* data_from_children, GSList* sibling_data,
@ -308,27 +233,9 @@ gnc_account_end_handler(gpointer data_for_children,
g_return_val_if_fail(acc, FALSE);
xaccAccountBeginEdit(acc);
set_handlers(account_handlers_v2);
for(achild = tree->xmlChildrenNode; achild; achild = achild->next)
{
if(!gnc_xml_set_account_data(achild->name, achild, acc,
account_handlers_v2))
{
g_warning("gnc_xml_set_account_data failed");
successful = FALSE;
break;
}
}
successful = dom_tree_generic_parse(tree, account_handlers_v2, acc);
xaccAccountCommitEdit(acc);
if(!all_required_gotten_p(account_handlers_v2))
{
g_warning("all_required_gotten_p failed");
successful = FALSE;
}
if(!successful)
{
xaccFreeAccount(acc);

View File

@ -27,6 +27,7 @@
#include <string.h>
#include "gnc-xml-helper.h"
#include "gnc-engine-util.h"
#include "sixtp.h"
#include "sixtp-utils.h"
@ -37,42 +38,402 @@
#include "gnc-xml.h"
#include "io-gncxml-v2.h"
#include "sixtp-dom-parsers.h"
#include "AccountP.h"
#include "Account.h"
#include "Group.h"
#include "Transaction.h"
#include "TransactionP.h"
const gchar *transaction_version_string = "2.0.0";
static void
add_gnc_num(xmlNodePtr node, const gchar *tag, gnc_numeric num)
{
xmlAddChild(node, gnc_numeric_to_dom_tree(tag, &num));
}
static void
add_timespec(xmlNodePtr node, const gchar *tag, Timespec tms, gboolean always)
{
if(always || !((tms.tv_sec == 0) && (tms.tv_nsec == 0)))
{
xmlAddChild(node, timespec_to_dom_tree(tag, &tms));
}
}
xmlNodePtr
gnc_transaction_dom_tree_create(const Transaction *com)
split_to_dom_tree(const gchar *tag, Split *spl)
{
xmlNodePtr ret;
ret = xmlNewNode(NULL, tag);
xmlAddChild(ret, guid_to_dom_tree("split:id", xaccSplitGetGUID(spl)));
if(xaccSplitGetMemo(spl))
{
xmlNewTextChild(ret, NULL, "split:memo", xaccSplitGetMemo(spl));
}
{
char tmp[2];
tmp[0] = xaccSplitGetReconcile(spl);
tmp[1] = '\0';
xmlNewTextChild(ret, NULL, "split:reconciled-state", tmp);
}
add_timespec(ret, "split:reconcile-date",
xaccSplitRetDateReconciledTS(spl), FALSE);
add_gnc_num(ret, "split:value", xaccSplitGetValue(spl));
add_gnc_num(ret, "split:quantity", xaccSplitGetShareAmount(spl));
xmlAddChild(ret, guid_to_dom_tree(
"split:account",
xaccSplitGetAccountGUID(spl)));
xmlAddChild(ret, kvp_frame_to_dom_tree("split:slots",
xaccSplitGetSlots(spl)));
return ret;
}
static void
add_trans_splits(xmlNodePtr node, Transaction *trn)
{
Split *mark;
int i;
xmlNodePtr toaddto;
toaddto = xmlNewChild(node, NULL, "trn:splits", NULL);
for(i = 0, mark = xaccTransGetSplit(trn, i); mark;
i++, mark = xaccTransGetSplit(trn, i))
{
xmlAddChild(toaddto, split_to_dom_tree("trn:split", mark));
}
}
xmlNodePtr
gnc_transaction_dom_tree_create(Transaction *trn)
{
xmlNodePtr ret;
ret = xmlNewNode(NULL, "gnc:transaction");
xmlSetProp(ret, "version", transaction_version_string);
xmlAddChild(ret, guid_to_dom_tree("trn:id", xaccTransGetGUID(trn)));
if(xaccTransGetNum(trn))
{
xmlNewTextChild(ret, NULL, "trn:num", xaccTransGetNum(trn));
}
add_timespec(ret, "trn:date-posted", xaccTransRetDatePostedTS(trn), TRUE);
add_timespec(ret, "trn:date-entered",
xaccTransRetDateEnteredTS(trn), TRUE);
if(xaccTransGetDescription(trn))
{
xmlNewTextChild(ret, NULL, "trn:description",
xaccTransGetDescription(trn));
}
xmlAddChild(ret, kvp_frame_to_dom_tree("trn:slots",
xaccTransGetSlots(trn)));
add_trans_splits(ret, trn);
return ret;
}
/***********************************************************************/
static gboolean
valid_transaction(const Transaction *com)
set_spl_string(xmlNodePtr node, Split *spl,
void (*func)(Split *spl, const char *txt))
{
gchar *tmp = dom_tree_to_text(node);
g_return_val_if_fail(tmp, FALSE);
func(spl, tmp);
g_free(tmp);
return TRUE;
}
static gboolean
set_spl_gnc_num(xmlNodePtr node, Split* spl,
void (*func)(Split *spl, gnc_numeric gn))
{
gnc_numeric *num = dom_tree_to_gnc_numeric(node);
g_return_val_if_fail(num, FALSE);
func(spl, *num);
g_free(num);
return FALSE;
}
static gboolean
spl_id_handler(xmlNodePtr node, gpointer spl)
{
GUID *tmp = dom_tree_to_guid(node);
g_return_val_if_fail(tmp, FALSE);
xaccSplitSetGUID((Split*)spl, tmp);
g_free(tmp);
return TRUE;
}
static gboolean
spl_memo_handler(xmlNodePtr node, gpointer spl)
{
return set_spl_string(node, (Split*)spl, xaccSplitSetMemo);
}
static gboolean
spl_reconciled_state_handler(xmlNodePtr node, gpointer spl)
{
gchar *tmp = dom_tree_to_text(node);
g_return_val_if_fail(tmp, FALSE);
xaccSplitSetReconcile((Split*)spl, tmp[0]);
g_free(tmp);
return TRUE;
}
static gboolean
spl_reconcile_date_handler(xmlNodePtr node, gpointer spl)
{
Timespec *ts;
ts = dom_tree_to_timespec(node);
g_return_val_if_fail(ts, FALSE);
xaccSplitSetDateReconciledTS((Split*)spl, ts);
g_free(ts);
return TRUE;
}
static gboolean
spl_value_handler(xmlNodePtr node, gpointer spl)
{
return set_spl_gnc_num(node, (Split*)spl, xaccSplitSetValue);
}
static gboolean
spl_quantity_handler(xmlNodePtr node, gpointer spl)
{
return set_spl_gnc_num(node, (Split*)spl, xaccSplitSetValue);
}
static gboolean
spl_account_handler(xmlNodePtr node, gpointer spl)
{
GUID *id = dom_tree_to_guid(node);
if(!id) return FALSE;
xaccSplitSetAccountGUID((Split*)spl, *id);
g_free(id);
return TRUE;
}
static gboolean
spl_slots_handler(xmlNodePtr node, gpointer spl)
{
kvp_frame *frm = dom_tree_to_kvp_frame(node);
g_return_val_if_fail(frm, FALSE);
xaccSplitSetSlots_nc((Split*)spl, frm);
return TRUE;
}
struct dom_tree_handler spl_dom_handlers[] =
{
{ "split:id", spl_id_handler, 1, 0 },
{ "split:memo", spl_memo_handler, 0, 0 },
{ "split:reconciled-state", spl_reconciled_state_handler, 1, 0 },
{ "split:reconcile-date", spl_reconcile_date_handler, 0, 0 },
{ "split:value", spl_value_handler, 1, 0 },
{ "split:quantity", spl_quantity_handler, 1, 0 },
{ "split:account", spl_account_handler, 1, 0 },
{ "split:slots", spl_slots_handler, 0, 0 },
{ NULL, NULL, 0, 0 },
};
Split*
dom_tree_to_split(xmlNodePtr node)
{
Split *ret;
ret = xaccMallocSplit();
g_return_val_if_fail(ret, NULL);
/* this isn't going to work in a testing setup */
if(dom_tree_generic_parse(node, spl_dom_handlers, ret))
{
return ret;
}
else
{
xaccSplitDestroy(ret);
return NULL;
}
}
static gboolean
trn_splits_handler(xmlNodePtr node, gpointer trn)
{
xmlNodePtr mark;
g_return_val_if_fail(node, FALSE);
g_return_val_if_fail(node->xmlChildrenNode, FALSE);
for(mark = node->xmlChildrenNode; mark; mark = mark->next)
{
Split *spl;
if(safe_strcmp("trn:split", mark->name))
{
return FALSE;
}
spl = dom_tree_to_split(mark);
if(spl)
{
xaccTransAppendSplit((Transaction*)trn, spl);
}
else
{
return FALSE;
}
}
return TRUE;
}
/***********************************************************************/
static gboolean
set_tran_string(xmlNodePtr node, Transaction *trn,
void (*func)(Transaction *trn, const char *txt))
{
gchar *tmp;
tmp = dom_tree_to_text(node);
g_return_val_if_fail(tmp, FALSE);
func(trn, tmp);
g_free(tmp);
return TRUE;
}
static gboolean
set_tran_date(xmlNodePtr node, Transaction *trn,
void (*func)(Transaction *trn, const Timespec *tm))
{
Timespec *tm;
tm = dom_tree_to_timespec(node);
g_return_val_if_fail(tm, FALSE);
func(trn, tm);
g_free(tm);
return TRUE;
}
static gboolean
trn_id_handler(xmlNodePtr node, gpointer trn)
{
GUID *tmp = dom_tree_to_guid(node);
g_return_val_if_fail(tmp, FALSE);
xaccTransSetGUID((Transaction*)trn, tmp);
g_free(tmp);
return TRUE;
}
static gboolean
trn_num_handler(xmlNodePtr node, gpointer trn)
{
return set_tran_string(node, (Transaction*)trn, xaccTransSetNum);
}
static gboolean
trn_date_posted_handler(xmlNodePtr node, gpointer trn)
{
return set_tran_date(node, (Transaction*)trn, xaccTransSetDatePostedTS);
}
static gboolean
trn_date_entered_handler(xmlNodePtr node, gpointer trn)
{
return set_tran_date(node, (Transaction*)trn, xaccTransSetDateEnteredTS);
}
static gboolean
trn_description_handler(xmlNodePtr node, gpointer trn)
{
return set_tran_string(node, (Transaction*)trn, xaccTransSetDescription);
}
static gboolean
trn_slots_handler(xmlNodePtr node, gpointer trn)
{
kvp_frame *frm;
frm = dom_tree_to_kvp_frame(node);
xaccTransSetSlots_nc((Transaction*)trn, frm);
return TRUE;
}
struct dom_tree_handler trn_dom_handlers[] =
{
{ "trn:id", trn_id_handler, 1, 0 },
{ "trn:num", trn_num_handler, 0, 0 },
{ "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:splits", trn_splits_handler, 1, 0 },
{ NULL, NULL, 0, 0 },
};
static gboolean
gnc_transaction_end_handler(gpointer data_for_children,
GSList* data_from_children, GSList* sibling_data,
gpointer parent_data, gpointer global_data,
gpointer *result, const gchar *tag)
{
Transaction *tran;
Transaction *trn = NULL;
gboolean successful = FALSE;
xmlNodePtr achild;
xmlNodePtr tree = (xmlNodePtr)data_for_children;
sixtp_gdv2 *globaldata = (sixtp_gdv2*)global_data;
@ -82,20 +443,43 @@ gnc_transaction_end_handler(gpointer data_for_children,
return TRUE;
}
if(!valid_transaction(com))
/* OK. For some messed up reason this is getting called again with a
NULL tag. So we ignore those cases */
if(!tag)
{
return FALSE;
return TRUE;
}
g_return_val_if_fail(tree, FALSE);
trn = xaccMallocTransaction();
g_return_val_if_fail(trn, FALSE);
xaccTransBeginEdit(trn);
successful = dom_tree_generic_parse(tree, trn_dom_handlers, trn);
xaccTransCommitEdit(trn);
if(successful)
{
globaldata->addTransactionFunc(globaldata, trn);
successful = TRUE;
}
else
{
xmlElemDump(stdout, NULL, tree);
xaccTransBeginEdit(trn);
xaccTransDestroy(trn);
}
globaldata->accTransactionFunc(globaldata, tran);
xmlFreeNode(tree);
return TRUE
return successful;
}
sixtp*
gnc_transaction_sixtp_parser_create(void)
{
return sixtp_dom_parser_new(gnc_transaction_end_handler);
return sixtp_dom_parser_new(gnc_transaction_end_handler, NULL, NULL);
}

View File

@ -18,8 +18,10 @@ sixtp* gnc_account_sixtp_parser_create(void);
xmlNodePtr gnc_commodity_dom_tree_create(const gnc_commodity *act);
sixtp* gnc_commodity_sixtp_parser_create(void);
xmlNodePtr gnc_transaction_dom_tree_create(const Transaction *com);
xmlNodePtr gnc_transaction_dom_tree_create(Transaction *com);
sixtp* gnc_transaction_sixtp_parser_create(void);
xmlNodePtr split_to_dom_tree(const gchar *tag, Split *spl);
Split* dom_tree_to_split(xmlNodePtr node);
#endif /* __GNC_XML_H__ */

View File

@ -1939,7 +1939,7 @@ writeSplit ( int fd, Split *split )
return -1;
/* write the credited/debted account */
xfer_acc = split->acc;
xfer_acc = xaccSplitGetAccount(split);
acc_id = -1;
if (xfer_acc) acc_id = get_or_assign_account_write_id(xfer_acc);
DEBUG ("credit %d \n", acc_id);

View File

@ -1,10 +1,44 @@
#include "io-gncxml-v2.h"
struct _load_counter_struct
{
int accounts_total;
int accounts_loaded;
int commodities_total;
int commodities_loaded;
int transactions_total;
int transactions_loaded;
int prices_total;
int prices_loaded;
};
typedef struct _load_counter_struct load_counter;
static load_counter*
make_counter()
{
load_counter *ret;
ret = g_new0(load_counter, 1);
return ret;
}
gboolean
gnc_book_load_from_xml_file_v2(GNCBook *book)
{
sixtp_gdv2 gd;
gd.book = book;
gd.data = (gpointer)make_counter();
/* gd.addAccountFunc = add_account_local; */
return FALSE;
}

View File

@ -30,6 +30,8 @@ struct sixtp_global_data_v2_struct
gnc_commodity *com);
gboolean (*addTransactionFunc)(struct sixtp_global_data_v2_struct *data,
Transaction *act);
gboolean (*addPriceDBFunc)(struct sixtp_global_data_v2_struct *data,
GNCPrice *prc);
};
typedef struct sixtp_global_data_v2_struct sixtp_gdv2;

View File

@ -644,3 +644,82 @@ associate_commodity_ref_with_engine_commodity(gnc_commodity *com)
gnc_commodity_get_namespace(com),
gnc_commodity_get_mnemonic(com));
}
/***********************************************************************/
/* generic parser */
static void
dom_tree_handlers_reset(struct dom_tree_handler *handlers)
{
for(;handlers->tag != NULL; handlers++)
{
handlers->gotten = 0;
}
}
static gboolean
dom_tree_handlers_all_gotten_p(struct dom_tree_handler *handlers)
{
gboolean ret = TRUE;
for(;handlers->tag != NULL;handlers++)
{
if(handlers->required && ! handlers->gotten)
{
g_warning("Not defined and it should be: %s", handlers->tag);
ret = FALSE;
}
}
return ret;
}
static gboolean
gnc_xml_set_data(const gchar* tag, xmlNodePtr node, gboolean *item,
struct dom_tree_handler *handlers)
{
for(;handlers->tag != NULL; handlers++)
{
if(safe_strcmp(tag, handlers->tag) == 0)
{
(handlers->handler)(node, item);
handlers->gotten = TRUE;
break;
}
}
if(!handlers->tag)
{
g_warning("Unhandled tag: %s\n", tag);
return FALSE;
}
return TRUE;
}
gboolean
dom_tree_generic_parse(xmlNodePtr node, struct dom_tree_handler *handlers,
gpointer data)
{
xmlNodePtr achild;
gboolean successful = TRUE;
dom_tree_handlers_reset(handlers);
for(achild = node->xmlChildrenNode; achild; achild = achild->next)
{
if(!gnc_xml_set_data(achild->name, achild, data, handlers))
{
g_warning("gnc_xml_set_data failed");
successful = FALSE;
break;
}
}
if(!dom_tree_handlers_all_gotten_p(handlers))
{
g_warning("missing tag in input");
successful = FALSE;
}
return successful;
}

View File

@ -63,4 +63,20 @@ kvp_value* dom_tree_to_frame_kvp_value(xmlNodePtr node);
gboolean dom_tree_to_integer(xmlNodePtr node, gint64 *daint);
struct dom_tree_handler
{
const char *tag;
gboolean (*handler) (xmlNodePtr, gpointer);
int required;
int gotten;
};
gboolean dom_tree_generic_parse(xmlNodePtr node,
struct dom_tree_handler *handlers,
gpointer data);
#endif /* _SIXTP_DOM_PARSERS_H_ */

View File

@ -354,7 +354,12 @@ sixtp_sax_start_handler(void *user_data,
gboolean lookup_success = FALSE;
sixtp_stack_frame *new_frame = NULL;
g_return_if_fail(pdata->parsing_ok);
/* don't replace with g_return_if_fail because we don't want to see
the critical warnings. We error elsewhere. */
if(!pdata->parsing_ok)
{
return;
}
current_frame = (sixtp_stack_frame *) pdata->stack->data;
current_parser = current_frame->parser;
@ -426,7 +431,12 @@ sixtp_sax_characters_handler(void *user_data, const xmlChar *text, int len) {
sixtp_sax_data *pdata = (sixtp_sax_data *) user_data;
sixtp_stack_frame *frame;
g_return_if_fail(pdata->parsing_ok);
/* don't replace with g_return_if_fail because we don't want to see
the critical warnings. We error elsewhere. */
if(!pdata->parsing_ok)
{
return;
}
frame = (sixtp_stack_frame *) pdata->stack->data;
if(frame->parser->characters_handler) {
@ -465,7 +475,12 @@ sixtp_sax_end_handler(void *user_data, const xmlChar *name) {
sixtp_child_result *child_result_data = NULL;
gchar *end_tag = NULL;
g_return_if_fail(pdata->parsing_ok);
/* don't replace with g_return_if_fail because we don't want to see
the critical warnings. We error elsewhere. */
if(!pdata->parsing_ok)
{
return;
}
current_frame = (sixtp_stack_frame *) pdata->stack->data;
parent_frame = (sixtp_stack_frame *) pdata->stack->next->data;