large invasive patch to send account-deletion info to the backend

Hopefully the last such invasion ...


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3597 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Linas Vepstas
2001-02-05 10:09:57 +00:00
parent 8788434a5f
commit d590daddac
8 changed files with 290 additions and 199 deletions

View File

@@ -478,7 +478,6 @@ acc_restore_parent_end_handler(gpointer data_for_children,
g_return_val_if_fail(parent, FALSE);
xaccRemoveAccount(acc); /* just to be anal */
xaccAccountInsertSubAccount(parent, acc);
return(TRUE);

View File

@@ -53,6 +53,8 @@ static short module = MOD_ENGINE;
* of the internals of the Account in one file. *
\********************************************************************/
static void xaccAccountBringUpToDate(Account *acc);
/********************************************************************\
\********************************************************************/
@@ -109,6 +111,8 @@ xaccInitAccount (Account * acc)
acc->editlevel = 0;
acc->balance_dirty = FALSE;
acc->sort_dirty = FALSE;
acc->core_dirty = FALSE;
acc->do_free = FALSE;
xaccGUIDNew(&acc->guid);
xaccStoreEntity(acc, &acc->guid, GNC_ID_ACCOUNT);
@@ -145,36 +149,52 @@ xaccFreeAccount (Account *acc)
xaccRemoveEntity(&acc->guid);
/* First, recursively free children */
xaccFreeAccountGroup (acc->children);
if (acc->children)
{
PERR (" xinstead of calling xaccFreeAccount(), please call \n"
" xaccAccountBeginEdit(); xaccAccountDestroy(); \n");
/* First, recursively free children */
xaccFreeAccountGroup (acc->children);
acc->children = NULL;
}
/* Next, clean up the splits */
/* 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;
/* NB there shouldn't be any splits by now ... they should
* have been all been freed by CommitEdit(). We can remove this
* check once we know the warning isn't occurring any more. */
if (acc->splits)
{
PERR (" instead of calling xaccFreeAccount(), please call \n"
" xaccAccountBeginEdit(); xaccAccountDestroy(); \n");
/* 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;
}
acc->editlevel = 0;
for(lp = acc->splits; lp; lp = lp->next) {
Split *s = (Split *) lp->data;
t = s->parent;
xaccTransBeginEdit (t);
xaccSplitDestroy (s);
xaccTransCommitEdit (t);
}
/* free up array of split pointers */
g_list_free(acc->splits);
acc->splits = NULL;
}
/* FIXME: is this right? */
acc->editlevel = 0;
for(lp = acc->splits; lp; lp = lp->next) {
Split *s = (Split *) lp->data;
t = s->parent;
xaccTransBeginEdit (t);
xaccSplitDestroy (s);
xaccTransCommitEdit (t);
}
/* free up array of split pointers */
g_list_free(acc->splits);
acc->splits = NULL;
g_free (acc->accountName);
if (acc->accountName) g_free (acc->accountName);
acc->accountName = NULL;
g_free (acc->accountCode);
if (acc->accountCode) g_free (acc->accountCode);
acc->accountCode = NULL;
g_free (acc->description);
if (acc->description) g_free (acc->description);
acc->description = NULL;
kvp_frame_delete (acc->kvp_data);
@@ -207,10 +227,129 @@ xaccFreeAccount (Account *acc)
acc->editlevel = 0;
acc->balance_dirty = FALSE;
acc->sort_dirty = FALSE;
acc->core_dirty = FALSE;
g_free(acc);
}
/********************************************************************\
* transactional routines
\********************************************************************/
void
xaccAccountBeginEdit (Account *acc)
{
Backend * be;
if (!acc) return;
acc->editlevel++;
if (1 < acc->editlevel) return;
if (0 >= acc->editlevel)
{
PERR ("unbalanced call - resetting (was %d)", acc->editlevel);
acc->editlevel = 0;
}
acc->core_dirty = FALSE;
/* See if there's a backend. If there is, invoke it. */
be = xaccAccountGetBackend (acc);
if (be && be->account_begin_edit) {
(be->account_begin_edit) (be, acc);
}
}
void
xaccAccountCommitEdit (Account *acc)
{
Backend * be;
int rc;
if (!acc) return;
acc->editlevel--;
if (0 < acc->editlevel) return;
if (0 > acc->editlevel)
{
PERR ("unbalanced call - resetting (was %d)", acc->editlevel);
acc->editlevel = 0;
}
/* If marked for deletion, get rid of subaccounts first,
* and then the splits ... */
if (acc->do_free)
{
GList *lp;
/* First, recursively free children */
xaccFreeAccountGroup (acc->children);
acc->children = NULL;
PINFO ("freeing splits for account %p (%s)\n", acc, acc->accountName);
/* 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;
}
for(lp = acc->splits; lp; lp = lp->next)
{
Split *s = (Split *) lp->data;
Transaction *t = s->parent;
xaccTransBeginEdit (t);
xaccSplitDestroy (s);
xaccTransCommitEdit (t);
}
/* free up array of split pointers */
g_list_free(acc->splits);
acc->splits = NULL;
acc->core_dirty = TRUE;
}
else
{
xaccAccountBringUpToDate(acc);
}
/* See if there's a backend. If there is, invoke it. */
be = xaccAccountGetBackend (acc);
if (be && be->account_commit_edit)
{
rc = (be->account_commit_edit) (be, acc);
/* hack alert -- we really really should be checking
* for errors returned by the back end ... */
if (rc)
{
/* destroys must be rolled back as well ... ??? */
acc->do_free = FALSE;
PERR (" backend asked engine to rollback, but this isn't"
" handled yet. Return code=%d", rc);
}
}
acc->core_dirty = FALSE;
/* final stages of freeing the account */
if (acc->do_free)
{
xaccRemoveAccount(acc);
xaccFreeAccount(acc);
}
}
void
xaccAccountDestroy (Account *acc)
{
if (!acc) return;
acc->do_free = TRUE;
xaccAccountCommitEdit (acc);
}
/********************************************************************\
\********************************************************************/
@@ -272,7 +411,8 @@ split_sort_func(gconstpointer a, gconstpointer b) {
}
static void
xaccAccountSortSplits (Account *acc) {
xaccAccountSortSplits (Account *acc)
{
if(!acc) return;
if(!acc->sort_dirty) return;
@@ -282,7 +422,8 @@ xaccAccountSortSplits (Account *acc) {
}
static void
xaccAccountBringUpToDate(Account *acc) {
xaccAccountBringUpToDate(Account *acc)
{
if(!acc) return;
/* if a re-sort happens here, then everything will update, so the
@@ -291,60 +432,6 @@ xaccAccountBringUpToDate(Account *acc) {
xaccAccountRecomputeBalance(acc);
}
void
xaccAccountBeginEdit (Account *acc)
{
Backend * be;
if (!acc) return;
acc->editlevel++;
if (1 < acc->editlevel) return;
if (0 >= acc->editlevel)
{
PERR ("unbalanced call - resetting (was %d)", acc->editlevel);
acc->editlevel = 0;
}
/* See if there's a backend. If there is, invoke it. */
be = xaccAccountGetBackend (acc);
if (be && be->account_begin_edit) {
(be->account_begin_edit) (be, acc);
}
}
void
xaccAccountCommitEdit (Account *acc)
{
Backend * be;
int rc;
if (!acc) return;
acc->editlevel--;
if (0 < acc->editlevel) return;
if (0 > acc->editlevel)
{
PERR ("unbalanced call - resetting (was %d)", acc->editlevel);
acc->editlevel = 0;
}
xaccAccountBringUpToDate(acc);
/* See if there's a backend. If there is, invoke it. */
be = xaccAccountGetBackend (acc);
if (be && be->account_commit_edit) {
rc = (be->account_commit_edit) (be, acc);
/* hack alert -- we really really should be checking
* for errors returned by the back end ... */
if (rc)
{
PERR (" backend asked engine to rollback, but this isn't"
" handled yet. Return code=%d", rc);
}
}
}
/********************************************************************
* xaccAccountGetSlots
@@ -376,11 +463,14 @@ xaccAccountSetGUID (Account *account, GUID *guid)
if (!account || !guid) return;
PINFO("acct=%p", account);
xaccAccountBeginEdit (account);
xaccRemoveEntity(&account->guid);
account->guid = *guid;
xaccStoreEntity(account, &account->guid, GNC_ID_ACCOUNT);
account->core_dirty = TRUE;
xaccAccountCommitEdit (account);
}
/********************************************************************\
@@ -482,22 +572,6 @@ xaccClearMarkDownGr (AccountGroup *grp, short val)
/********************************************************************\
\********************************************************************/
G_INLINE_FUNC void check_open (Account *account);
G_INLINE_FUNC void
check_open (Account *account)
{
if (account->editlevel <= 0)
{
/* not today, some day in the future ... */
/* PERR ("Account not open for editing\n"); */
/* assert (0); */
/* return; */
}
}
/********************************************************************\
\********************************************************************/
void
xaccAccountInsertSplit (Account *acc, Split *split)
{
@@ -520,7 +594,6 @@ xaccAccountInsertSplit (Account *acc, Split *split)
xaccAccountBeginEdit(acc);
{
Account *oldacc;
check_open (acc);
acc->balance_dirty = TRUE;
acc->sort_dirty = TRUE;
@@ -572,8 +645,6 @@ xaccAccountRemoveSplit (Account *acc, Split *split)
{
GList *node;
check_open (acc);
node = g_list_find (acc->splits, split);
if (!node)
{
@@ -793,16 +864,15 @@ xaccAccountSetStartingBalance(Account *acc,
\********************************************************************/
void
xaccAccountFixSplitDateOrder (Account * acc, Split *split ) {
xaccAccountFixSplitDateOrder (Account * acc, Split *split )
{
if (NULL == acc) return;
if (NULL == split) return;
xaccAccountBeginEdit(acc);
{
acc->sort_dirty = TRUE;
acc->balance_dirty = TRUE;
}
xaccAccountCommitEdit(acc);
}
/********************************************************************\
@@ -913,6 +983,7 @@ xaccAccountAutoCode (Account *acc, int digits) {
{
acc->accountCode = xaccGroupGetNextFreeCode (acc->parent, digits);
acc->parent->saved = FALSE;
acc->core_dirty = TRUE;
}
xaccAccountCommitEdit(acc);
}
@@ -927,8 +998,6 @@ xaccAccountSetType (Account *acc, int tip) {
xaccAccountBeginEdit(acc);
{
check_open (acc);
/* refuse invalid account types, and don't bother if not new type. */
if((NUM_ACCOUNT_TYPES > tip) && (acc->type != tip)) {
acc->type = tip;
@@ -937,6 +1006,7 @@ xaccAccountSetType (Account *acc, int tip) {
mark_account (acc);
}
acc->core_dirty = TRUE;
xaccAccountCommitEdit(acc);
}
@@ -948,15 +1018,14 @@ xaccAccountSetName (Account *acc, const char *str) {
xaccAccountBeginEdit(acc);
{
check_open (acc);
/* make strdup before freeing */
/* make strdup before freeing (just in case str==accountName !!) */
tmp = g_strdup (str);
g_free (acc->accountName);
acc->accountName = tmp;
mark_account (acc);
}
acc->core_dirty = TRUE;
xaccAccountCommitEdit(acc);
}
@@ -967,8 +1036,6 @@ xaccAccountSetCode (Account *acc, const char *str) {
xaccAccountBeginEdit(acc);
{
check_open (acc);
/* make strdup before freeing */
tmp = g_strdup (str);
g_free (acc->accountCode);
@@ -976,6 +1043,7 @@ xaccAccountSetCode (Account *acc, const char *str) {
mark_account (acc);
}
acc->core_dirty = TRUE;
xaccAccountCommitEdit(acc);
}
@@ -986,15 +1054,14 @@ xaccAccountSetDescription (Account *acc, const char *str) {
xaccAccountBeginEdit(acc);
{
check_open (acc);
/* make strdup before freeing */
/* make strdup before freeing (just in case str==description !!) */
tmp = g_strdup (str);
g_free (acc->description);
acc->description = tmp;
mark_account (acc);
}
acc->core_dirty = TRUE;
xaccAccountCommitEdit(acc);
}
@@ -1006,8 +1073,6 @@ xaccAccountSetNotes (Account *acc, const char *str) {
xaccAccountBeginEdit(acc);
{
check_open (acc);
new_value = kvp_value_new_string(str);
if(new_value) {
kvp_frame_set_slot(xaccAccountGetSlots(acc), "notes", new_value);
@@ -1019,16 +1084,19 @@ xaccAccountSetNotes (Account *acc, const char *str) {
mark_account (acc);
}
acc->core_dirty = TRUE;
xaccAccountCommitEdit(acc);
}
/* FIXME : is this the right way to do this? */
static void
update_split_currency(Account * acc) {
update_split_currency(Account * acc)
{
GList *lp;
if(!acc) return;
xaccAccountBeginEdit(acc);
/* iterate over splits */
for(lp = acc->splits; lp; lp = lp->next) {
Split *s = (Split *) lp->data;
@@ -1039,6 +1107,7 @@ update_split_currency(Account * acc) {
xaccAccountGetSecuritySCU(acc),
GNC_RND_ROUND);
}
xaccAccountCommitEdit(acc);
}
/********************************************************************\
@@ -1053,6 +1122,7 @@ xaccAccountSetCommodity (Account * acc, const gnc_commodity * com)
{
if ((!acc) || (!com)) return;
xaccAccountBeginEdit(acc);
switch (acc->type)
{
case BANK:
@@ -1072,6 +1142,8 @@ xaccAccountSetCommodity (Account * acc, const gnc_commodity * com)
break;
default:
}
acc->core_dirty = TRUE;
xaccAccountCommitEdit(acc);
}
/********************************************************************\
@@ -1085,8 +1157,6 @@ xaccAccountSetCurrency (Account * acc, const gnc_commodity * currency) {
xaccAccountBeginEdit(acc);
{
check_open (acc);
acc->currency = currency;
acc->currency_scu = gnc_commodity_get_fraction(currency);
update_split_currency(acc);
@@ -1096,6 +1166,7 @@ xaccAccountSetCurrency (Account * acc, const gnc_commodity * currency) {
mark_account (acc);
}
acc->core_dirty = TRUE;
xaccAccountCommitEdit(acc);
}
@@ -1106,8 +1177,6 @@ xaccAccountSetSecurity (Account *acc, const gnc_commodity * security) {
xaccAccountBeginEdit(acc);
{
check_open (acc);
acc->security = security;
acc->security_scu = gnc_commodity_get_fraction(security);
update_split_currency(acc);
@@ -1117,6 +1186,7 @@ xaccAccountSetSecurity (Account *acc, const gnc_commodity * security) {
mark_account (acc);
}
acc->core_dirty = TRUE;
xaccAccountCommitEdit(acc);
}
@@ -1127,10 +1197,10 @@ xaccAccountSetCurrencySCU (Account * acc, int scu) {
xaccAccountBeginEdit(acc);
{
check_open (acc);
acc->currency_scu = scu;
mark_account (acc);
}
acc->core_dirty = TRUE;
xaccAccountCommitEdit(acc);
}
@@ -1141,10 +1211,10 @@ xaccAccountSetSecuritySCU (Account *acc, int scu) {
xaccAccountBeginEdit(acc);
{
check_open (acc);
acc->security_scu = scu;
mark_account (acc);
}
acc->core_dirty = TRUE;
xaccAccountCommitEdit(acc);
}
@@ -1449,8 +1519,6 @@ xaccAccountSetTaxRelated (Account *account, gboolean tax_related)
xaccAccountBeginEdit (account);
{
check_open (account);
kvp_frame_set_slot(xaccAccountGetSlots (account),
"tax-related", new_value);
@@ -1459,6 +1527,7 @@ xaccAccountSetTaxRelated (Account *account, gboolean tax_related)
mark_account (account);
}
account->core_dirty = TRUE;
xaccAccountCommitEdit (account);
}
@@ -1685,9 +1754,6 @@ xaccAccountSetReconcileLastDate (Account *account, time_t last_date)
xaccAccountBeginEdit (account);
{
kvp_value *value;
check_open (account);
value = kvp_value_new_gint64 (last_date);
kvp_frame_set_slot_path (xaccAccountGetSlots (account), value,
@@ -1697,6 +1763,7 @@ xaccAccountSetReconcileLastDate (Account *account, time_t last_date)
mark_account (account);
}
account->core_dirty = TRUE;
xaccAccountCommitEdit (account);
}
@@ -1740,8 +1807,6 @@ xaccAccountSetReconcilePostponeDate (Account *account,
{
kvp_value *value;
check_open (account);
value = kvp_value_new_gint64 (postpone_date);
kvp_frame_set_slot_path (xaccAccountGetSlots (account), value,
@@ -1751,6 +1816,7 @@ xaccAccountSetReconcilePostponeDate (Account *account,
mark_account (account);
}
account->core_dirty = TRUE;
xaccAccountCommitEdit (account);
}
@@ -1795,8 +1861,6 @@ xaccAccountSetReconcilePostponeBalance (Account *account,
{
kvp_value *value;
check_open (account);
value = kvp_value_new_gnc_numeric (balance);
kvp_frame_set_slot_path (xaccAccountGetSlots (account), value,
@@ -1806,6 +1870,7 @@ xaccAccountSetReconcilePostponeBalance (Account *account,
mark_account (account);
}
account->core_dirty = TRUE;
xaccAccountCommitEdit (account);
}
@@ -1819,13 +1884,12 @@ xaccAccountClearReconcilePostpone (Account *account)
xaccAccountBeginEdit (account);
{
check_open (account);
kvp_frame_set_slot_path (xaccAccountGetSlots (account), NULL,
"reconcile-info", "postpone", NULL);
mark_account (account);
}
account->core_dirty = TRUE;
xaccAccountCommitEdit (account);
}
@@ -1858,8 +1922,6 @@ xaccAccountSetLastNum (Account *account, const char *num)
{
kvp_value *value;
check_open (account);
value = kvp_value_new_string (num);
kvp_frame_set_slot (xaccAccountGetSlots (account), "last-num", value);
@@ -1868,6 +1930,7 @@ xaccAccountSetLastNum (Account *account, const char *num)
mark_account (account);
}
account->core_dirty = TRUE;
xaccAccountCommitEdit (account);
}
@@ -1886,7 +1949,6 @@ xaccAccountSetPriceSrc(Account *acc, const char *src) {
if((t == STOCK) || (t == MUTUAL)) {
kvp_value *new_value = kvp_value_new_string(src);
if(new_value) {
check_open (acc);
kvp_frame_set_slot(xaccAccountGetSlots(acc),
"old-price-source",
new_value);
@@ -1897,6 +1959,7 @@ xaccAccountSetPriceSrc(Account *acc, const char *src) {
}
}
}
acc->core_dirty = TRUE;
xaccAccountCommitEdit(acc);
}

View File

@@ -116,21 +116,22 @@ GNCAccountType xaccAccountStringToEnum (const char* str);
gboolean xaccAccountTypesCompatible (int parent_type, int child_type);
Account *xaccMallocAccount (void);
void xaccFreeAccount (Account *account);
/* Compare two accounts for equality - this is a deep compare. */
gboolean xaccAccountEqual(Account *a, Account* b, gboolean check_guids);
/*
* The xaccAccountBeginEdit() and xaccAccountCommitEdit() subroutines
* provide a pseudo-two-phase-commit wrapper for account updates.
* They are mildly useful for detecting attempted updates outside
* of their scope. However, they do not provide any true two-phase-anything
* in the current implementation.
* provide a two-phase-commit wrapper for account updates.
* They are incompletely implemented ....
*
* The xaccAccountDestroy() routine can be used to get rid of an
* account. The account should have been opened for editing
* (by calling xaccAccountBeginEdit()) before calling this routine.
*/
Account *xaccMallocAccount (void);
void xaccAccountBeginEdit (Account *account);
void xaccAccountCommitEdit (Account *account);
void xaccAccountDestroy (Account *account);
kvp_frame * xaccAccountGetSlots (Account *account);

View File

@@ -126,20 +126,13 @@ struct _account {
GList *splits; /* list of split pointers */
/* The "changed" flag is used to invalidate cached values in this structure.
* Currently, the balances and the cost basis are cached.
*/
/*short changed;*/
/* The "open" flag indicates if the account has been
* opened for editing. */
/* short open; */
/* keep track of nesting level of begin/end edit calls */
gint32 editlevel;
gboolean balance_dirty;
gboolean sort_dirty;
gboolean core_dirty; /* fields in this struct have changed */
gboolean do_free;
/* The "mark" flag can be used by the user to mark this account
* in any way desired. Handy for specialty traversals of the
@@ -147,16 +140,6 @@ struct _account {
short mark;
};
/* bitfields for the changed flag */
#define ACC_INVALID_BALN 0x1
#define ACC_INVALID_COSTB 0x2
#define ACC_INVALIDATE_ALL 0x3
/* bitflields for the open flag */
#define ACC_BEGIN_EDIT 0x1
#define ACC_DEFER_REBALANCE 0x2
#define ACC_BEING_DESTROYED 0x4
/* The xaccAccountRemoveSplit() routine will remove the indicated split
* from the indicated account. Note that this will leave the split
@@ -197,4 +180,11 @@ void xaccAccountSetStartingBalance(Account *account,
const gnc_numeric start_cleared_baln,
const gnc_numeric start_reconciled_baln);
/* The xaccFreeAccount() routine releases memory associated with the
* account. It should never be called directly from user code;
* instead, the xaccAccountDestroy() routine should be used
* (because xaccAccountDestroy() has the correct commit semantics).
*/
void xaccFreeAccount (Account *account);
#endif /* __XACC_ACCOUNT_P_H__ */

View File

@@ -21,6 +21,8 @@
* *
\********************************************************************/
#include <glib.h>
#include "Account.h"
#include "AccountP.h"
#include "BackendP.h"
@@ -68,13 +70,13 @@ xaccAccountGetBackend (Account * acc)
if (!acc) return NULL;
/* find the first account group that has a backend */
grp = (AccountGroup *) acc->parent;
grp = acc->parent;
while (grp) {
if (grp->backend) return (grp->backend);
parent_acc = grp -> parent;
grp = NULL;
if (parent_acc) {
grp = (AccountGroup *) parent_acc->parent;
grp = parent_acc->parent;
}
}
return NULL;
@@ -87,17 +89,34 @@ xaccAccountGetBackend (Account * acc)
Backend *
xaccTransactionGetBackend (Transaction *trans)
{
Split *s;
GList *snode, *node;
Split *s=NULL;
if (!trans) return NULL;
/* find an account */
s = xaccTransGetSplit (trans, 0);
if (!s) {
s = xaccTransGetSplit (trans->orig, 0);
if (!s) return NULL;
}
snode = xaccTransGetSplitList(trans);
for (node = snode; node; node=node->next)
{
s = node->data;
if (s->acc) break;
s = NULL;
}
/* if transaction is being deleted, it won't have any splits
* so lets take a look at the 'original' transaction */
if (!s)
{
snode = xaccTransGetSplitList(trans->orig);
for (node = snode; node; node=node->next)
{
s = node->data;
if (s->acc) break;
s = NULL;
}
}
if (!s) return NULL;
/* I suppose it would be more 'technically correct' to make sure that
* all splits share the same backend, and flag an error if they
* don't. However, at this point, it seems quite unlikely, so we'll

View File

@@ -159,28 +159,37 @@ xaccAccountGroupCommitEdit (AccountGroup *grp)
void
xaccFreeAccountGroup (AccountGroup *grp)
{
GList *node;
if (!grp) return;
xaccAccountGroupBeginEdit (grp);
for (node = grp->accounts; node; node = node->next)
if (grp->accounts)
{
Account *account = node->data;
xaccFreeAccount (account);
Account *account;
/* This is a weird iterator & needs some explanation.
* xaccAccountDestroy() will rip the account out
* of the list, thus iterating while grp->accounts
* is non-null is enough to iterate the loop. But
* when it deletes the last account, then it will also
* delete the group, making the grp pointer invalid.
* So we have to be careful with the last deletion:
* in particular, g_free(grp) would be freeing that
* memory a second time, so don't do it.
*/
while (grp->accounts->next)
{
account = grp->accounts->next->data;
xaccAccountBeginEdit (account);
xaccAccountDestroy (account);
}
account = grp->accounts->data;
xaccAccountBeginEdit (account);
xaccAccountDestroy (account);
}
else
{
grp->parent = NULL;
grp->balance = gnc_numeric_zero();
g_free (grp);
}
g_list_free (grp->accounts);
/* null everything out, just in case somebody
* tries to traverse freed memory */
grp->parent = NULL;
grp->accounts = NULL;
grp->balance = gnc_numeric_zero();
g_free (grp);
}
/********************************************************************\
@@ -925,7 +934,8 @@ xaccGroupMergeAccounts (AccountGroup *grp)
/* remove from list -- node_a is ok, it's before node_b */
grp->accounts = g_list_remove (grp->accounts, acc_b);
xaccFreeAccount (acc_b);
xaccAccountBeginEdit (acc_b);
xaccAccountDestroy (acc_b);
break;
}
}

View File

@@ -1118,6 +1118,13 @@ xaccTransFindCommonCurrency (Transaction *trans)
gnc_commodity_get_unique_name (retval));
}
if (NULL == retval)
{
/* in every situation I can think of, this routine should return
* common currency. So make note of this ... */
PWARN ("unable to find a common currency, and that is strange.");
}
return retval;
}
@@ -1298,7 +1305,8 @@ xaccTransCommitEdit (Transaction *trans)
/* See if there's a backend. If there is, invoke it. */
PINFO ("descr is %s", xaccTransGetDescription(trans));
be = xaccTransactionGetBackend (trans);
if (be && be->trans_commit_edit) {
if (be && be->trans_commit_edit)
{
int rc = 0;
rc = (be->trans_commit_edit) (be, trans, trans->orig);
@@ -1593,21 +1601,20 @@ xaccSplitDestroy (Split *split)
if (!split) return;
trans = split->parent;
if (trans)
{
check_open (trans);
}
check_open (trans);
mark_split (split);
xaccRemoveEntity (&split->guid);
if (trans)
{
gboolean ismember = (g_list_find (trans->splits, split) != NULL);
assert (ismember);
}
mark_split (split);
if (trans)
xaccTransRemoveSplit (trans, split);
}
xaccAccountRemoveSplit (split->acc, split);
xaccAccountRecomputeBalance (split->acc);
@@ -1623,8 +1630,7 @@ xaccTransAppendSplit (Transaction *trans, Split *split)
{
Transaction *oldtrans;
if (!trans) return;
if (!split) return;
if (!trans || !split) return;
check_open (trans);

View File

@@ -578,6 +578,8 @@ gnc_book_save (GNCBook *book)
if (ERR_BACKEND_NO_ERR != retval)
{
gnc_book_push_error (book, retval);
/* we close the backend here ... isn't this a bit harsh ??? */
if (be->book_end)
{
(be->book_end)(be);
@@ -655,6 +657,7 @@ gnc_book_destroy (GNCBook *book)
/* destroy the backend */
if (book->backend) g_free(book->backend);
xaccGroupSetBackend (book->topgroup, NULL);
xaccFreeAccountGroup (book->topgroup);
book->topgroup = NULL;