From 5b18db7e5a7acac9b91227c009013bf4100a0e4c Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Fri, 19 May 2000 06:00:25 +0000 Subject: [PATCH] mostly cosmetic, with one actual bug fix git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@2351 57a11ea4-9604-0410-9ed3-97b8803252fd --- src/engine/Transaction.c | 140 ++++++++++++++++++++------------------- 1 file changed, 72 insertions(+), 68 deletions(-) diff --git a/src/engine/Transaction.c b/src/engine/Transaction.c index 9b4c84cfc6..c6d8cc9bbf 100644 --- a/src/engine/Transaction.c +++ b/src/engine/Transaction.c @@ -62,6 +62,7 @@ int force_double_entry = 0; /* bit-field flags for controlling transaction commits */ #define BEGIN_EDIT 0x1 #define DEFER_REBALANCE 0x2 +#define BEING_DESTROYED 0x4 /********************************************************************\ * Because I can't use C++ for this project, doesn't mean that I * @@ -102,8 +103,10 @@ xaccInitSplit(Split * split) split->share_cleared_balance = 0.0; split->share_reconciled_balance = 0.0; split->cost_basis = 0.0; - split->ticket = 0; + + xaccGUIDNew(&split->guid); + xaccStoreEntity(split, &split->guid, GNC_ID_SPLIT); } /********************************************************************\ @@ -113,13 +116,7 @@ Split * xaccMallocSplit(void) { Split *split = (Split *)_malloc(sizeof(Split)); - xaccInitSplit (split); - - xaccGUIDNew(&split->guid); - - xaccStoreEntity(split, &split->guid, GNC_ID_SPLIT); - return split; } @@ -149,6 +146,8 @@ xaccCloneSplit (Split *s) split->date_reconciled.tv_sec = s->date_reconciled.tv_sec; split->date_reconciled.tv_nsec = s->date_reconciled.tv_nsec; + /* copy(!) the guid. The cloned split is *not* unique, + * is a sick twisted clone that holds 'undo' information. */ split->guid = s->guid; /* no need to futz with the balances; these get wiped each time ... @@ -193,35 +192,33 @@ xaccFreeSplit( Split *split ) /********************************************************************\ \********************************************************************/ + const GUID * xaccSplitGetGUID (Split *split) { - if (!split) - return xaccGUIDNULL(); - + if (!split) return xaccGUIDNULL(); return &split->guid; } /********************************************************************\ \********************************************************************/ -void xaccSplitSetGUID (Split *split, GUID *guid) + +void +xaccSplitSetGUID (Split *split, GUID *guid) { if (!split || !guid) return; - xaccRemoveEntity(&split->guid); - split->guid = *guid; - xaccStoreEntity(split, &split->guid, GNC_ID_SPLIT); } /********************************************************************\ \********************************************************************/ + Split * xaccSplitLookup (const GUID *guid) { if (!guid) return NULL; - return xaccLookupEntity(guid, GNC_ID_SPLIT); } @@ -365,14 +362,14 @@ xaccInitTransaction( Transaction * trans ) { Split *split; - /* fill in some sane defaults */ + /* Fill in some sane defaults */ trans->num = strdup(""); trans->description = strdup(""); trans->docref = strdup(""); trans->splits = (Split **) _malloc (3* sizeof (Split *)); - /* create a single split only. As soon as the balance becomes + /* Create a single split only. As soon as the balance becomes * non-zero, additional splits will get created. */ split = xaccMallocSplit (); @@ -389,6 +386,9 @@ xaccInitTransaction( Transaction * trans ) trans->marker = 0; trans->open = 0; trans->orig = NULL; + + xaccGUIDNew(&trans->guid); + xaccStoreEntity(trans, &trans->guid, GNC_ID_TRANS); } /********************************************************************\ @@ -398,13 +398,7 @@ Transaction * xaccMallocTransaction( void ) { Transaction *trans = (Transaction *)_malloc(sizeof(Transaction)); - xaccInitTransaction (trans); - - xaccGUIDNew(&trans->guid); - - xaccStoreEntity(trans, &trans->guid, GNC_ID_TRANS); - return trans; } @@ -447,6 +441,8 @@ xaccCloneTransaction (Transaction *t) trans->open = 0; trans->orig = NULL; + /* copy(!) the guid. The cloned transaction is *not* unique, + * is a sick twisted clone that holds 'undo' information. */ trans->guid = t->guid; return (trans); @@ -509,31 +505,30 @@ xaccFreeTransaction( Transaction *trans ) /********************************************************************\ \********************************************************************/ + const GUID * xaccTransGetGUID (Transaction *trans) { - if (!trans) - return xaccGUIDNULL(); - + if (!trans) return xaccGUIDNULL(); return &trans->guid; } /********************************************************************\ \********************************************************************/ -void xaccTransSetGUID (Transaction *trans, GUID *guid) + +void +xaccTransSetGUID (Transaction *trans, GUID *guid) { if (!trans || !guid) return; - xaccRemoveEntity(&trans->guid); - trans->guid = *guid; - xaccStoreEntity(trans, &trans->guid, GNC_ID_TRANS); } /********************************************************************\ \********************************************************************/ + Transaction * xaccTransLookup (const GUID *guid) { @@ -981,7 +976,7 @@ xaccTransBeginEdit (Transaction *trans, int defer) void xaccTransCommitEdit (Transaction *trans) { - int i, rc; + int i, rc=0; Split *split; Account *acc; Backend *be; @@ -996,7 +991,7 @@ xaccTransCommitEdit (Transaction *trans) * return. */ split = trans->splits[0]; - if (!split) + if (!split || (trans->open & BEING_DESTROYED)) { PINFO ("delete trans at addr=%p\n", trans); /* Make a log in the journal before destruction. */ @@ -1049,6 +1044,7 @@ xaccTransCommitEdit (Transaction *trans) /* See if there's a backend. If there is, invoke it. */ be = xaccTransactionGetBackend (trans); + rc = 0; if (be && be->trans_commit_edit) { rc = (be->trans_commit_edit) (be, trans, trans->orig); } @@ -1084,7 +1080,7 @@ xaccTransCommitEdit (Transaction *trans) trans->open = 0; xaccTransWriteLog (trans, 'C'); - /* get rid of the copy we made. We won't be rolling back, + /* Get rid of the copy we made. We won't be rolling back, * so we don't need it any more. */ xaccFreeTransaction (trans->orig); trans->orig = NULL; @@ -1109,6 +1105,8 @@ xaccTransRollbackEdit (Transaction *trans) /* copy the original values back in. */ orig = trans->orig; + /* If the transaction had been deleted before the rollback, + * the guid would have been unlisted. Restore that */ xaccStoreEntity(trans, &trans->guid, GNC_ID_TRANS); #define PUT_BACK(val) { free(trans->val); trans->val=orig->val; orig->val=0x0; } @@ -1130,34 +1128,39 @@ xaccTransRollbackEdit (Transaction *trans) * CheckDateOrder routine could be cpu-cyle brutal, so it maybe * it could use some tuning ... */ - i=0; - s = trans->splits[0]; - so = orig->splits[0]; - while (s && so) { - if (so->acc != s->acc) { force_it = 1; mismatch=i; break; } - -#define HONKY_CAT(val) { free(s->val); s->val=so->val; so->val=0x0; } - HONKY_CAT (action); - HONKY_CAT (memo); - HONKY_CAT (docref); - - s->reconciled = so->reconciled; - s->damount = so->damount; - s->share_price = so->share_price; - - s->date_reconciled.tv_sec = so->date_reconciled.tv_sec; - s->date_reconciled.tv_nsec = so->date_reconciled.tv_nsec; - - /* do NOT check date order until all of the other fields - * have been properly restored */ - xaccCheckDateOrder (s->acc, s); - MARK_SPLIT (s); - xaccAccountRecomputeBalance (s->acc); - i++; - s = trans->splits[i]; - so = orig->splits[i]; + if (trans->open & BEING_DESTROYED) { + force_it = 1; + mismatch = 0; + } else { + i=0; + s = trans->splits[0]; + so = orig->splits[0]; + while (s && so) { + if (so->acc != s->acc) { force_it = 1; mismatch=i; break; } + + #define HONKY_CAT(val) { free(s->val); s->val=so->val; so->val=0x0; } + HONKY_CAT (action); + HONKY_CAT (memo); + HONKY_CAT (docref); + + s->reconciled = so->reconciled; + s->damount = so->damount; + s->share_price = so->share_price; + + s->date_reconciled.tv_sec = so->date_reconciled.tv_sec; + s->date_reconciled.tv_nsec = so->date_reconciled.tv_nsec; + + /* do NOT check date order until all of the other fields + * have been properly restored */ + xaccCheckDateOrder (s->acc, s); + MARK_SPLIT (s); + xaccAccountRecomputeBalance (s->acc); + i++; + s = trans->splits[i]; + so = orig->splits[i]; + } + if (so != s) { force_it = 1; mismatch=i; } } - if (so != s) { force_it = 1; mismatch=i; } /* OK, if force_it got set, we'll have to tough it out and brute-force * the rest of the way. Clobber all the edited splits, add all new splits. @@ -1175,9 +1178,9 @@ xaccTransRollbackEdit (Transaction *trans) while (s) { acc = s->acc; MARK_SPLIT (s); - xaccRemoveEntity(&s->guid); xaccAccountRemoveSplit (acc, s); xaccAccountRecomputeBalance (acc); + xaccRemoveEntity(&s->guid); xaccFreeSplit (s); i++; s = trans->splits[i]; @@ -1212,9 +1215,8 @@ xaccTransRollbackEdit (Transaction *trans) gncBoolean xaccTransIsOpen (Transaction *trans) { - if (trans == NULL) return GNC_F; - - return ((trans->open & BEGIN_EDIT) != 0); + if (!trans) return GNC_F; + return (0 != (trans->open & BEGIN_EDIT)); } /********************************************************************\ @@ -1229,24 +1231,25 @@ xaccTransDestroy (Transaction *trans) if (!trans) return; CHECK_OPEN (trans); + trans->open |= BEING_DESTROYED; xaccTransWriteLog (trans, 'D'); - xaccRemoveEntity(&trans->guid); - i=0; split = trans->splits[i]; while (split) { MARK_SPLIT (split); acc = split ->acc; - xaccRemoveEntity(&split->guid); xaccAccountRemoveSplit (acc, split); xaccAccountRecomputeBalance (acc); + xaccRemoveEntity(&split->guid); xaccFreeSplit (split); trans->splits[i] = NULL; i++; split = trans->splits[i]; } + xaccRemoveEntity(&trans->guid); + /* the actual free is done with the commit call, else its rolled back */ /* xaccFreeTransaction (trans); don't do this here ... */ } @@ -1286,7 +1289,8 @@ xaccSplitDestroy (Split *split) * Or if the account has only two splits, * then this destroy will leave only one split. * Don't rebalance, as this will goof up the - * value of the remaining split. + * value of the remaining split. (The rebalance + * happens later(?) during commit(?).) */ MARK_SPLIT (split); xaccTransRemoveSplit (trans, split);