mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
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:
parent
cad90da64b
commit
a14bf2bfab
84
ChangeLog
84
ChangeLog
@ -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
4
debian/changelog
vendored
@ -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
1
debian/rules
vendored
@ -25,6 +25,7 @@ Makefile: Makefile.in configure
|
||||
--mandir=/usr/share/man \
|
||||
--enable-error-on-warnings
|
||||
|
||||
# --enable-efence \
|
||||
# --enable-profile \
|
||||
|
||||
build: build-stamp
|
||||
|
@ -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;>
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 \
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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__ */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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_ */
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user