mirror of
https://github.com/Gnucash/gnucash.git
synced 2024-11-22 17:06:36 -06:00
*** empty log message ***
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@2183 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
d8704ffea5
commit
58058e8010
11
ChangeLog
11
ChangeLog
@ -1,3 +1,14 @@
|
||||
2000-04-14 Dave Peticolas <peticola@cs.ucdavis.edu>
|
||||
|
||||
* lots of build system files: changes for the global id stuff.
|
||||
|
||||
* src/engine/GNCId.c: engine globally unique id api implementation.
|
||||
|
||||
* src/engine/guid/md5.c: taken from GNU textutils.
|
||||
|
||||
* src/engine/guid/guid.c: new file with routines for generating
|
||||
globally unique ids.
|
||||
|
||||
2000-04-10 Dave Peticolas <peticola@cs.ucdavis.edu>
|
||||
|
||||
* doc/README: only the environment variable LANG needs to
|
||||
|
@ -1,8 +1,22 @@
|
||||
### -*-makefile-*- #################################################
|
||||
## Makefile.common
|
||||
##
|
||||
## standard targets and rules
|
||||
####################################################################
|
||||
# Makefile.common -- standard targets and rules
|
||||
# Copyright (C) 2000 Linas Vepstas
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, contact:
|
||||
#
|
||||
# Free Software Foundation Voice: +1-617-542-5942
|
||||
# 59 Temple Place - Suite 330 Fax: +1-617-542-2652
|
||||
# Boston, MA 02111-1307, USA gnu@gnu.org
|
||||
|
||||
# Autoconf notes...
|
||||
# Need to handle -MD there.
|
||||
@ -34,6 +48,11 @@ ifdef GNOME_CONFIG_BIN
|
||||
GNOME_CFLAGS += $(shell ${GNOME_CONFIG_BIN} --cflags gnomeui)
|
||||
endif
|
||||
|
||||
ifdef GLIB_CONFIG_BIN
|
||||
GLIB_CFLAGS := $(shell ${GLIB_CONFIG_BIN} --cflags)
|
||||
GLIB_LIBS := $(shell ${GLIB_CONFIG_BIN} --libs)
|
||||
endif
|
||||
|
||||
QT_FLAGS :=
|
||||
|
||||
|
||||
|
12
Makefile.in
12
Makefile.in
@ -14,13 +14,11 @@
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Author: Robin Clark
|
||||
# Internet: rclark@rush.aero.org
|
||||
# Address: 609 8th Street
|
||||
# Huntington Beach, CA 92648-4632
|
||||
# along with this program; if not, contact:
|
||||
#
|
||||
# Free Software Foundation Voice: +1-617-542-5942
|
||||
# 59 Temple Place - Suite 330 Fax: +1-617-542-2652
|
||||
# Boston, MA 02111-1307, USA gnu@gnu.org
|
||||
|
||||
include @top_srcdir@/Makefile.init
|
||||
|
||||
|
@ -1,3 +1,23 @@
|
||||
# Makefile.init -- configured make variables
|
||||
# Copyright (C) 2000 Linas Vepstas
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, contact:
|
||||
#
|
||||
# Free Software Foundation Voice: +1-617-542-5942
|
||||
# 59 Temple Place - Suite 330 Fax: +1-617-542-2652
|
||||
# Boston, MA 02111-1307, USA gnu@gnu.org
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
export PATH := @GUILE_BIN@:@ABSOLUTE_TOP_SRCDIR@/lib/g-wrap-install/bin/:${PATH}
|
||||
|
@ -39,6 +39,12 @@
|
||||
/* Enable debugging stuff */
|
||||
#define USE_DEBUG
|
||||
|
||||
/* Standard C headers present */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* memcpy present */
|
||||
#undef HAVE_MEMCPY
|
||||
|
||||
/* check for stpcpy for Solaris */
|
||||
#undef HAVE_STPCPY
|
||||
|
||||
|
@ -38,8 +38,10 @@ AC_PROG_CC
|
||||
AC_ISC_POSIX
|
||||
AC_C_BIGENDIAN
|
||||
AC_PROG_MAKE_SET
|
||||
AC_HEADER_STDC
|
||||
|
||||
AC_CHECK_FUNCS(stpcpy memcpy)
|
||||
|
||||
AC_CHECK_FUNCS(stpcpy)
|
||||
|
||||
### --------------------------------------------------------------------------
|
||||
### Fix up prefix for recursive expansion
|
||||
|
@ -13,19 +13,18 @@
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Author: Robin Clark
|
||||
# Internet: rclark@rush.aero.org
|
||||
# Address: 609 8th Street
|
||||
# Huntington Beach, CA 92648-4632
|
||||
# along with this program; if not, contact:
|
||||
#
|
||||
# Free Software Foundation Voice: +1-617-542-5942
|
||||
# 59 Temple Place - Suite 330 Fax: +1-617-542-2652
|
||||
# Boston, MA 02111-1307, USA gnu@gnu.org
|
||||
|
||||
include @top_srcdir@/Makefile.init
|
||||
|
||||
INCLPATH = -I. \
|
||||
-I.. \
|
||||
-I./engine \
|
||||
-I./engine/guid \
|
||||
-I./register \
|
||||
-Ireports \
|
||||
-I@srcdir@/../include \
|
||||
|
@ -1,7 +1,7 @@
|
||||
/********************************************************************\
|
||||
* Account.c -- the Account data structure *
|
||||
* Copyright (C) 1997 Robin D. Clark *
|
||||
* Copyright (C) 1997, 1998, 1999 Linas Vepstas *
|
||||
* Copyright (C) 1997, 1998, 1999, 2000 Linas Vepstas *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
@ -14,13 +14,12 @@
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
* Author: Rob Clark *
|
||||
* Internet: rclark@cs.hmc.edu *
|
||||
* Address: 609 8th Street *
|
||||
* Huntington Beach, CA 92648-4632 *
|
||||
\********************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
@ -37,6 +36,7 @@
|
||||
#include "Queue.h"
|
||||
#include "Transaction.h"
|
||||
#include "TransactionP.h"
|
||||
#include "GNCIdP.h"
|
||||
#include "util.h"
|
||||
|
||||
/* The unsafe_ops flag allows certain unsafe manipulations to be
|
||||
@ -109,7 +109,17 @@ Account *
|
||||
xaccMallocAccount( void )
|
||||
{
|
||||
Account *acc = (Account *)_malloc(sizeof(Account));
|
||||
|
||||
xaccInitAccount (acc);
|
||||
|
||||
guid_new(&acc->guid);
|
||||
|
||||
if (xaccGUIDType(&acc->guid) != GNC_ID_NONE) {
|
||||
PWARN("xaccMallocAccount: duplicate id\n");
|
||||
}
|
||||
|
||||
xaccStoreEntity(acc, &acc->guid, GNC_ID_ACCOUNT);
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
@ -124,10 +134,12 @@ xaccFreeAccount( Account *acc )
|
||||
Transaction *t;
|
||||
|
||||
if (NULL == acc) return;
|
||||
|
||||
|
||||
xaccRemoveEntity(&acc->guid);
|
||||
|
||||
/* First, recursively free children */
|
||||
xaccFreeAccountGroup (acc->children);
|
||||
|
||||
|
||||
/* Next, clean up the splits */
|
||||
/* any split pointing at this account needs to be unmarked */
|
||||
for (i=0; i<acc->numSplits; i++) {
|
||||
@ -152,7 +164,7 @@ xaccFreeAccount( Account *acc )
|
||||
_free (acc->splits);
|
||||
acc->splits = NULL;
|
||||
acc->numSplits = 0;
|
||||
|
||||
|
||||
/* Finally, clean up the account info */
|
||||
if (acc->accInfo) xaccFreeAccInfo (acc->accInfo);
|
||||
acc->accInfo = NULL;
|
||||
@ -208,6 +220,24 @@ xaccAccountCommitEdit (Account *acc)
|
||||
acc->open = 0;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
GUID *
|
||||
xaccAccountGetGUID (Account *account)
|
||||
{
|
||||
if (!account) return NULL;
|
||||
return &account->guid;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
Account *
|
||||
xaccAccountLookup (GUID *guid)
|
||||
{
|
||||
if (!guid) return NULL;
|
||||
return xaccLookupEntity(guid, GNC_ID_ACCOUNT);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
@ -896,9 +926,9 @@ xaccConsolidateTransactions (Account * acc)
|
||||
if (xaccSplitGetReconcile(sa) != NREC)
|
||||
continue;
|
||||
|
||||
/* We get the matching split using the tickee value
|
||||
/* We get the matching split using the ticket value
|
||||
generated by xaccTransMatch above. */
|
||||
sb = xaccTransGetSplit(tb, sa->tickee);
|
||||
sb = xaccTransGetSplit(tb, sa->ticket);
|
||||
|
||||
xaccSplitSetReconcile (sa, xaccSplitGetReconcile(sb));
|
||||
xaccSplitGetDateReconciledTS (sb, &ts);
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "config.h"
|
||||
#include "AccInfo.h"
|
||||
#include "Transaction.h"
|
||||
#include "GNCId.h"
|
||||
|
||||
|
||||
/** PROTOTYPES ******************************************************/
|
||||
@ -49,6 +50,19 @@ void xaccFreeAccount( Account * );
|
||||
void xaccAccountBeginEdit (Account *, int defer);
|
||||
void xaccAccountCommitEdit (Account *);
|
||||
|
||||
/*
|
||||
* The xaccAccountGetGUID() subroutine will return the
|
||||
* globally unique id associated with that account.
|
||||
* User code should use this id to reference accounts
|
||||
* and *not* the integer account id below.
|
||||
*
|
||||
* The xaccAccountLookup() subroutine will return the
|
||||
* account associated with the given id, or NULL
|
||||
* if there is no such account.
|
||||
*/
|
||||
GUID * xaccAccountGetGUID (Account *account);
|
||||
Account * xaccAccountLookup (GUID *guid);
|
||||
|
||||
int xaccGetAccountID (Account *);
|
||||
char xaccGetAccountFlags (Account *);
|
||||
|
||||
@ -56,11 +70,11 @@ char xaccGetAccountFlags (Account *);
|
||||
* The xaccAccountInsertSplit() method will insert the indicated
|
||||
* split into the indicated account. If the split already
|
||||
* belongs to another account, it will be removed from that
|
||||
* account first.
|
||||
* account first.
|
||||
*/
|
||||
void xaccAccountInsertSplit (Account *, Split *);
|
||||
|
||||
/* The xaccCheckDateOrder() surboutine checks to see if
|
||||
/* The xaccCheckDateOrder() subroutine checks to see if
|
||||
* a split is in proper sorted date order with respect
|
||||
* to the other splits in this account.
|
||||
*
|
||||
@ -109,13 +123,13 @@ void xaccConsolidateTransactions (Account *);
|
||||
|
||||
/* The xaccMoveFarEnd() method changes the account to which the
|
||||
* "far end" of the split belongs. The "far end" is as follows:
|
||||
* Double-entry transactions by thier nature consist of a set of
|
||||
* Double-entry transactions by their nature consist of a set of
|
||||
* two or more splits. If the transaction has precisely two splits,
|
||||
* then the "far end" is the "other split" of the pair. If
|
||||
* the transaction consists of three or more splits, then the
|
||||
* "far end" is undefined. All that the xaccMoveFareEnd() method
|
||||
* does is reparent the "other split" to the indicated account.
|
||||
* The first argument is the split whose fare end will be changed,
|
||||
* The first argument is the split whose far end will be changed,
|
||||
* the second argument is the new far-end account.
|
||||
*/
|
||||
|
||||
|
@ -1,3 +1,27 @@
|
||||
/********************************************************************\
|
||||
* Account.h -- the Account data structure *
|
||||
* Copyright (C) 1997 Robin D. Clark *
|
||||
* Copyright (C) 1997, 1998, 1999 Linas Vepstas *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
/*
|
||||
* FILE:
|
||||
* AccountP.h
|
||||
@ -15,37 +39,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/********************************************************************\
|
||||
* Account.h -- the Account data structure *
|
||||
* Copyright (C) 1997 Robin D. Clark *
|
||||
* Copyright (C) 1997, 1998, 1999 Linas Vepstas *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* *
|
||||
* Author: Rob Clark *
|
||||
* Internet: rclark@cs.hmc.edu *
|
||||
* Address: 609 8th Street *
|
||||
* Huntington Beach, CA 92648-4632 *
|
||||
\********************************************************************/
|
||||
|
||||
#ifndef __XACC_ACCOUNT_P_H__
|
||||
#define __XACC_ACCOUNT_P_H__
|
||||
|
||||
#include "config.h"
|
||||
#include "AccInfo.h"
|
||||
#include "Transaction.h"
|
||||
#include "GNCId.h"
|
||||
|
||||
|
||||
/** STRUCTS *********************************************************/
|
||||
struct _account {
|
||||
@ -106,7 +107,7 @@ struct _account {
|
||||
char *security;
|
||||
|
||||
/* The parent and children pointers are used to implement an account
|
||||
* heirarchy, of accounts that have sub-accounts ("detail accounts").
|
||||
* hierarchy, of accounts that have sub-accounts ("detail accounts").
|
||||
*/
|
||||
AccountGroup *parent; /* back-pointer to parent */
|
||||
AccountGroup *children; /* pointer to sub-accounts */
|
||||
@ -117,6 +118,8 @@ struct _account {
|
||||
int id; /* unique account id, internally assigned */
|
||||
char flags;
|
||||
|
||||
GUID guid; /* globally unique account id */
|
||||
|
||||
/* protected data, cached parameters */
|
||||
double balance;
|
||||
double cleared_balance;
|
||||
|
@ -97,6 +97,7 @@
|
||||
#include "Transaction.h"
|
||||
#include "TransactionP.h"
|
||||
#include "TransLog.h"
|
||||
#include "GNCIdP.h"
|
||||
#include "util.h"
|
||||
|
||||
#define PERMS 0666
|
||||
@ -155,7 +156,7 @@ static int writeTSDate( int fd, Timespec *);
|
||||
/*******************************************************/
|
||||
/* backwards compatibility definitions for numeric value
|
||||
* of account type. These numbers are used (are to be
|
||||
* used) no where else but here, precisely because they
|
||||
* used) nowhere else but here, precisely because they
|
||||
* are non-portable. The values of these defines MUST
|
||||
* NOT BE CHANGED; ANY CHANGES WILL BREAK FILE COMPATIBILITY.
|
||||
* YOU HAVE BEEN WARNED!!!!
|
||||
@ -307,14 +308,14 @@ xaccReadAccountGroup( int fd )
|
||||
|
||||
maingrp = 0x0;
|
||||
error_code = ERR_FILEIO_NO_ERROR;
|
||||
|
||||
|
||||
/* check for valid file descriptor */
|
||||
if( 0 > fd )
|
||||
{
|
||||
error_code = ERR_FILEIO_FILE_NOT_FOUND;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Read in the file format token */
|
||||
err = read( fd, &token, sizeof(int) );
|
||||
if( sizeof(int) != err )
|
||||
@ -534,7 +535,7 @@ readAccount( int fd, AccountGroup *grp, int token )
|
||||
xaccAccountSetCurrency (acc, DEFAULT_CURRENCY);
|
||||
}
|
||||
|
||||
/* aux account info first appears in versin ten files */
|
||||
/* aux account info first appears in version ten files */
|
||||
if (10 <= token) {
|
||||
readAccInfo( fd, acc, token );
|
||||
}
|
||||
@ -600,7 +601,7 @@ readAccount( int fd, AccountGroup *grp, int token )
|
||||
* With the double-entry system, the file may reference accounts
|
||||
* that have not yet been read or properly parented. Thus, we need
|
||||
* a way of dealing with this, and this routine performs this
|
||||
* work. Basically, accounts are requested by thier id. If an
|
||||
* work. Basically, accounts are requested by their id. If an
|
||||
* account with the indicated ID does not exist, it is created
|
||||
* and placed in a temporary holding cell. Accounts in the
|
||||
* holding cell can be located, (so that transactions can be
|
||||
@ -632,19 +633,19 @@ locateAccount (int acc_id)
|
||||
|
||||
/* normalize the account numbers -- positive-definite.
|
||||
* That is, the unique id must never decrease,
|
||||
* nor must it overalp any existing account id */
|
||||
* nor must it overlap any existing account id */
|
||||
if (next_free_unique_account_id <= acc_id) {
|
||||
next_free_unique_account_id = acc_id+1;
|
||||
}
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
|
||||
static Account *
|
||||
springAccount (int acc_id)
|
||||
{
|
||||
Account * acc;
|
||||
|
||||
|
||||
/* first, see if we're confused about the account */
|
||||
acc = xaccGetAccountFromID (maingrp, acc_id);
|
||||
if (acc) {
|
||||
@ -665,7 +666,7 @@ springAccount (int acc_id)
|
||||
printf ("Couldn't find account \n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************\
|
||||
* readInvAcct *
|
||||
* reads in the auxilliary account info *
|
||||
@ -1005,6 +1006,7 @@ readTransaction( int fd, Account *acc, int token )
|
||||
* Later versions don't have this. */
|
||||
offset = 1;
|
||||
split = readSplit (fd, token);
|
||||
xaccRemoveEntity(&trans->splits[0]->guid);
|
||||
xaccFreeSplit (trans->splits[0]);
|
||||
trans->splits[0] = split;
|
||||
split->parent = trans;
|
||||
@ -1024,6 +1026,7 @@ readTransaction( int fd, Account *acc, int token )
|
||||
split = readSplit (fd, token);
|
||||
if (0 == i+offset) {
|
||||
/* the first split has been malloced. just replace it */
|
||||
xaccRemoveEntity (&trans->splits[i+offset]->guid);
|
||||
xaccFreeSplit (trans->splits[i+offset]);
|
||||
trans->splits[i+offset] = split;
|
||||
split->parent = trans;
|
||||
|
221
src/engine/GNCId.c
Normal file
221
src/engine/GNCId.c
Normal file
@ -0,0 +1,221 @@
|
||||
/********************************************************************\
|
||||
* GNCId.c -- Gnucash entity identifier implementation *
|
||||
* Copyright (C) 2000 Dave Peticolas <peticola@cs.ucdavis.edu> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "GNCIdP.h"
|
||||
|
||||
|
||||
/** Type definitions ************************************************/
|
||||
typedef struct entity_node
|
||||
{
|
||||
GNCIdType entity_type;
|
||||
gpointer entity;
|
||||
} EntityNode;
|
||||
|
||||
|
||||
/** Static global variables *****************************************/
|
||||
static GHashTable * entity_table = NULL;
|
||||
|
||||
|
||||
/** Function implementations ****************************************/
|
||||
|
||||
static gboolean
|
||||
entity_node_destroy(gpointer key, gpointer value, gpointer not_used)
|
||||
{
|
||||
GUID *guid = key;
|
||||
EntityNode *e_node = value;
|
||||
|
||||
e_node->entity_type = GNC_ID_NONE;
|
||||
e_node->entity = NULL;
|
||||
|
||||
g_free(guid);
|
||||
g_free(e_node);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void entity_table_destroy()
|
||||
{
|
||||
if (entity_table == NULL)
|
||||
return;
|
||||
|
||||
g_hash_table_foreach_remove(entity_table, entity_node_destroy, NULL);
|
||||
g_hash_table_destroy(entity_table);
|
||||
|
||||
entity_table = NULL;
|
||||
}
|
||||
|
||||
static guint
|
||||
id_hash(gconstpointer key)
|
||||
{
|
||||
const GUID *guid = key;
|
||||
|
||||
if (key == NULL)
|
||||
return 0;
|
||||
|
||||
if (sizeof(guint) <= 16)
|
||||
return *((guint *) guid->data);
|
||||
else
|
||||
{
|
||||
guint hash = 0;
|
||||
int i, j;
|
||||
|
||||
for (i = 0, j = 0; i < sizeof(guint); i++, j++)
|
||||
{
|
||||
if (j == 16)
|
||||
j = 0;
|
||||
|
||||
hash <<= 4;
|
||||
hash |= guid->data[j];
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
id_compare(gconstpointer key_1, gconstpointer key_2)
|
||||
{
|
||||
return memcmp(key_1, key_2, sizeof(GUID)) == 0;
|
||||
}
|
||||
|
||||
static void summarize_table();
|
||||
|
||||
static void
|
||||
entity_table_init()
|
||||
{
|
||||
if (entity_table != NULL)
|
||||
entity_table_destroy();
|
||||
|
||||
entity_table = g_hash_table_new(id_hash, id_compare);
|
||||
|
||||
atexit(summarize_table);
|
||||
}
|
||||
|
||||
GNCIdType
|
||||
xaccGUIDType(GUID * guid)
|
||||
{
|
||||
EntityNode *e_node;
|
||||
|
||||
if (guid == NULL)
|
||||
return GNC_ID_NONE;
|
||||
|
||||
if (entity_table == NULL)
|
||||
entity_table_init();
|
||||
|
||||
e_node = g_hash_table_lookup(entity_table, guid->data);
|
||||
if (e_node == NULL)
|
||||
return GNC_ID_NONE;
|
||||
|
||||
return e_node->entity_type;
|
||||
}
|
||||
|
||||
void *
|
||||
xaccLookupEntity(GUID * guid, GNCIdType entity_type)
|
||||
{
|
||||
EntityNode *e_node;
|
||||
|
||||
if (guid == NULL)
|
||||
return NULL;
|
||||
|
||||
if (entity_table == NULL)
|
||||
entity_table_init();
|
||||
|
||||
e_node = g_hash_table_lookup(entity_table, guid->data);
|
||||
if (e_node == NULL)
|
||||
return NULL;
|
||||
|
||||
if (e_node->entity_type != entity_type)
|
||||
return NULL;
|
||||
|
||||
return e_node->entity;
|
||||
}
|
||||
|
||||
void
|
||||
xaccStoreEntity(void * entity, GUID * guid, GNCIdType entity_type)
|
||||
{
|
||||
EntityNode *e_node;
|
||||
GUID *new_guid;
|
||||
|
||||
if (entity == NULL)
|
||||
return;
|
||||
|
||||
if (guid == NULL)
|
||||
return;
|
||||
|
||||
if ((entity_type <= GNC_ID_NONE) || (entity_type > LAST_GNC_ID))
|
||||
return;
|
||||
|
||||
xaccRemoveEntity(guid);
|
||||
|
||||
e_node = g_new(EntityNode, 1);
|
||||
e_node->entity_type = entity_type;
|
||||
e_node->entity = entity;
|
||||
|
||||
new_guid = g_new(GUID, 1);
|
||||
*new_guid = *guid;
|
||||
|
||||
g_hash_table_insert(entity_table, new_guid, e_node);
|
||||
}
|
||||
|
||||
void
|
||||
xaccRemoveEntity(GUID * guid)
|
||||
{
|
||||
gpointer e_node;
|
||||
gpointer old_guid;
|
||||
|
||||
if (guid == NULL)
|
||||
return;
|
||||
|
||||
if (entity_table == NULL)
|
||||
entity_table_init();
|
||||
|
||||
if (g_hash_table_lookup_extended(entity_table, guid, &old_guid, &e_node))
|
||||
{
|
||||
g_hash_table_remove(entity_table, old_guid);
|
||||
entity_node_destroy(old_guid, e_node, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_node(gpointer key, gpointer value, gpointer not_used)
|
||||
{
|
||||
GUID *guid = key;
|
||||
EntityNode *node = value;
|
||||
|
||||
fprintf(stderr, "%s %d %p\n",
|
||||
guid_to_string(guid), node->entity_type, node->entity);
|
||||
}
|
||||
|
||||
static void
|
||||
summarize_table()
|
||||
{
|
||||
if (entity_table == NULL)
|
||||
return;
|
||||
|
||||
g_hash_table_foreach(entity_table, print_node, NULL);
|
||||
}
|
64
src/engine/GNCId.h
Normal file
64
src/engine/GNCId.h
Normal file
@ -0,0 +1,64 @@
|
||||
/********************************************************************\
|
||||
* GNCId.h -- Gnucash entity identifier API *
|
||||
* Copyright (C) 2000 Dave Peticolas <peticola@cs.ucdavis.edu> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
#ifndef __GNC_ID__
|
||||
#define __GNC_ID__ 1
|
||||
|
||||
/* This file defines an API for using gnucash entity identifiers.
|
||||
*
|
||||
* Identifiers can be used to reference Account Groups, Accounts,
|
||||
* Transactions, and Splits. These four Gnucash types are referred to
|
||||
* as Gnucash entities. Identifiers are globally-unique and permanent,
|
||||
* i.e., once an entity has been assigned an identifier, it retains
|
||||
* that same identifier for its lifetime.
|
||||
*
|
||||
* Identifiers can be encoded as hex strings. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "guid.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
/* Identifiers are 'typed' with integers. The ids used in gnucash are
|
||||
* defined below. An id with type GNC_ID_NONE does not refer to any
|
||||
* entity. An identifier with a type other than GNC_ID_NONE may refer
|
||||
* to an actual entity, but that is not guaranteed. If an id does
|
||||
* refer to an entity, the type of the entity will match the type
|
||||
* of the identifier. */
|
||||
typedef enum
|
||||
{
|
||||
GNC_ID_NONE = 0,
|
||||
GNC_ID_GROUP,
|
||||
GNC_ID_ACCOUNT,
|
||||
GNC_ID_TRANS,
|
||||
GNC_ID_SPLIT,
|
||||
LAST_GNC_ID = GNC_ID_SPLIT
|
||||
} GNCIdType;
|
||||
|
||||
|
||||
/* Return the type of an identifier. */
|
||||
GNCIdType xaccGUIDType(GUID * guid);
|
||||
|
||||
|
||||
#endif
|
45
src/engine/GNCIdP.h
Normal file
45
src/engine/GNCIdP.h
Normal file
@ -0,0 +1,45 @@
|
||||
/********************************************************************\
|
||||
* GNCIdP.h -- Gnucash entity identifier engine-only API *
|
||||
* Copyright (C) 2000 Dave Peticolas <peticola@cs.ucdavis.edu> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
#ifndef __GNC_ID_P__
|
||||
#define __GNC_ID_P__ 1
|
||||
|
||||
#include "GNCId.h"
|
||||
|
||||
/* This file defines an engine-only API for using gnucash entity
|
||||
* identifiers. */
|
||||
|
||||
/* Lookup an entity given an id and a type. If there is no entity
|
||||
* associated with the id, or if it has a different type, NULL
|
||||
* is returned. */
|
||||
void * xaccLookupEntity(GUID * guid, GNCIdType entity_type);
|
||||
|
||||
/* Store the given entity under the given id with the given type. */
|
||||
void xaccStoreEntity(void * entity, GUID * guid, GNCIdType entity_type);
|
||||
|
||||
/* Remove any existing association between an entity and the given
|
||||
* id. The entity is not changed in any way. */
|
||||
void xaccRemoveEntity(GUID * guid);
|
||||
|
||||
|
||||
#endif
|
@ -14,13 +14,12 @@
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
* Author: Rob Clark *
|
||||
* Internet: rclark@cs.hmc.edu *
|
||||
* Address: 609 8th Street *
|
||||
* Huntington Beach, CA 92648-4632 *
|
||||
\********************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
@ -33,9 +32,12 @@
|
||||
#include "Group.h"
|
||||
#include "GroupP.h"
|
||||
#include "TransactionP.h"
|
||||
#include "GNCIdP.h"
|
||||
#include "util.h"
|
||||
#include "gnc-common.h"
|
||||
|
||||
static short module = MOD_ENGINE;
|
||||
|
||||
/********************************************************************\
|
||||
* Because I can't use C++ for this project, doesn't mean that I *
|
||||
* can't pretend to! These functions perform actions on the *
|
||||
@ -49,12 +51,12 @@ void
|
||||
xaccInitializeAccountGroup (AccountGroup *grp)
|
||||
{
|
||||
grp->saved = GNC_T;
|
||||
|
||||
|
||||
grp->parent = NULL;
|
||||
grp->numAcc = 0;
|
||||
grp->account = _malloc (sizeof (Account *));
|
||||
grp->account[0] = NULL; /* null-terminated array */
|
||||
|
||||
|
||||
grp->balance = 0.0;
|
||||
}
|
||||
|
||||
@ -64,9 +66,17 @@ AccountGroup *
|
||||
xaccMallocAccountGroup( void )
|
||||
{
|
||||
AccountGroup *grp = (AccountGroup *)_malloc(sizeof(AccountGroup));
|
||||
|
||||
|
||||
xaccInitializeAccountGroup (grp);
|
||||
|
||||
guid_new(&grp->guid);
|
||||
|
||||
if (xaccGUIDType(&grp->guid) != GNC_ID_NONE) {
|
||||
PWARN("xaccMallocAccountGroup: duplicate id\n");
|
||||
}
|
||||
|
||||
xaccStoreEntity(grp, &grp->guid, GNC_ID_GROUP);
|
||||
|
||||
return grp;
|
||||
}
|
||||
|
||||
@ -76,12 +86,14 @@ void
|
||||
xaccFreeAccountGroup( AccountGroup *grp )
|
||||
{
|
||||
int i;
|
||||
|
||||
if (NULL == grp) return;
|
||||
|
||||
for( i=0; i<grp->numAcc; i++ ) {
|
||||
xaccRemoveEntity(&grp->guid);
|
||||
|
||||
for( i=0; i<grp->numAcc; i++ )
|
||||
xaccFreeAccount( grp->account[i] );
|
||||
}
|
||||
|
||||
|
||||
_free( grp->account );
|
||||
|
||||
/* null everything out, just in case somebody
|
||||
@ -90,7 +102,7 @@ xaccFreeAccountGroup( AccountGroup *grp )
|
||||
grp->numAcc = 0;
|
||||
grp->account = NULL;
|
||||
grp->balance = 0.0;
|
||||
|
||||
|
||||
_free(grp);
|
||||
}
|
||||
|
||||
@ -136,6 +148,24 @@ xaccAccountGroupNotSaved (AccountGroup *grp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
GUID *
|
||||
xaccGroupGetGUID (AccountGroup *group)
|
||||
{
|
||||
if (!group) return NULL;
|
||||
return &group->guid;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
AccountGroup *
|
||||
xaccGroupLookup (GUID *guid)
|
||||
{
|
||||
if (!guid) return NULL;
|
||||
return xaccLookupEntity(guid, GNC_ID_GROUP);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* Get the number of accounts, including subaccounts *
|
||||
\********************************************************************/
|
||||
@ -758,7 +788,7 @@ xaccConcatGroups (AccountGroup *togrp, AccountGroup *fromgrp)
|
||||
|
||||
if (!togrp) return;
|
||||
if (!fromgrp) return;
|
||||
|
||||
|
||||
/* The act of inserting the account into togrp also causes
|
||||
* it to automatically be deleted from fromgrp. But use a
|
||||
* saved copy of fromgrp's numAcc member since, after the
|
||||
|
@ -1,7 +1,7 @@
|
||||
/********************************************************************\
|
||||
* Group.h -- the main data structure of the program *
|
||||
* Copyright (C) 1997 Robin D. Clark *
|
||||
* Copyright (C) 1997, 1998 Linas Vepstas *
|
||||
* Copyright (C) 1997, 1998, 1999, 2000 Linas Vepstas *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
@ -14,13 +14,12 @@
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
* Author: Rob Clark *
|
||||
* Internet: rclark@cs.hmc.edu *
|
||||
* Address: 609 8th Street *
|
||||
* Huntington Beach, CA 92648-4632 *
|
||||
\********************************************************************/
|
||||
|
||||
#ifndef __XACC_ACCOUNT_GROUP_H__
|
||||
@ -30,10 +29,23 @@
|
||||
#include "gnc-common.h"
|
||||
|
||||
#include "Account.h"
|
||||
#include "GNCId.h"
|
||||
|
||||
|
||||
/** PROTOTYPES ******************************************************/
|
||||
AccountGroup *xaccMallocAccountGroup( void );
|
||||
void xaccFreeAccountGroup( AccountGroup *account_group );
|
||||
AccountGroup *xaccMallocAccountGroup( void );
|
||||
void xaccFreeAccountGroup( AccountGroup *account_group );
|
||||
|
||||
/*
|
||||
* The xaccGroupGetGUID() subroutine will return the
|
||||
* globally unique id associated with that group.
|
||||
*
|
||||
* The xaccGroupLookup() subroutine will return the
|
||||
* group associated with the given id, or NULL
|
||||
* if there is no such group.
|
||||
*/
|
||||
GUID * xaccGroupGetGUID (AccountGroup *group);
|
||||
AccountGroup * xaccGroupLookup (GUID *guid);
|
||||
|
||||
/*
|
||||
* The xaccConcatGroups() subroutine will move all accounts
|
||||
|
@ -1,17 +1,7 @@
|
||||
/*
|
||||
* FILE:
|
||||
* GroupP.h
|
||||
*
|
||||
* FUNCTION:
|
||||
* This is the *private* account group structure.
|
||||
* This header should *not* be included by any code outside of the
|
||||
* engine.
|
||||
*
|
||||
*/
|
||||
/********************************************************************\
|
||||
* GroupP.h -- the main data structure of the program *
|
||||
* Copyright (C) 1997 Robin D. Clark *
|
||||
* Copyright (C) 1997, 1998 Linas Vepstas *
|
||||
* Copyright (C) 1997, 1998, 1999, 2000 Linas Vepstas *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
@ -24,20 +14,32 @@
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
* Author: Rob Clark *
|
||||
* Internet: rclark@cs.hmc.edu *
|
||||
* Address: 609 8th Street *
|
||||
* Huntington Beach, CA 92648-4632 *
|
||||
\********************************************************************/
|
||||
|
||||
/*
|
||||
* FILE:
|
||||
* GroupP.h
|
||||
*
|
||||
* FUNCTION:
|
||||
* This is the *private* account group structure.
|
||||
* This header should *not* be included by any code outside of the
|
||||
* engine.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __XACC_ACCOUNT_GROUP_P_H__
|
||||
#define __XACC_ACCOUNT_GROUP_P_H__
|
||||
|
||||
#include "config.h"
|
||||
#include "Transaction.h"
|
||||
#include "GNCId.h"
|
||||
|
||||
|
||||
/** STRUCTS *********************************************************/
|
||||
struct _account_group {
|
||||
@ -50,9 +52,10 @@ struct _account_group {
|
||||
int numAcc; /* number of accounts in array */
|
||||
Account **account; /* array of account pointers */
|
||||
|
||||
GUID guid; /* globally unique id */
|
||||
|
||||
/* cached parameters */
|
||||
double balance;
|
||||
|
||||
};
|
||||
|
||||
#endif /* __XACC_ACCOUNT_GROUP_P_H__ */
|
||||
|
@ -14,27 +14,30 @@
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Author: Robin Clark
|
||||
# Internet: rclark@rush.aero.org
|
||||
# Address: 609 8th Street
|
||||
# Huntington Beach, CA 92648-4632
|
||||
# along with this program; if not, contact:
|
||||
#
|
||||
# Free Software Foundation Voice: +1-617-542-5942
|
||||
# 59 Temple Place - Suite 330 Fax: +1-617-542-2652
|
||||
# Boston, MA 02111-1307, USA gnu@gnu.org
|
||||
|
||||
include @top_srcdir@/Makefile.init
|
||||
|
||||
INCLPATH = -I@srcdir@/../../include -I@srcdir@/../.. -I@prefix@/include
|
||||
INCLPATH = -I@srcdir@/../../include \
|
||||
-I@srcdir@/../.. \
|
||||
-I@srcdir@/guid \
|
||||
-I@prefix@/include
|
||||
|
||||
# add the -fpic flag to generate relocatable position independent code
|
||||
# for the engine so that in can be used in a shared module (e.g. a perl module)
|
||||
CFLAGS = @CFLAGS@ ${INCLPATH} -fpic
|
||||
# for the engine so that in can be used in a shared module (e.g. a perl module)
|
||||
CFLAGS = @CFLAGS@ ${INCLPATH} -fpic ${GLIB_CFLAGS}
|
||||
LIBS = @LIBS@ ${GLIB_LIBS}
|
||||
|
||||
######################################################################
|
||||
# See Makefile.common for information about these variables.
|
||||
INDEP_SRCS := AccInfo.c Account.c DateUtils.c FileIO.c Group.c \
|
||||
LedgerUtils.c QIFIO.c Query.c Queue.c Scrub.c Session.c \
|
||||
Transaction.c TransLog.c date.c util.c
|
||||
Transaction.c TransLog.c date.c util.c GNCId.c \
|
||||
guid/md5.c guid/guid.c
|
||||
######################################################################
|
||||
|
||||
all: default
|
||||
|
@ -14,13 +14,12 @@
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
* Author: Rob Clark *
|
||||
* Internet: rclark@cs.hmc.edu *
|
||||
* Address: 609 8th Street *
|
||||
* Huntington Beach, CA 92648-4632 *
|
||||
\********************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
@ -37,6 +36,7 @@
|
||||
#include "Transaction.h"
|
||||
#include "TransactionP.h"
|
||||
#include "TransLog.h"
|
||||
#include "GNCIdP.h"
|
||||
#include "util.h"
|
||||
#include "date.h"
|
||||
|
||||
@ -102,7 +102,7 @@ xaccInitSplit(Split * split)
|
||||
split->share_reconciled_balance = 0.0;
|
||||
split->cost_basis = 0.0;
|
||||
|
||||
split->tickee = 0;
|
||||
split->ticket = 0;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
@ -112,7 +112,17 @@ Split *
|
||||
xaccMallocSplit(void)
|
||||
{
|
||||
Split *split = (Split *)_malloc(sizeof(Split));
|
||||
|
||||
xaccInitSplit (split);
|
||||
|
||||
guid_new(&split->guid);
|
||||
|
||||
if (xaccGUIDType(&split->guid) != GNC_ID_NONE) {
|
||||
PWARN("xaccMallocSplit: duplicate id\n");
|
||||
}
|
||||
|
||||
xaccStoreEntity(split, &split->guid, GNC_ID_SPLIT);
|
||||
|
||||
return split;
|
||||
}
|
||||
|
||||
@ -142,6 +152,8 @@ xaccCloneSplit (Split *s)
|
||||
split->date_reconciled.tv_sec = s->date_reconciled.tv_sec;
|
||||
split->date_reconciled.tv_nsec = s->date_reconciled.tv_nsec;
|
||||
|
||||
split->guid = s->guid;
|
||||
|
||||
/* no need to futz with the balances; these get wiped each time ...
|
||||
* split->balance = s->balance;
|
||||
* split->cleared_balance = s->cleared_balance;
|
||||
@ -182,6 +194,24 @@ xaccFreeSplit( Split *split )
|
||||
_free(split);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
GUID *
|
||||
xaccSplitGetGUID (Split *split)
|
||||
{
|
||||
if (!split) return NULL;
|
||||
return &split->guid;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
Split *
|
||||
xaccSplitLookup (GUID *guid)
|
||||
{
|
||||
if (!guid) return NULL;
|
||||
return xaccLookupEntity(guid, GNC_ID_SPLIT);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
@ -355,7 +385,17 @@ Transaction *
|
||||
xaccMallocTransaction( void )
|
||||
{
|
||||
Transaction *trans = (Transaction *)_malloc(sizeof(Transaction));
|
||||
|
||||
xaccInitTransaction (trans);
|
||||
|
||||
guid_new(&trans->guid);
|
||||
|
||||
if (xaccGUIDType(&trans->guid) != GNC_ID_NONE) {
|
||||
PWARN("xaccMallocTransaction: duplicate id\n");
|
||||
}
|
||||
|
||||
xaccStoreEntity(trans, &trans->guid, GNC_ID_TRANS);
|
||||
|
||||
return trans;
|
||||
}
|
||||
|
||||
@ -380,7 +420,7 @@ xaccCloneTransaction (Transaction *t)
|
||||
trans->docref = strdup(t->docref);
|
||||
|
||||
n=0; while (t->splits[n]) n++;
|
||||
trans->splits = (Split **) _malloc ((n+1)* sizeof (Split *));
|
||||
trans->splits = (Split **) _malloc ((n+1)* sizeof (Split *));
|
||||
|
||||
n=0;
|
||||
while (t->splits[n]) {
|
||||
@ -398,6 +438,8 @@ xaccCloneTransaction (Transaction *t)
|
||||
trans->open = 0;
|
||||
trans->orig = NULL;
|
||||
|
||||
trans->guid = t->guid;
|
||||
|
||||
return (trans);
|
||||
}
|
||||
|
||||
@ -412,6 +454,7 @@ xaccFreeTransaction( Transaction *trans )
|
||||
Split *s;
|
||||
|
||||
if (!trans) return;
|
||||
|
||||
ENTER ("xaccFreeTransaction(): addr=%p\n", trans);
|
||||
|
||||
/* free up the destination splits */
|
||||
@ -451,9 +494,28 @@ xaccFreeTransaction( Transaction *trans )
|
||||
}
|
||||
|
||||
_free(trans);
|
||||
|
||||
LEAVE ("xaccFreeTransaction(): addr=%p\n", trans);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
GUID *
|
||||
xaccTransGetGUID (Transaction *trans)
|
||||
{
|
||||
if (!trans) return NULL;
|
||||
return &trans->guid;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
Transaction *
|
||||
xaccTransLookup (GUID *guid)
|
||||
{
|
||||
if (!guid) return NULL;
|
||||
return xaccLookupEntity(guid, GNC_ID_TRANS);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
@ -752,6 +814,7 @@ xaccSplitRebalance (Split *split)
|
||||
if (!trans) return;
|
||||
|
||||
if (DEFER_REBALANCE & (trans->open)) return;
|
||||
|
||||
if (split->acc) {
|
||||
char *ra, *rb;
|
||||
if (ACC_DEFER_REBALANCE & (split->acc->open)) return;
|
||||
@ -908,6 +971,7 @@ xaccTransCommitEdit (Transaction *trans)
|
||||
PINFO ("xaccTransCommitEdit(): delete trans at addr=%p\n", trans);
|
||||
/* Make a log in the journal before destruction. */
|
||||
xaccTransWriteLog (trans, 'D');
|
||||
xaccRemoveEntity(&trans->guid);
|
||||
xaccFreeTransaction (trans);
|
||||
return;
|
||||
}
|
||||
@ -987,12 +1051,16 @@ xaccTransRollbackEdit (Transaction *trans)
|
||||
int force_it=0, mismatch=0, i;
|
||||
|
||||
if (!trans) return;
|
||||
|
||||
CHECK_OPEN (trans);
|
||||
|
||||
ENTER ("xaccTransRollbackEdit(): trans addr=%p\n", trans);
|
||||
|
||||
/* copy the original values back in. */
|
||||
orig = trans->orig;
|
||||
|
||||
xaccStoreEntity(trans, &trans->guid, GNC_ID_TRANS);
|
||||
|
||||
#define PUT_BACK(val) { free(trans->val); trans->val=orig->val; orig->val=0x0; }
|
||||
PUT_BACK (num);
|
||||
PUT_BACK (description);
|
||||
@ -1012,7 +1080,7 @@ xaccTransRollbackEdit (Transaction *trans)
|
||||
* CheckDateOrder routine could be cpu-cyle brutal, so it maybe
|
||||
* it could use some tuning ...
|
||||
*/
|
||||
i=0;
|
||||
i=0;
|
||||
s = trans->splits[0];
|
||||
so = orig->splits[0];
|
||||
while (s && so) {
|
||||
@ -1030,8 +1098,8 @@ xaccTransRollbackEdit (Transaction *trans)
|
||||
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 teh other fields
|
||||
* have beenproperly restored */
|
||||
/* 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);
|
||||
@ -1051,12 +1119,13 @@ xaccTransRollbackEdit (Transaction *trans)
|
||||
xaccFreeSplit (orig->splits[i]);
|
||||
orig->splits[i] = s;
|
||||
i++;
|
||||
s = trans->splits[i];
|
||||
s = trans->splits[i];
|
||||
}
|
||||
i=mismatch; s = trans->splits[i];
|
||||
while (s) {
|
||||
acc = s->acc;
|
||||
MARK_SPLIT (s);
|
||||
xaccRemoveEntity(&s->guid);
|
||||
xaccAccountRemoveSplit (acc, s);
|
||||
xaccAccountRecomputeBalance (acc);
|
||||
xaccFreeSplit (s);
|
||||
@ -1064,26 +1133,29 @@ xaccTransRollbackEdit (Transaction *trans)
|
||||
s = trans->splits[i];
|
||||
}
|
||||
_free (trans->splits);
|
||||
|
||||
|
||||
trans->splits = orig->splits;
|
||||
orig->splits = NULL;
|
||||
|
||||
|
||||
i=mismatch; s = trans->splits[i];
|
||||
while (s) {
|
||||
acc = s->acc;
|
||||
MARK_SPLIT (s);
|
||||
xaccStoreEntity(s, &s->guid, GNC_ID_SPLIT);
|
||||
xaccAccountInsertSplit (acc, s);
|
||||
xaccAccountRecomputeBalance (acc);
|
||||
i++;
|
||||
s = trans->splits[i];
|
||||
s = trans->splits[i];
|
||||
}
|
||||
}
|
||||
|
||||
xaccTransWriteLog (trans, 'R');
|
||||
|
||||
xaccFreeTransaction (trans->orig);
|
||||
|
||||
trans->orig = NULL;
|
||||
trans->open = 0;
|
||||
|
||||
LEAVE ("xaccTransRollbackEdit(): trans addr=%p\n", trans);
|
||||
}
|
||||
|
||||
@ -1109,11 +1181,14 @@ xaccTransDestroy (Transaction *trans)
|
||||
CHECK_OPEN (trans);
|
||||
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);
|
||||
xaccFreeSplit (split);
|
||||
@ -1143,6 +1218,8 @@ xaccSplitDestroy (Split *split)
|
||||
assert (trans->splits);
|
||||
CHECK_OPEN (trans);
|
||||
|
||||
xaccRemoveEntity(&split->guid);
|
||||
|
||||
numsplits = 0;
|
||||
s = trans->splits[0];
|
||||
while (s) {
|
||||
@ -1159,7 +1236,7 @@ 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 teh remaining split.
|
||||
* value of the remaining split.
|
||||
*/
|
||||
MARK_SPLIT (split);
|
||||
xaccTransRemoveSplit (trans, split);
|
||||
@ -1248,7 +1325,7 @@ xaccTransRemoveSplit (Transaction *trans, Split *split)
|
||||
* returns a positive value if transaction a is dated later than b,
|
||||
*
|
||||
* This function tries very hard to uniquely order all transactions.
|
||||
* If two transactions occur on the same date, then thier "num" fields
|
||||
* If two transactions occur on the same date, then their "num" fields
|
||||
* are compared. If the num fields are identical, then the description
|
||||
* fields are compared. If these are identical, then the memo fields
|
||||
* are compared. Hopefully, there will not be any transactions that
|
||||
@ -1484,32 +1561,32 @@ xaccTransMatch (Transaction **tap, Transaction **tbp)
|
||||
* have to be in identical order to match. So we have to cycle through them,
|
||||
* without creating bogus matches.
|
||||
*/
|
||||
na=0; while ((sa=ta->splits[na])) { sa->tickee = -1; na++; }
|
||||
nb=0; while ((sb=tb->splits[nb])) { sb->tickee = -1; nb++; }
|
||||
na=0; while ((sa=ta->splits[na])) { sa->ticket = -1; na++; }
|
||||
nb=0; while ((sb=tb->splits[nb])) { sb->ticket = -1; nb++; }
|
||||
|
||||
na=0;
|
||||
while ((sa=ta->splits[na])) {
|
||||
if (-1 < sa->tickee) {na++; continue;}
|
||||
if (-1 < sa->ticket) {na++; continue;}
|
||||
|
||||
nb=0;
|
||||
while ((sb=tb->splits[nb])) {
|
||||
if (-1 < sb->tickee) {nb++; continue;}
|
||||
if (-1 < sb->ticket) {nb++; continue;}
|
||||
retval = xaccSplitMatch (&sa, &sb);
|
||||
if ((0 == retval) && (sa->acc == sb->acc)) {
|
||||
sb->tickee = na;
|
||||
sa->tickee = nb;
|
||||
sb->ticket = na;
|
||||
sa->ticket = nb;
|
||||
break;
|
||||
}
|
||||
nb++;
|
||||
}
|
||||
|
||||
if (-1 == sa->tickee) return -1;
|
||||
if (-1 == sa->ticket) return -1;
|
||||
na++;
|
||||
}
|
||||
|
||||
nb=0;
|
||||
while ((sb=tb->splits[nb])) {
|
||||
if (-1 == sb->tickee) return +1;
|
||||
if (-1 == sb->ticket) return +1;
|
||||
nb++;
|
||||
}
|
||||
|
||||
@ -1550,13 +1627,12 @@ xaccTransSetDateSecs (Transaction *trans, time_t secs)
|
||||
trans->date_posted.tv_nsec = 0;
|
||||
|
||||
/* Because the date has changed, we need to make sure that each of the
|
||||
* splits is properly ordered in each of thier accounts. We could do that
|
||||
* splits is properly ordered in each of their accounts. We could do that
|
||||
* here, simply by reinserting each split into its account. However, in
|
||||
* some ways this is bad behaviour, and it seems much better/nicer to defer
|
||||
* that until the commit phase, i.e. until the user has called the
|
||||
* xaccTransCommitEdit() routine. So, for now, we are done.
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@ -1670,7 +1746,6 @@ xaccTransSetDateToday (Transaction *trans)
|
||||
|
||||
PINFO ("xaccTransSetDateToday(): addr=%p set date to %lu %s \n",
|
||||
trans, tv.tv_sec, ctime ((time_t *)&tv.tv_sec));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1989,7 +2064,8 @@ xaccGetAccountByName (Transaction *trans, const char * name)
|
||||
if (!trans) return NULL;
|
||||
if (!name) return NULL;
|
||||
|
||||
/* walk through the splits, looking for one, any one, that has a parent account */
|
||||
/* walk through the splits, looking for one, any one, that has a
|
||||
* parent account */
|
||||
i = 0;
|
||||
s = trans->splits[0];
|
||||
while (s) {
|
||||
@ -2019,7 +2095,8 @@ xaccGetAccountByFullName (Transaction *trans, const char * name,
|
||||
if (!trans) return NULL;
|
||||
if (!name) return NULL;
|
||||
|
||||
/* walk through the splits, looking for one, any one, that has a parent account */
|
||||
/* walk through the splits, looking for one, any one, that has a
|
||||
* parent account */
|
||||
i = 0;
|
||||
s = trans->splits[0];
|
||||
while (s) {
|
||||
|
@ -14,23 +14,25 @@
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
* Author: Rob Clark *
|
||||
* Internet: rclark@cs.hmc.edu *
|
||||
* Address: 609 8th Street *
|
||||
* Huntington Beach, CA 92648-4632 *
|
||||
\********************************************************************/
|
||||
|
||||
#ifndef __XACC_TRANSACTION_H__
|
||||
#define __XACC_TRANSACTION_H__
|
||||
|
||||
#include "config.h"
|
||||
#include "gnc-common.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "gnc-common.h"
|
||||
#include "GNCId.h"
|
||||
|
||||
|
||||
/* Values for the reconciled field in Transaction: */
|
||||
#define CREC 'c' /* The transaction has been cleared */
|
||||
#define YREC 'y' /* The transaction has been reconciled */
|
||||
@ -146,6 +148,17 @@ void xaccTransRollbackEdit (Transaction *);
|
||||
|
||||
gncBoolean xaccTransIsOpen (Transaction *trans);
|
||||
|
||||
/*
|
||||
* The xaccTransGetGUID() subroutine will return the
|
||||
* globally unique id associated with that transaction.
|
||||
*
|
||||
* The xaccTransLookup() subroutine will return the
|
||||
* transaction associated with the given id, or NULL
|
||||
* if there is no such transaction.
|
||||
*/
|
||||
GUID * xaccTransGetGUID (Transaction *trans);
|
||||
Transaction * xaccTransLookup (GUID *guid);
|
||||
|
||||
/* Convert a day, month, and year to a Timespec */
|
||||
Timespec gnc_dmy2timespec(int day, int month, int year);
|
||||
|
||||
@ -298,6 +311,17 @@ double xaccTransGetImbalance (Transaction * trans);
|
||||
Split * xaccMallocSplit (void);
|
||||
void xaccInitSplit (Split *); /* clears a split struct */
|
||||
|
||||
/*
|
||||
* The xaccSplitGetGUID() subroutine will return the
|
||||
* globally unique id associated with that split.
|
||||
*
|
||||
* The xaccSplitLookup() subroutine will return the
|
||||
* split associated with the given id, or NULL
|
||||
* if there is no such split.
|
||||
*/
|
||||
GUID * xaccSplitGetGUID (Split *split);
|
||||
Split * xaccSplitLookup (GUID *guid);
|
||||
|
||||
/* The memo is an arbitrary string associated with a split.
|
||||
* Users typically type in free form text from the GUI.
|
||||
*/
|
||||
@ -314,7 +338,7 @@ void xaccSplitSetAction (Split *, const char *);
|
||||
void xaccSplitSetDocref (Split *, const char *);
|
||||
|
||||
/* The Reconcile is a single byte, whose values are typically
|
||||
* are "no", "cleared" and "reconciled"
|
||||
* are "N", "C" and "R"
|
||||
*/
|
||||
void xaccSplitSetReconcile (Split *, char);
|
||||
void xaccSplitSetDateReconciledSecs (Split *, time_t);
|
||||
|
@ -14,13 +14,12 @@
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
* Author: Rob Clark *
|
||||
* Internet: rclark@cs.hmc.edu *
|
||||
* Address: 609 8th Street *
|
||||
* Huntington Beach, CA 92648-4632 *
|
||||
\********************************************************************/
|
||||
|
||||
/*
|
||||
@ -49,12 +48,14 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "Transaction.h" /* for typedefs */
|
||||
#include "GNCId.h"
|
||||
|
||||
|
||||
/** STRUCTS *********************************************************/
|
||||
/*
|
||||
* Double-entry is forced by having at least two splits in every
|
||||
* transaction. By convention, (and only by convention, not by
|
||||
* any inate requirement), the first split is considered to be
|
||||
* any innate requirement), the first split is considered to be
|
||||
* the source split or the crediting split, and the others are
|
||||
* the destination, or debiting splits. The grand total of all
|
||||
* of the splits must always be kept zero.
|
||||
@ -117,8 +118,10 @@ struct _split
|
||||
double share_reconciled_balance;
|
||||
|
||||
double cost_basis;
|
||||
/* no tickee no washee */
|
||||
int tickee;
|
||||
|
||||
GUID guid; /* globally unique id */
|
||||
|
||||
int ticket; /* used for matching up splits for QIFIO.c */
|
||||
};
|
||||
|
||||
|
||||
@ -129,7 +132,7 @@ struct _transaction
|
||||
|
||||
/* The num field is a arbitrary user-assigned field.
|
||||
* It is intended to store a short id number, typically the check number,
|
||||
* deposit number, invoice number or other tracking number
|
||||
* deposit number, invoice number or other tracking number.
|
||||
*/
|
||||
char * num;
|
||||
|
||||
@ -149,10 +152,10 @@ struct _transaction
|
||||
Split **splits; /* list of splits, null terminated */
|
||||
|
||||
/* marker is used to track the progress of transaction traversals.
|
||||
* 0 is never a legitimate marker value, so we can tell is we hit a
|
||||
* new transaction in the middle of a traversal. All each new
|
||||
* traversal cares about is whether or not the marker stored in a
|
||||
* transaction is the same as or different than the one
|
||||
* 0 is never a legitimate marker value, so we can tell is we hit
|
||||
* a new transaction in the middle of a traversal. All each new
|
||||
* traversal cares about is whether or not the marker stored in
|
||||
* a transaction is the same as or different than the one
|
||||
* corresponding to the current traversal. */
|
||||
unsigned char marker;
|
||||
|
||||
@ -160,6 +163,11 @@ struct _transaction
|
||||
* opened for editing. */
|
||||
char open;
|
||||
|
||||
/* guid is a globally unique identifier which can be used to
|
||||
* reference the transaction.
|
||||
*/
|
||||
GUID guid;
|
||||
|
||||
/* the orig pointer points at a copy of the original transaction,
|
||||
* before editing was started. This orig copy is used to rollback
|
||||
* any changes made if/when the edit is abandoned.
|
||||
@ -206,7 +214,7 @@ void xaccTransRemoveSplit (Transaction*, Split *);
|
||||
* (the share price of the source split is not changed).
|
||||
* If the indicated split is the source split, then the value
|
||||
* of the very first destination split is adjusted so that
|
||||
* the blanace is zero. If there is not destination split,
|
||||
* the balance is zero. If there is not destination split,
|
||||
* one of two outcomes are possible, depending on whether
|
||||
* "forced_double_entry" is enabled or disabled.
|
||||
* (1) if forced-double-entry is disabled, the fact that
|
||||
|
434
src/engine/guid/guid.c
Normal file
434
src/engine/guid/guid.c
Normal file
@ -0,0 +1,434 @@
|
||||
/********************************************************************\
|
||||
* guid.c -- globally unique ID implementation *
|
||||
* Copyright (C) 2000 Dave Peticolas <peticola@cs.ucdavis.edu> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/times.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "guid.h"
|
||||
#include "md5.h"
|
||||
|
||||
# ifndef P_tmpdir
|
||||
# define P_tmpdir "/tmp"
|
||||
# endif
|
||||
|
||||
|
||||
/** Constants *******************************************************/
|
||||
#define GUID_TRUE (0 == 0)
|
||||
#define GUID_FALSE (! GUID_TRUE)
|
||||
#define BLOCKSIZE 4096
|
||||
#define THRESHOLD (2 * BLOCKSIZE)
|
||||
|
||||
|
||||
/** Static global variables *****************************************/
|
||||
static int guid_initialized = GUID_FALSE;
|
||||
static struct md5_ctx guid_context;
|
||||
|
||||
|
||||
/** Function implementations ****************************************/
|
||||
|
||||
/* This code is based on code in md5.c in GNU textutils. */
|
||||
static size_t
|
||||
init_from_stream(FILE *stream, size_t max_size)
|
||||
{
|
||||
char buffer[BLOCKSIZE + 72];
|
||||
size_t sum, block_size, total;
|
||||
|
||||
if (max_size <= 0)
|
||||
return 0;
|
||||
|
||||
total = 0;
|
||||
|
||||
/* Iterate over file contents. */
|
||||
while (1)
|
||||
{
|
||||
/* We read the file in blocks of BLOCKSIZE bytes. One call of the
|
||||
* computation function processes the whole buffer so that with the
|
||||
* next round of the loop another block can be read. */
|
||||
size_t n;
|
||||
sum = 0;
|
||||
|
||||
if (max_size < BLOCKSIZE)
|
||||
block_size = max_size;
|
||||
else
|
||||
block_size = BLOCKSIZE;
|
||||
|
||||
/* Read block. Take care for partial reads. */
|
||||
do
|
||||
{
|
||||
n = fread (buffer + sum, 1, block_size - sum, stream);
|
||||
|
||||
sum += n;
|
||||
}
|
||||
while (sum < block_size && n != 0);
|
||||
|
||||
max_size -= sum;
|
||||
|
||||
if (n == 0 && ferror (stream))
|
||||
return total;
|
||||
|
||||
/* If end of file or max_size is reached, end the loop. */
|
||||
if ((n == 0) || (max_size == 0))
|
||||
break;
|
||||
|
||||
/* Process buffer with BLOCKSIZE bytes. Note that
|
||||
* BLOCKSIZE % 64 == 0 */
|
||||
md5_process_block (buffer, BLOCKSIZE, &guid_context);
|
||||
|
||||
total += sum;
|
||||
}
|
||||
|
||||
/* Add the last bytes if necessary. */
|
||||
if (sum > 0)
|
||||
{
|
||||
md5_process_bytes (buffer, sum, &guid_context);
|
||||
total += sum;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
static size_t
|
||||
init_from_file(const char *filename, size_t max_size)
|
||||
{
|
||||
struct stat stats;
|
||||
size_t total = 0;
|
||||
FILE *fp;
|
||||
|
||||
if (stat(filename, &stats) == 0)
|
||||
{
|
||||
md5_process_bytes(&stats, sizeof(stats), &guid_context);
|
||||
total += sizeof(stats);
|
||||
}
|
||||
|
||||
if (max_size <= 0)
|
||||
return total;
|
||||
|
||||
fp = fopen (filename, "r");
|
||||
if (fp == NULL)
|
||||
return total;
|
||||
|
||||
total += init_from_stream(fp, max_size);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
static size_t
|
||||
init_from_dir(const char *dirname, unsigned int max_files)
|
||||
{
|
||||
char filename[1024];
|
||||
struct dirent *de;
|
||||
struct stat stats;
|
||||
size_t total;
|
||||
int result;
|
||||
DIR *dir;
|
||||
|
||||
if (max_files <= 0)
|
||||
return 0;
|
||||
|
||||
dir = opendir (dirname);
|
||||
if (dir == NULL)
|
||||
return 0;
|
||||
|
||||
total = 0;
|
||||
|
||||
do
|
||||
{
|
||||
de = readdir(dir);
|
||||
if (de == NULL)
|
||||
break;
|
||||
|
||||
md5_process_bytes(de, sizeof(struct dirent), &guid_context);
|
||||
total += sizeof(struct dirent);
|
||||
|
||||
result = snprintf(filename, sizeof(filename),
|
||||
"%s/%s", dirname, de->d_name);
|
||||
if ((result < 0) || (result >= sizeof(filename)))
|
||||
continue;
|
||||
|
||||
if (stat(filename, &stats) != 0)
|
||||
continue;
|
||||
md5_process_bytes(&stats, sizeof(stats), &guid_context);
|
||||
total += sizeof(stats);
|
||||
|
||||
max_files--;
|
||||
} while (max_files > 0);
|
||||
|
||||
closedir(dir);
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
static size_t
|
||||
init_from_time()
|
||||
{
|
||||
size_t total;
|
||||
time_t t_time;
|
||||
clock_t clocks;
|
||||
struct tms tms_buf;
|
||||
|
||||
total = 0;
|
||||
|
||||
t_time = time(NULL);
|
||||
md5_process_bytes(&t_time, sizeof(t_time), &guid_context);
|
||||
total += sizeof(t_time);
|
||||
|
||||
clocks = times(&tms_buf);
|
||||
md5_process_bytes(&clocks, sizeof(clocks), &guid_context);
|
||||
md5_process_bytes(&tms_buf, sizeof(tms_buf), &guid_context);
|
||||
total += sizeof(clocks) + sizeof(tms_buf);
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
void
|
||||
guid_init()
|
||||
{
|
||||
size_t bytes = 0;
|
||||
|
||||
md5_init_ctx(&guid_context);
|
||||
|
||||
/* files */
|
||||
{
|
||||
const char * files[] =
|
||||
{ "/dev/urandom",
|
||||
"/etc/passwd",
|
||||
"/proc/loadavg",
|
||||
"/proc/meminfo",
|
||||
"/proc/net/dev",
|
||||
"/proc/rtc",
|
||||
"/proc/self/environ",
|
||||
"/proc/self/stat",
|
||||
"/proc/stat",
|
||||
"/proc/uptime",
|
||||
"/dev/urandom", /* once more for good measure :) */
|
||||
NULL
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; files[i] != NULL; i++)
|
||||
bytes += init_from_file(files[i], BLOCKSIZE);
|
||||
}
|
||||
|
||||
/* directories */
|
||||
{
|
||||
const char * dirname;
|
||||
const char * dirs[] =
|
||||
{
|
||||
"/proc",
|
||||
P_tmpdir,
|
||||
"/var/lock",
|
||||
"/var/log",
|
||||
"/var/mail",
|
||||
"/var/spool/mail",
|
||||
"/var/run",
|
||||
NULL
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; dirs[i] != NULL; i++)
|
||||
bytes += init_from_dir(dirs[i], 32);
|
||||
|
||||
dirname = getenv("HOME");
|
||||
if (dirname != NULL)
|
||||
bytes += init_from_dir(dirname, 32);
|
||||
}
|
||||
|
||||
/* process and parent ids */
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
pid = getpid();
|
||||
md5_process_bytes(&pid, sizeof(pid), &guid_context);
|
||||
bytes += sizeof(pid);
|
||||
|
||||
pid = getppid();
|
||||
md5_process_bytes(&pid, sizeof(pid), &guid_context);
|
||||
bytes += sizeof(pid);
|
||||
}
|
||||
|
||||
/* user info */
|
||||
{
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
char *s;
|
||||
|
||||
s = getlogin();
|
||||
md5_process_bytes(s, strlen(s), &guid_context);
|
||||
bytes += strlen(s);
|
||||
|
||||
uid = getuid();
|
||||
md5_process_bytes(&uid, sizeof(uid), &guid_context);
|
||||
bytes += sizeof(uid);
|
||||
|
||||
gid = getgid();
|
||||
md5_process_bytes(&gid, sizeof(gid), &guid_context);
|
||||
bytes += sizeof(gid);
|
||||
}
|
||||
|
||||
/* plain old random */
|
||||
{
|
||||
int n, i;
|
||||
|
||||
srand((unsigned int) time(NULL));
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
n = rand();
|
||||
|
||||
md5_process_bytes(&n, sizeof(n), &guid_context);
|
||||
bytes += sizeof(n);
|
||||
}
|
||||
}
|
||||
|
||||
/* time in secs and clock ticks */
|
||||
bytes += init_from_time();
|
||||
|
||||
fprintf(stderr, "guid_init got %u bytes.\n", bytes);
|
||||
if (bytes < THRESHOLD)
|
||||
fprintf(stderr,
|
||||
"WARNING: guid_init only got %u bytes.\n"
|
||||
"The identifiers might not be very random.\n", bytes);
|
||||
|
||||
guid_initialized = GUID_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
guid_init_with_salt(const void *salt, size_t salt_len)
|
||||
{
|
||||
guid_init();
|
||||
|
||||
md5_process_bytes(salt, salt_len, &guid_context);
|
||||
}
|
||||
|
||||
void
|
||||
guid_init_only_salt(const void *salt, size_t salt_len)
|
||||
{
|
||||
md5_init_ctx(&guid_context);
|
||||
|
||||
md5_process_bytes(salt, salt_len, &guid_context);
|
||||
|
||||
guid_initialized = GUID_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
guid_new(GUID *guid)
|
||||
{
|
||||
struct md5_ctx ctx;
|
||||
|
||||
if (guid == NULL)
|
||||
return;
|
||||
|
||||
if (!guid_initialized)
|
||||
guid_init();
|
||||
|
||||
/* make the id */
|
||||
ctx = guid_context;
|
||||
md5_finish_ctx(&ctx, guid->data);
|
||||
|
||||
/* update the global context */
|
||||
init_from_time();
|
||||
}
|
||||
|
||||
/* needs 32 bytes exactly, doesn't print a null char */
|
||||
static void
|
||||
encode_md5_data(const unsigned char *data, char *buffer)
|
||||
{
|
||||
size_t count;
|
||||
|
||||
for (count = 0; count < 16; count++, buffer += 2)
|
||||
sprintf(buffer, "%02x", data[count]);
|
||||
}
|
||||
|
||||
/* returns true if the first 32 bytes of buffer encode
|
||||
* a hex number. returns false otherwise. Decoded number
|
||||
* is packed into data in little endian order. */
|
||||
static int
|
||||
decode_md5_string(const char *string, unsigned char *data)
|
||||
{
|
||||
unsigned char n1, n2;
|
||||
size_t count;
|
||||
char c1, c2;
|
||||
|
||||
if (string == NULL)
|
||||
return GUID_FALSE;
|
||||
|
||||
for (count = 0; count < 16; count++)
|
||||
{
|
||||
c1 = tolower(string[2 * count]);
|
||||
if (!isxdigit(c1))
|
||||
return GUID_FALSE;
|
||||
|
||||
c2 = tolower(string[2 * count + 1]);
|
||||
if (!isxdigit(c2))
|
||||
return GUID_FALSE;
|
||||
|
||||
if (isdigit(c1))
|
||||
n1 = c1 - '0';
|
||||
else
|
||||
n1 = c1 - 'a' + 10;
|
||||
|
||||
if (isdigit(c2))
|
||||
n2 = c2 - '0';
|
||||
else
|
||||
n2 = c2 - 'a' + 10;
|
||||
|
||||
if (data != NULL)
|
||||
data[count] = (n1 << 4) | n2;
|
||||
}
|
||||
|
||||
return GUID_TRUE;
|
||||
}
|
||||
|
||||
const char *
|
||||
guid_to_string(const GUID * guid)
|
||||
{
|
||||
static char string[33];
|
||||
|
||||
encode_md5_data(guid->data, string);
|
||||
|
||||
string[32] = '\0';
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
int
|
||||
string_to_guid(const char * string, GUID * guid)
|
||||
{
|
||||
return decode_md5_string(string, (guid != NULL) ? guid->data : NULL);
|
||||
}
|
82
src/engine/guid/guid.h
Normal file
82
src/engine/guid/guid.h
Normal file
@ -0,0 +1,82 @@
|
||||
/********************************************************************\
|
||||
* guid.h -- globally unique ID User API *
|
||||
* Copyright (C) 2000 Dave Peticolas <peticola@cs.ucdavis.edu> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
#ifndef __GUID__
|
||||
#define __GUID__ 1
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
/* This file defines an API for using globally unique identifiers. */
|
||||
|
||||
/* The type used to store guids */
|
||||
typedef struct _GUID
|
||||
{
|
||||
unsigned char data[16];
|
||||
} GUID;
|
||||
|
||||
|
||||
/* Three functions to initialize the id generator. Only one needs to
|
||||
* be called. Calling any initialization function a second time will
|
||||
* reset the generator and erase the effect of the first call.
|
||||
*
|
||||
* guid_init() will initialize the generator with a variety of random
|
||||
* sources.
|
||||
*
|
||||
* guid_init_with_salt() will initialize the generator with guid_init()
|
||||
* and with the data given in the salt argument. This argument can be
|
||||
* used to add additional randomness to the generated ids.
|
||||
*
|
||||
* guid_init_only_salt() will initialize the generator with the data
|
||||
* given in the salt argument, but not with any other source. Calling
|
||||
* guid_init_only_salt() with a specific argument will produce a
|
||||
* specific sequence of ids reliably. */
|
||||
void guid_init();
|
||||
void guid_init_with_salt(const void *salt, size_t salt_len);
|
||||
void guid_init_only_salt(const void *salt, size_t salt_len);
|
||||
|
||||
|
||||
/* Generate a new id. If no initialization function has been called,
|
||||
* guid_init() will be called before the id is created. */
|
||||
void guid_new(GUID *guid);
|
||||
|
||||
|
||||
/* Return a null-terminated string encoding of the id. String
|
||||
* encodings of identifiers are hex numbers printed only with the
|
||||
* characters '0' through '9' and 'a' through 'f'. The encoding will
|
||||
* always be 32 characters long. The returned string should not be
|
||||
* modified. A subsequent call to guid_to_string() will overwrite
|
||||
* the result of a previous call. */
|
||||
const char * guid_to_string(const GUID * guid);
|
||||
|
||||
|
||||
/* Given a string, decode the id into the guid if guid is non-NULL.
|
||||
* The function returns true if the string was a valid 32 character
|
||||
* hexadecimal number. This function accepts both upper and lower case
|
||||
* hex digits. If the return value if false, the effect on guid is
|
||||
* undefined. */
|
||||
int string_to_guid(const char * string, GUID * guid);
|
||||
|
||||
|
||||
#endif
|
419
src/engine/guid/md5.c
Normal file
419
src/engine/guid/md5.c
Normal file
@ -0,0 +1,419 @@
|
||||
/* md5.c - Functions to compute MD5 message digest of files or memory blocks
|
||||
according to the definition of MD5 in RFC 1321 from April 1992.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
NOTE: The canonical source of this file is maintained with the GNU C
|
||||
Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#if STDC_HEADERS || defined _LIBC
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
#else
|
||||
# ifndef HAVE_MEMCPY
|
||||
# define memcpy(d, s, n) bcopy ((s), (d), (n))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
#ifdef _LIBC
|
||||
# include <endian.h>
|
||||
# if __BYTE_ORDER == __BIG_ENDIAN
|
||||
# define WORDS_BIGENDIAN 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
# define SWAP(n) \
|
||||
(((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
|
||||
#else
|
||||
# define SWAP(n) (n)
|
||||
#endif
|
||||
|
||||
|
||||
/* This array contains the bytes used to pad the buffer to the next
|
||||
64-byte boundary. (RFC 1321, 3.1: Step 1) */
|
||||
static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
|
||||
|
||||
|
||||
/* Initialize structure containing state of computation.
|
||||
(RFC 1321, 3.3: Step 3) */
|
||||
void
|
||||
md5_init_ctx (ctx)
|
||||
struct md5_ctx *ctx;
|
||||
{
|
||||
ctx->A = 0x67452301;
|
||||
ctx->B = 0xefcdab89;
|
||||
ctx->C = 0x98badcfe;
|
||||
ctx->D = 0x10325476;
|
||||
|
||||
ctx->total[0] = ctx->total[1] = 0;
|
||||
ctx->buflen = 0;
|
||||
}
|
||||
|
||||
/* Put result from CTX in first 16 bytes following RESBUF. The result
|
||||
must be in little endian byte order.
|
||||
|
||||
IMPORTANT: On some systems it is required that RESBUF is correctly
|
||||
aligned for a 32 bits value. */
|
||||
void *
|
||||
md5_read_ctx (ctx, resbuf)
|
||||
const struct md5_ctx *ctx;
|
||||
void *resbuf;
|
||||
{
|
||||
((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
|
||||
((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
|
||||
((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
|
||||
((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
|
||||
|
||||
return resbuf;
|
||||
}
|
||||
|
||||
/* Process the remaining bytes in the internal buffer and the usual
|
||||
prolog according to the standard and write the result to RESBUF.
|
||||
|
||||
IMPORTANT: On some systems it is required that RESBUF is correctly
|
||||
aligned for a 32 bits value. */
|
||||
void *
|
||||
md5_finish_ctx (ctx, resbuf)
|
||||
struct md5_ctx *ctx;
|
||||
void *resbuf;
|
||||
{
|
||||
/* Take yet unprocessed bytes into account. */
|
||||
md5_uint32 bytes = ctx->buflen;
|
||||
size_t pad;
|
||||
|
||||
/* Now count remaining bytes. */
|
||||
ctx->total[0] += bytes;
|
||||
if (ctx->total[0] < bytes)
|
||||
++ctx->total[1];
|
||||
|
||||
pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
|
||||
memcpy (&ctx->buffer[bytes], fillbuf, pad);
|
||||
|
||||
/* Put the 64-bit file length in *bits* at the end of the buffer. */
|
||||
*(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
|
||||
*(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |
|
||||
(ctx->total[0] >> 29));
|
||||
|
||||
/* Process last bytes. */
|
||||
md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
|
||||
|
||||
return md5_read_ctx (ctx, resbuf);
|
||||
}
|
||||
|
||||
/* Compute MD5 message digest for bytes read from STREAM. The
|
||||
resulting message digest number will be written into the 16 bytes
|
||||
beginning at RESBLOCK. */
|
||||
int
|
||||
md5_stream (stream, resblock)
|
||||
FILE *stream;
|
||||
void *resblock;
|
||||
{
|
||||
/* Important: BLOCKSIZE must be a multiple of 64. */
|
||||
#define BLOCKSIZE 4096
|
||||
struct md5_ctx ctx;
|
||||
char buffer[BLOCKSIZE + 72];
|
||||
size_t sum;
|
||||
|
||||
/* Initialize the computation context. */
|
||||
md5_init_ctx (&ctx);
|
||||
|
||||
/* Iterate over full file contents. */
|
||||
while (1)
|
||||
{
|
||||
/* We read the file in blocks of BLOCKSIZE bytes. One call of the
|
||||
computation function processes the whole buffer so that with the
|
||||
next round of the loop another block can be read. */
|
||||
size_t n;
|
||||
sum = 0;
|
||||
|
||||
/* Read block. Take care for partial reads. */
|
||||
do
|
||||
{
|
||||
n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
|
||||
|
||||
sum += n;
|
||||
}
|
||||
while (sum < BLOCKSIZE && n != 0);
|
||||
if (n == 0 && ferror (stream))
|
||||
return 1;
|
||||
|
||||
/* If end of file is reached, end the loop. */
|
||||
if (n == 0)
|
||||
break;
|
||||
|
||||
/* Process buffer with BLOCKSIZE bytes. Note that
|
||||
BLOCKSIZE % 64 == 0
|
||||
*/
|
||||
md5_process_block (buffer, BLOCKSIZE, &ctx);
|
||||
}
|
||||
|
||||
/* Add the last bytes if necessary. */
|
||||
if (sum > 0)
|
||||
md5_process_bytes (buffer, sum, &ctx);
|
||||
|
||||
/* Construct result in desired memory. */
|
||||
md5_finish_ctx (&ctx, resblock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
|
||||
result is always in little endian byte order, so that a byte-wise
|
||||
output yields to the wanted ASCII representation of the message
|
||||
digest. */
|
||||
void *
|
||||
md5_buffer (buffer, len, resblock)
|
||||
const char *buffer;
|
||||
size_t len;
|
||||
void *resblock;
|
||||
{
|
||||
struct md5_ctx ctx;
|
||||
|
||||
/* Initialize the computation context. */
|
||||
md5_init_ctx (&ctx);
|
||||
|
||||
/* Process whole buffer but last len % 64 bytes. */
|
||||
md5_process_bytes (buffer, len, &ctx);
|
||||
|
||||
/* Put result in desired memory area. */
|
||||
return md5_finish_ctx (&ctx, resblock);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
md5_process_bytes (buffer, len, ctx)
|
||||
const void *buffer;
|
||||
size_t len;
|
||||
struct md5_ctx *ctx;
|
||||
{
|
||||
/* When we already have some bits in our internal buffer concatenate
|
||||
both inputs first. */
|
||||
if (ctx->buflen != 0)
|
||||
{
|
||||
size_t left_over = ctx->buflen;
|
||||
size_t add = 128 - left_over > len ? len : 128 - left_over;
|
||||
|
||||
memcpy (&ctx->buffer[left_over], buffer, add);
|
||||
ctx->buflen += add;
|
||||
|
||||
if (left_over + add > 64)
|
||||
{
|
||||
md5_process_block (ctx->buffer, (left_over + add) & ~63, ctx);
|
||||
/* The regions in the following copy operation cannot overlap. */
|
||||
memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
|
||||
(left_over + add) & 63);
|
||||
ctx->buflen = (left_over + add) & 63;
|
||||
}
|
||||
|
||||
buffer = (const char *) buffer + add;
|
||||
len -= add;
|
||||
}
|
||||
|
||||
/* Process available complete blocks. */
|
||||
if (len > 64)
|
||||
{
|
||||
md5_process_block (buffer, len & ~63, ctx);
|
||||
buffer = (const char *) buffer + (len & ~63);
|
||||
len &= 63;
|
||||
}
|
||||
|
||||
/* Move remaining bytes in internal buffer. */
|
||||
if (len > 0)
|
||||
{
|
||||
memcpy (ctx->buffer, buffer, len);
|
||||
ctx->buflen = len;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* These are the four functions used in the four steps of the MD5 algorithm
|
||||
and defined in the RFC 1321. The first function is a little bit optimized
|
||||
(as found in Colin Plumbs public domain implementation). */
|
||||
/* #define FF(b, c, d) ((b & c) | (~b & d)) */
|
||||
#define FF(b, c, d) (d ^ (b & (c ^ d)))
|
||||
#define FG(b, c, d) FF (d, b, c)
|
||||
#define FH(b, c, d) (b ^ c ^ d)
|
||||
#define FI(b, c, d) (c ^ (b | ~d))
|
||||
|
||||
/* Process LEN bytes of BUFFER, accumulating context into CTX.
|
||||
It is assumed that LEN % 64 == 0. */
|
||||
|
||||
void
|
||||
md5_process_block (buffer, len, ctx)
|
||||
const void *buffer;
|
||||
size_t len;
|
||||
struct md5_ctx *ctx;
|
||||
{
|
||||
md5_uint32 correct_words[16];
|
||||
const md5_uint32 *words = buffer;
|
||||
size_t nwords = len / sizeof (md5_uint32);
|
||||
const md5_uint32 *endp = words + nwords;
|
||||
md5_uint32 A = ctx->A;
|
||||
md5_uint32 B = ctx->B;
|
||||
md5_uint32 C = ctx->C;
|
||||
md5_uint32 D = ctx->D;
|
||||
|
||||
/* First increment the byte count. RFC 1321 specifies the possible
|
||||
length of the file up to 2^64 bits. Here we only compute the
|
||||
number of bytes. Do a double word increment. */
|
||||
ctx->total[0] += len;
|
||||
if (ctx->total[0] < len)
|
||||
++ctx->total[1];
|
||||
|
||||
/* Process all bytes in the buffer with 64 bytes in each round of
|
||||
the loop. */
|
||||
while (words < endp)
|
||||
{
|
||||
md5_uint32 *cwp = correct_words;
|
||||
md5_uint32 A_save = A;
|
||||
md5_uint32 B_save = B;
|
||||
md5_uint32 C_save = C;
|
||||
md5_uint32 D_save = D;
|
||||
|
||||
/* First round: using the given function, the context and a constant
|
||||
the next context is computed. Because the algorithms processing
|
||||
unit is a 32-bit word and it is determined to work on words in
|
||||
little endian byte order we perhaps have to change the byte order
|
||||
before the computation. To reduce the work for the next steps
|
||||
we store the swapped words in the array CORRECT_WORDS. */
|
||||
|
||||
#define OP(a, b, c, d, s, T) \
|
||||
do \
|
||||
{ \
|
||||
a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \
|
||||
++words; \
|
||||
CYCLIC (a, s); \
|
||||
a += b; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* It is unfortunate that C does not provide an operator for
|
||||
cyclic rotation. Hope the C compiler is smart enough. */
|
||||
#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
|
||||
|
||||
/* Before we start, one word to the strange constants.
|
||||
They are defined in RFC 1321 as
|
||||
|
||||
T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
|
||||
*/
|
||||
|
||||
/* Round 1. */
|
||||
OP (A, B, C, D, 7, 0xd76aa478);
|
||||
OP (D, A, B, C, 12, 0xe8c7b756);
|
||||
OP (C, D, A, B, 17, 0x242070db);
|
||||
OP (B, C, D, A, 22, 0xc1bdceee);
|
||||
OP (A, B, C, D, 7, 0xf57c0faf);
|
||||
OP (D, A, B, C, 12, 0x4787c62a);
|
||||
OP (C, D, A, B, 17, 0xa8304613);
|
||||
OP (B, C, D, A, 22, 0xfd469501);
|
||||
OP (A, B, C, D, 7, 0x698098d8);
|
||||
OP (D, A, B, C, 12, 0x8b44f7af);
|
||||
OP (C, D, A, B, 17, 0xffff5bb1);
|
||||
OP (B, C, D, A, 22, 0x895cd7be);
|
||||
OP (A, B, C, D, 7, 0x6b901122);
|
||||
OP (D, A, B, C, 12, 0xfd987193);
|
||||
OP (C, D, A, B, 17, 0xa679438e);
|
||||
OP (B, C, D, A, 22, 0x49b40821);
|
||||
|
||||
/* For the second to fourth round we have the possibly swapped words
|
||||
in CORRECT_WORDS. Redefine the macro to take an additional first
|
||||
argument specifying the function to use. */
|
||||
#undef OP
|
||||
#define OP(f, a, b, c, d, k, s, T) \
|
||||
do \
|
||||
{ \
|
||||
a += f (b, c, d) + correct_words[k] + T; \
|
||||
CYCLIC (a, s); \
|
||||
a += b; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Round 2. */
|
||||
OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
|
||||
OP (FG, D, A, B, C, 6, 9, 0xc040b340);
|
||||
OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
|
||||
OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
|
||||
OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
|
||||
OP (FG, D, A, B, C, 10, 9, 0x02441453);
|
||||
OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
|
||||
OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
|
||||
OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
|
||||
OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
|
||||
OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
|
||||
OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
|
||||
OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
|
||||
OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
|
||||
OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
|
||||
OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
|
||||
|
||||
/* Round 3. */
|
||||
OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
|
||||
OP (FH, D, A, B, C, 8, 11, 0x8771f681);
|
||||
OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
|
||||
OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
|
||||
OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
|
||||
OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
|
||||
OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
|
||||
OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
|
||||
OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
|
||||
OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
|
||||
OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
|
||||
OP (FH, B, C, D, A, 6, 23, 0x04881d05);
|
||||
OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
|
||||
OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
|
||||
OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
|
||||
OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
|
||||
|
||||
/* Round 4. */
|
||||
OP (FI, A, B, C, D, 0, 6, 0xf4292244);
|
||||
OP (FI, D, A, B, C, 7, 10, 0x432aff97);
|
||||
OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
|
||||
OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
|
||||
OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
|
||||
OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
|
||||
OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
|
||||
OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
|
||||
OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
|
||||
OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
|
||||
OP (FI, C, D, A, B, 6, 15, 0xa3014314);
|
||||
OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
|
||||
OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
|
||||
OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
|
||||
OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
|
||||
OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
|
||||
|
||||
/* Add the starting values of the context. */
|
||||
A += A_save;
|
||||
B += B_save;
|
||||
C += C_save;
|
||||
D += D_save;
|
||||
}
|
||||
|
||||
/* Put checksum in context given as argument. */
|
||||
ctx->A = A;
|
||||
ctx->B = B;
|
||||
ctx->C = C;
|
||||
ctx->D = D;
|
||||
}
|
146
src/engine/guid/md5.h
Normal file
146
src/engine/guid/md5.h
Normal file
@ -0,0 +1,146 @@
|
||||
/* md5.h - Declaration of functions and data types used for MD5 sum
|
||||
computing library functions.
|
||||
Copyright (C) 1995, 1996, 1999 Free Software Foundation, Inc.
|
||||
NOTE: The canonical source of this file is maintained with the GNU C
|
||||
Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _MD5_H
|
||||
#define _MD5_H 1
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined HAVE_LIMITS_H || _LIBC
|
||||
# include <limits.h>
|
||||
#endif
|
||||
|
||||
/* The following contortions are an attempt to use the C preprocessor
|
||||
to determine an unsigned integral type that is 32 bits wide. An
|
||||
alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
|
||||
doing that would require that the configure script compile and *run*
|
||||
the resulting executable. Locally running cross-compiled executables
|
||||
is usually not possible. */
|
||||
|
||||
#ifdef _LIBC
|
||||
# include <sys/types.h>
|
||||
typedef u_int32_t md5_uint32;
|
||||
#else
|
||||
# if defined __STDC__ && __STDC__
|
||||
# define UINT_MAX_32_BITS 4294967295U
|
||||
# else
|
||||
# define UINT_MAX_32_BITS 0xFFFFFFFF
|
||||
# endif
|
||||
|
||||
/* If UINT_MAX isn't defined, assume it's a 32-bit type.
|
||||
This should be valid for all systems GNU cares about because
|
||||
that doesn't include 16-bit systems, and only modern systems
|
||||
(that certainly have <limits.h>) have 64+-bit integral types. */
|
||||
|
||||
# ifndef UINT_MAX
|
||||
# define UINT_MAX UINT_MAX_32_BITS
|
||||
# endif
|
||||
|
||||
# if UINT_MAX == UINT_MAX_32_BITS
|
||||
typedef unsigned int md5_uint32;
|
||||
# else
|
||||
# if USHRT_MAX == UINT_MAX_32_BITS
|
||||
typedef unsigned short md5_uint32;
|
||||
# else
|
||||
# if ULONG_MAX == UINT_MAX_32_BITS
|
||||
typedef unsigned long md5_uint32;
|
||||
# else
|
||||
/* The following line is intended to evoke an error.
|
||||
Using #error is not portable enough. */
|
||||
"Cannot determine unsigned 32-bit data type."
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#undef __P
|
||||
#if defined (__STDC__) && __STDC__
|
||||
#define __P(x) x
|
||||
#else
|
||||
#define __P(x) ()
|
||||
#endif
|
||||
|
||||
/* Structure to save state of computation between the single steps. */
|
||||
struct md5_ctx
|
||||
{
|
||||
md5_uint32 A;
|
||||
md5_uint32 B;
|
||||
md5_uint32 C;
|
||||
md5_uint32 D;
|
||||
|
||||
md5_uint32 total[2];
|
||||
md5_uint32 buflen;
|
||||
char buffer[128];
|
||||
};
|
||||
|
||||
/*
|
||||
* The following three functions are build up the low level used in
|
||||
* the functions `md5_stream' and `md5_buffer'.
|
||||
*/
|
||||
|
||||
/* Initialize structure containing state of computation.
|
||||
(RFC 1321, 3.3: Step 3) */
|
||||
extern void md5_init_ctx __P ((struct md5_ctx *ctx));
|
||||
|
||||
/* Starting with the result of former calls of this function (or the
|
||||
initialization function update the context for the next LEN bytes
|
||||
starting at BUFFER.
|
||||
It is necessary that LEN is a multiple of 64!!! */
|
||||
extern void md5_process_block __P ((const void *buffer, size_t len,
|
||||
struct md5_ctx *ctx));
|
||||
|
||||
/* Starting with the result of former calls of this function (or the
|
||||
initialization function update the context for the next LEN bytes
|
||||
starting at BUFFER.
|
||||
It is NOT required that LEN is a multiple of 64. */
|
||||
extern void md5_process_bytes __P ((const void *buffer, size_t len,
|
||||
struct md5_ctx *ctx));
|
||||
|
||||
/* Process the remaining bytes in the buffer and put result from CTX
|
||||
in first 16 bytes following RESBUF. The result is always in little
|
||||
endian byte order, so that a byte-wise output yields to the wanted
|
||||
ASCII representation of the message digest.
|
||||
|
||||
IMPORTANT: On some systems it is required that RESBUF be correctly
|
||||
aligned for a 32 bits value. */
|
||||
extern void *md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf));
|
||||
|
||||
|
||||
/* Put result from CTX in first 16 bytes following RESBUF. The result is
|
||||
always in little endian byte order, so that a byte-wise output yields
|
||||
to the wanted ASCII representation of the message digest.
|
||||
|
||||
IMPORTANT: On some systems it is required that RESBUF is correctly
|
||||
aligned for a 32 bits value. */
|
||||
extern void *md5_read_ctx __P ((const struct md5_ctx *ctx, void *resbuf));
|
||||
|
||||
|
||||
/* Compute MD5 message digest for bytes read from STREAM. The
|
||||
resulting message digest number will be written into the 16 bytes
|
||||
beginning at RESBLOCK. */
|
||||
extern int md5_stream __P ((FILE *stream, void *resblock));
|
||||
|
||||
/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
|
||||
result is always in little endian byte order, so that a byte-wise
|
||||
output yields to the wanted ASCII representation of the message
|
||||
digest. */
|
||||
extern void *md5_buffer __P ((const char *buffer, size_t len, void *resblock));
|
||||
|
||||
#endif
|
@ -14,13 +14,11 @@
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Author: Robin Clark
|
||||
# Internet: rclark@rush.aero.org
|
||||
# Address: 609 8th Street
|
||||
# Huntington Beach, CA 92648-4632
|
||||
# along with this program; if not, contact:
|
||||
#
|
||||
# Free Software Foundation Voice: +1-617-542-5942
|
||||
# 59 Temple Place - Suite 330 Fax: +1-617-542-2652
|
||||
# Boston, MA 02111-1307, USA gnu@gnu.org
|
||||
|
||||
include @top_srcdir@/Makefile.init
|
||||
|
||||
@ -28,6 +26,7 @@ INCLPATH := -I.. \
|
||||
-I../.. \
|
||||
-I../guile \
|
||||
-I../engine \
|
||||
-I../engine/guid \
|
||||
-I../register \
|
||||
-I../reports \
|
||||
-I@srcdir@/../../include \
|
||||
@ -53,6 +52,7 @@ endif
|
||||
# text to work on...
|
||||
OTHER_OBJS += $(wildcard @top_srcdir@/src/obj/gnome/*.o)
|
||||
OTHER_OBJS += $(wildcard @top_srcdir@/src/engine/obj/*.o)
|
||||
OTHER_OBJS += $(wildcard @top_srcdir@/src/engine/obj/guid/*.o)
|
||||
OTHER_OBJS += $(wildcard @top_srcdir@/src/register/obj/gnome/*.o)
|
||||
OTHER_OBJS += $(wildcard @top_srcdir@/src/reports/obj/*.o)
|
||||
OTHER_OBJS += $(wildcard @top_srcdir@/src/guile/obj/*.o)
|
||||
|
@ -14,13 +14,12 @@
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
* Author: Rob Clark *
|
||||
* Internet: rclark@cs.hmc.edu *
|
||||
* Address: 609 8th Street *
|
||||
* Huntington Beach, CA 92648-4632 *
|
||||
\********************************************************************/
|
||||
|
||||
#include "top-level.h"
|
||||
@ -142,7 +141,7 @@ gnc_ui_AdjBWindow_ok_cb(GtkWidget * widget, gpointer data)
|
||||
|
||||
xaccAccountCommitEdit(adjBData->account);
|
||||
xaccTransCommitEdit(trans);
|
||||
|
||||
|
||||
gnc_account_ui_refresh(adjBData->account);
|
||||
gnc_refresh_main_window();
|
||||
|
||||
|
@ -27,6 +27,7 @@ INCLPATH = -I@top_srcdir@/ \
|
||||
-I@top_srcdir@/src \
|
||||
-I@top_srcdir@/include \
|
||||
-I@top_srcdir@/src/engine \
|
||||
-I@top_srcdir@/src/engine/guid \
|
||||
-I@top_srcdir@/lib/ComboBox-1.33 \
|
||||
-I@top_srcdir@/lib/Xbae-4.6.2-linas \
|
||||
-I@prefix@/include \
|
||||
|
@ -13,13 +13,11 @@
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Author: Robin Clark
|
||||
# Internet: rclark@rush.aero.org
|
||||
# Address: 609 8th Street
|
||||
# Huntington Beach, CA 92648-4632
|
||||
# along with this program; if not, contact:
|
||||
#
|
||||
# Free Software Foundation Voice: +1-617-542-5942
|
||||
# 59 Temple Place - Suite 330 Fax: +1-617-542-2652
|
||||
# Boston, MA 02111-1307, USA gnu@gnu.org
|
||||
|
||||
include @top_srcdir@/Makefile.init
|
||||
|
||||
@ -27,6 +25,7 @@ INCLPATH = -I@top_srcdir@/ \
|
||||
-I@top_srcdir@/src \
|
||||
-I@top_srcdir@/include \
|
||||
-I@top_srcdir@/src/engine \
|
||||
-I@top_srcdir@/src/engine/guid \
|
||||
-I@top_srcdir@/src/gnome \
|
||||
-I@prefix@/include \
|
||||
-I@top_srcdir@/src/register
|
||||
|
@ -47,7 +47,3 @@ perl5: ${OBJS} ../engine/libengine.a
|
||||
@cd perl5 && $(MAKE) default
|
||||
|
||||
.PHONY: motif
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 2
|
||||
# End:
|
||||
|
@ -27,6 +27,7 @@ INCLPATH = \
|
||||
-I@top_srcdir@/src \
|
||||
-I@top_srcdir@/src/swig\
|
||||
-I@top_srcdir@/src/engine \
|
||||
-I@top_srcdir@/src/engine/guid \
|
||||
-I@top_srcdir@/include \
|
||||
-I@PERLINCL@/CORE \
|
||||
-I$(prefix)/include
|
||||
@ -102,7 +103,3 @@ TRASH += gnucash.pm gnucash.so
|
||||
# ${SWIG} ${SWIG_FLAGS} -o $@ $<
|
||||
# ${PERL} -pi -e 's/^void gnucash\(\)/void gnucash_swig_init\(\)/' $@
|
||||
# TRASH += gnucash-all-guile_wrap.c
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 2
|
||||
# End:
|
||||
|
Loading…
Reference in New Issue
Block a user