mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Re-indentation of source code, next batch.
This also strips trailing whitespaces from lines where they existed. This re-indentation was done using astyle-1.24 using the following options: astyle --indent=spaces=4 --brackets=break --pad-oper --pad-header Discussed at http://lists.gnucash.org/pipermail/gnucash-devel/2009-August/026121.html git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@18675 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
@@ -73,7 +73,7 @@ GNCDruidProvider* gnc_druid_provider_new(GNCDruid* druid,
|
||||
|
||||
typedef GNCDruidProvider* (*GNCDruidProviderNew)(GNCDruid*, GNCDruidProviderDesc*);
|
||||
void gnc_druid_provider_register(const gchar* ui_type, const gchar* name,
|
||||
GNCDruidProviderNew new_provider);
|
||||
GNCDruidProviderNew new_provider);
|
||||
|
||||
/* methods */
|
||||
|
||||
|
||||
@@ -206,7 +206,7 @@ gnc_get_current_book (void)
|
||||
void
|
||||
gnc_set_current_book_tax_name (const gchar *tax_name)
|
||||
{
|
||||
qof_book_set_string_option(gnc_get_current_book(), OPTION_TAXUS_NAME, tax_name);
|
||||
qof_book_set_string_option(gnc_get_current_book(), OPTION_TAXUS_NAME, tax_name);
|
||||
}
|
||||
|
||||
const gchar *
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,46 +20,50 @@ int gnc_module_current = 0;
|
||||
int gnc_module_revision = 0;
|
||||
int gnc_module_age = 0;
|
||||
|
||||
/*@ dependent @*//*@ null @*/ static GNCModule engine;
|
||||
/*@ dependent @*//*@ null @*/
|
||||
static GNCModule engine;
|
||||
|
||||
gchar *
|
||||
gnc_module_path(void)
|
||||
{
|
||||
return g_strdup( "gnucash/backend/dbi" );
|
||||
return g_strdup( "gnucash/backend/dbi" );
|
||||
}
|
||||
|
||||
gchar *
|
||||
gnc_module_description(void)
|
||||
{
|
||||
return g_strdup( "The DBI/SQL backend for GnuCash" );
|
||||
return g_strdup( "The DBI/SQL backend for GnuCash" );
|
||||
}
|
||||
|
||||
int
|
||||
gnc_module_init(int refcount)
|
||||
{
|
||||
engine = gnc_module_load( "gnucash/engine", 0 );
|
||||
if( !engine ) return FALSE;
|
||||
engine = gnc_module_load( "gnucash/engine", 0 );
|
||||
if ( !engine ) return FALSE;
|
||||
|
||||
/* Need to initialize g-type engine for gconf */
|
||||
if (refcount == 0) {
|
||||
g_type_init();
|
||||
}
|
||||
/* Need to initialize g-type engine for gconf */
|
||||
if (refcount == 0)
|
||||
{
|
||||
g_type_init();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
gnc_module_end(int refcount)
|
||||
{
|
||||
int unload = TRUE;
|
||||
int unload = TRUE;
|
||||
|
||||
if( engine != NULL ) {
|
||||
unload = gnc_module_unload(engine);
|
||||
}
|
||||
if ( engine != NULL )
|
||||
{
|
||||
unload = gnc_module_unload(engine);
|
||||
}
|
||||
|
||||
if( refcount == 0 ) {
|
||||
engine = NULL;
|
||||
}
|
||||
if ( refcount == 0 )
|
||||
{
|
||||
engine = NULL;
|
||||
}
|
||||
|
||||
return unload;
|
||||
return unload;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include "qof.h"
|
||||
#include "cashobjects.h"
|
||||
@@ -41,60 +41,62 @@ static QofSession*
|
||||
create_session(void)
|
||||
{
|
||||
QofSession* session = qof_session_new();
|
||||
QofBook* book = qof_session_get_book( session );
|
||||
Account* root = gnc_book_get_root_account( book );
|
||||
Account* a;
|
||||
KvpFrame* frame;
|
||||
Timespec ts;
|
||||
struct timeval tv;
|
||||
QofBook* book = qof_session_get_book( session );
|
||||
Account* root = gnc_book_get_root_account( book );
|
||||
Account* a;
|
||||
KvpFrame* frame;
|
||||
Timespec ts;
|
||||
struct timeval tv;
|
||||
|
||||
a = xaccMallocAccount( book );
|
||||
xaccAccountSetType( a, ACCT_TYPE_BANK );
|
||||
xaccAccountSetName( a, "Bank" );
|
||||
a = xaccMallocAccount( book );
|
||||
xaccAccountSetType( a, ACCT_TYPE_BANK );
|
||||
xaccAccountSetName( a, "Bank" );
|
||||
|
||||
frame = qof_instance_get_slots( QOF_INSTANCE(a) );
|
||||
kvp_frame_set_gint64( frame, "int64-val", 100 );
|
||||
kvp_frame_set_double( frame, "double-val", 3.14159 );
|
||||
kvp_frame_set_numeric( frame, "numeric-val", gnc_numeric_zero() );
|
||||
frame = qof_instance_get_slots( QOF_INSTANCE(a) );
|
||||
kvp_frame_set_gint64( frame, "int64-val", 100 );
|
||||
kvp_frame_set_double( frame, "double-val", 3.14159 );
|
||||
kvp_frame_set_numeric( frame, "numeric-val", gnc_numeric_zero() );
|
||||
|
||||
time( &(tv.tv_sec) );
|
||||
tv.tv_usec = 0;
|
||||
ts.tv_sec = tv.tv_sec;
|
||||
ts.tv_nsec = 1000*tv.tv_usec;
|
||||
kvp_frame_set_timespec( frame, "timespec-val", ts );
|
||||
time( &(tv.tv_sec) );
|
||||
tv.tv_usec = 0;
|
||||
ts.tv_sec = tv.tv_sec;
|
||||
ts.tv_nsec = 1000 * tv.tv_usec;
|
||||
kvp_frame_set_timespec( frame, "timespec-val", ts );
|
||||
|
||||
kvp_frame_set_string( frame, "string-val", "abcdefghijklmnop" );
|
||||
kvp_frame_set_guid( frame, "guid-val", qof_instance_get_guid( QOF_INSTANCE(a) ) );
|
||||
kvp_frame_set_string( frame, "string-val", "abcdefghijklmnop" );
|
||||
kvp_frame_set_guid( frame, "guid-val", qof_instance_get_guid( QOF_INSTANCE(a) ) );
|
||||
|
||||
gnc_account_append_child( root, a );
|
||||
gnc_account_append_child( root, a );
|
||||
|
||||
return session;
|
||||
return session;
|
||||
}
|
||||
|
||||
int main (int argc, char ** argv)
|
||||
{
|
||||
gchar* filename;
|
||||
gchar* filename;
|
||||
QofSession* session_1;
|
||||
|
||||
|
||||
qof_init();
|
||||
cashobjects_register();
|
||||
qof_load_backend_library ("../.libs/", GNC_LIB_NAME);
|
||||
|
||||
// Create a session with data
|
||||
session_1 = create_session();
|
||||
filename = tempnam( "/tmp", "test-sqlite3-" );
|
||||
printf( "Using filename: %s\n", filename );
|
||||
test_dbi_store_and_reload( "sqlite3", session_1, filename );
|
||||
printf( "TEST_MYSQL_URL='%s'\n", TEST_MYSQL_URL );
|
||||
if( strlen( TEST_MYSQL_URL ) > 0 ) {
|
||||
session_1 = create_session();
|
||||
test_dbi_store_and_reload( "mysql", session_1, TEST_MYSQL_URL );
|
||||
}
|
||||
printf( "TEST_PGSQL_URL='%s'\n", TEST_PGSQL_URL );
|
||||
if( strlen( TEST_PGSQL_URL ) > 0 ) {
|
||||
session_1 = create_session();
|
||||
test_dbi_store_and_reload( "pgsql", session_1, TEST_PGSQL_URL );
|
||||
}
|
||||
// Create a session with data
|
||||
session_1 = create_session();
|
||||
filename = tempnam( "/tmp", "test-sqlite3-" );
|
||||
printf( "Using filename: %s\n", filename );
|
||||
test_dbi_store_and_reload( "sqlite3", session_1, filename );
|
||||
printf( "TEST_MYSQL_URL='%s'\n", TEST_MYSQL_URL );
|
||||
if ( strlen( TEST_MYSQL_URL ) > 0 )
|
||||
{
|
||||
session_1 = create_session();
|
||||
test_dbi_store_and_reload( "mysql", session_1, TEST_MYSQL_URL );
|
||||
}
|
||||
printf( "TEST_PGSQL_URL='%s'\n", TEST_PGSQL_URL );
|
||||
if ( strlen( TEST_PGSQL_URL ) > 0 )
|
||||
{
|
||||
session_1 = create_session();
|
||||
test_dbi_store_and_reload( "pgsql", session_1, TEST_PGSQL_URL );
|
||||
}
|
||||
print_test_results();
|
||||
qof_close();
|
||||
exit(get_rv());
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include "qof.h"
|
||||
#include "cashobjects.h"
|
||||
@@ -40,317 +40,318 @@ static QofLogModule log_module = "test-dbi";
|
||||
static gboolean
|
||||
test_commodity_equal(const gnc_commodity * a, const gnc_commodity * b)
|
||||
{
|
||||
if (a == b) return TRUE;
|
||||
if (a == b) return TRUE;
|
||||
|
||||
if (!a || !b)
|
||||
{
|
||||
DEBUG ("one is NULL");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
{
|
||||
const gchar* ns1 = gnc_commodity_get_namespace(a);
|
||||
const gchar* ns2 = gnc_commodity_get_namespace(b);
|
||||
|
||||
if( ns1 != ns2 && safe_strcmp(ns1, ns2) != 0 )
|
||||
if (!a || !b)
|
||||
{
|
||||
DEBUG ("namespaces differ: %s vs %s", ns1, ns2 );
|
||||
return FALSE;
|
||||
DEBUG ("one is NULL");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (safe_strcmp(gnc_commodity_get_mnemonic(a), gnc_commodity_get_mnemonic(b)) != 0)
|
||||
{
|
||||
DEBUG ("mnemonics differ: %s vs %s", gnc_commodity_get_mnemonic(a), gnc_commodity_get_mnemonic(b));
|
||||
return FALSE;
|
||||
}
|
||||
{
|
||||
const gchar* ns1 = gnc_commodity_get_namespace(a);
|
||||
const gchar* ns2 = gnc_commodity_get_namespace(b);
|
||||
|
||||
if (safe_strcmp(gnc_commodity_get_fullname(a), gnc_commodity_get_fullname(b)) != 0)
|
||||
{
|
||||
DEBUG ("fullnames differ: %s vs %s", gnc_commodity_get_fullname(a), gnc_commodity_get_fullname(b));
|
||||
return FALSE;
|
||||
}
|
||||
if ( ns1 != ns2 && safe_strcmp(ns1, ns2) != 0 )
|
||||
{
|
||||
DEBUG ("namespaces differ: %s vs %s", ns1, ns2 );
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (safe_strcmp(gnc_commodity_get_cusip(a), gnc_commodity_get_cusip(b)) != 0)
|
||||
{
|
||||
DEBUG ("cusips differ: %s vs %s", gnc_commodity_get_cusip(a), gnc_commodity_get_cusip(b));
|
||||
return FALSE;
|
||||
}
|
||||
if (safe_strcmp(gnc_commodity_get_mnemonic(a), gnc_commodity_get_mnemonic(b)) != 0)
|
||||
{
|
||||
DEBUG ("mnemonics differ: %s vs %s", gnc_commodity_get_mnemonic(a), gnc_commodity_get_mnemonic(b));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (gnc_commodity_get_fraction(a) != gnc_commodity_get_fraction(b))
|
||||
{
|
||||
DEBUG ("fractions differ: %d vs %d", gnc_commodity_get_fraction(a), gnc_commodity_get_fraction(b));
|
||||
return FALSE;
|
||||
}
|
||||
if (safe_strcmp(gnc_commodity_get_fullname(a), gnc_commodity_get_fullname(b)) != 0)
|
||||
{
|
||||
DEBUG ("fullnames differ: %s vs %s", gnc_commodity_get_fullname(a), gnc_commodity_get_fullname(b));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
if (safe_strcmp(gnc_commodity_get_cusip(a), gnc_commodity_get_cusip(b)) != 0)
|
||||
{
|
||||
DEBUG ("cusips differ: %s vs %s", gnc_commodity_get_cusip(a), gnc_commodity_get_cusip(b));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (gnc_commodity_get_fraction(a) != gnc_commodity_get_fraction(b))
|
||||
{
|
||||
DEBUG ("fractions differ: %d vs %d", gnc_commodity_get_fraction(a), gnc_commodity_get_fraction(b));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
testAcctChildrenEqual(const GList *na,
|
||||
const GList *nb,
|
||||
gboolean check_guids)
|
||||
const GList *nb,
|
||||
gboolean check_guids)
|
||||
{
|
||||
if ((!na && nb) || (na && !nb))
|
||||
{
|
||||
PWARN ("only one has accounts");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
while (na && nb)
|
||||
{
|
||||
Account *aa = na->data;
|
||||
Account *ab = nb->data;
|
||||
|
||||
if (!testAccountEqual(aa, ab, check_guids))
|
||||
if ((!na && nb) || (na && !nb))
|
||||
{
|
||||
char sa[GUID_ENCODING_LENGTH + 1];
|
||||
char sb[GUID_ENCODING_LENGTH + 1];
|
||||
|
||||
guid_to_string_buff (xaccAccountGetGUID (aa), sa);
|
||||
guid_to_string_buff (xaccAccountGetGUID (ab), sb);
|
||||
|
||||
PWARN ("accounts %s and %s differ", sa, sb);
|
||||
|
||||
return(FALSE);
|
||||
PWARN ("only one has accounts");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
na = na->next;
|
||||
nb = nb->next;
|
||||
}
|
||||
while (na && nb)
|
||||
{
|
||||
Account *aa = na->data;
|
||||
Account *ab = nb->data;
|
||||
|
||||
if (na || nb)
|
||||
{
|
||||
PWARN ("different numbers of accounts");
|
||||
return(FALSE);
|
||||
}
|
||||
if (!testAccountEqual(aa, ab, check_guids))
|
||||
{
|
||||
char sa[GUID_ENCODING_LENGTH + 1];
|
||||
char sb[GUID_ENCODING_LENGTH + 1];
|
||||
|
||||
return(TRUE);
|
||||
guid_to_string_buff (xaccAccountGetGUID (aa), sa);
|
||||
guid_to_string_buff (xaccAccountGetGUID (ab), sb);
|
||||
|
||||
PWARN ("accounts %s and %s differ", sa, sb);
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
na = na->next;
|
||||
nb = nb->next;
|
||||
}
|
||||
|
||||
if (na || nb)
|
||||
{
|
||||
PWARN ("different numbers of accounts");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
testAccountEqual(const Account *aa, const Account *ab, gboolean check_guids)
|
||||
{
|
||||
if(!aa && !ab) return TRUE;
|
||||
if (!aa && !ab) return TRUE;
|
||||
|
||||
g_return_val_if_fail(GNC_IS_ACCOUNT(aa), FALSE);
|
||||
g_return_val_if_fail(GNC_IS_ACCOUNT(ab), FALSE);
|
||||
g_return_val_if_fail(GNC_IS_ACCOUNT(aa), FALSE);
|
||||
g_return_val_if_fail(GNC_IS_ACCOUNT(ab), FALSE);
|
||||
|
||||
if (xaccAccountGetType(aa) != xaccAccountGetType(ab))
|
||||
{
|
||||
PWARN ("'%s' and '%s': types differ: %d vs %d",
|
||||
xaccAccountGetName(aa), xaccAccountGetName(ab),
|
||||
xaccAccountGetType(aa), xaccAccountGetType(ab));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (safe_strcmp(xaccAccountGetName(aa), xaccAccountGetName(ab)) != 0)
|
||||
{
|
||||
PWARN ("names differ: %s vs %s", xaccAccountGetName(aa), xaccAccountGetName(ab));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (safe_strcmp(xaccAccountGetCode(aa), xaccAccountGetCode(ab)) != 0)
|
||||
{
|
||||
PWARN ("codes differ: %s vs %s", xaccAccountGetCode(aa), xaccAccountGetCode(ab));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (safe_strcmp(xaccAccountGetDescription(aa), xaccAccountGetDescription(ab)) != 0)
|
||||
{
|
||||
PWARN ("descriptions differ: %s vs %s", xaccAccountGetDescription(aa), xaccAccountGetDescription(ab));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!test_commodity_equal(xaccAccountGetCommodity(aa), xaccAccountGetCommodity(ab)))
|
||||
{
|
||||
PWARN ("commodities differ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(check_guids) {
|
||||
if(qof_instance_guid_compare(aa, ab) != 0)
|
||||
if (xaccAccountGetType(aa) != xaccAccountGetType(ab))
|
||||
{
|
||||
gchar guid_a[33];
|
||||
gchar guid_b[33];
|
||||
|
||||
guid_to_string_buff( qof_entity_get_guid( QOF_INSTANCE(aa) ), guid_a );
|
||||
guid_to_string_buff( qof_entity_get_guid( QOF_INSTANCE(ab) ), guid_b );
|
||||
PWARN ("'%s' and '%s': GUIDs differ %s vs %s",
|
||||
xaccAccountGetName(aa), xaccAccountGetName(ab),
|
||||
guid_a, guid_b);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (kvp_frame_compare(qof_instance_get_slots(QOF_INSTANCE(aa)), qof_instance_get_slots(QOF_INSTANCE(ab))) != 0)
|
||||
{
|
||||
char *frame_a;
|
||||
char *frame_b;
|
||||
|
||||
frame_a = kvp_frame_to_string (qof_instance_get_slots(QOF_INSTANCE(aa)));
|
||||
frame_b = kvp_frame_to_string (qof_instance_get_slots(QOF_INSTANCE(ab)));
|
||||
|
||||
PWARN ("kvp frames differ:\n%s\n\nvs\n\n%s", frame_a, frame_b);
|
||||
|
||||
g_free (frame_a);
|
||||
g_free (frame_b);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gnc_numeric_equal(gnc_account_get_start_balance((Account*)aa), gnc_account_get_start_balance((Account*)ab)))
|
||||
{
|
||||
char *str_a;
|
||||
char *str_b;
|
||||
|
||||
str_a = gnc_numeric_to_string(gnc_account_get_start_balance((Account*)aa));
|
||||
str_b = gnc_numeric_to_string(gnc_account_get_start_balance((Account*)ab));
|
||||
|
||||
PWARN ("starting balances differ: %s vs %s", str_a, str_b);
|
||||
|
||||
g_free (str_a);
|
||||
g_free (str_b);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gnc_numeric_equal(gnc_account_get_start_cleared_balance((Account*)aa),
|
||||
gnc_account_get_start_cleared_balance((Account*)ab)))
|
||||
{
|
||||
char *str_a;
|
||||
char *str_b;
|
||||
|
||||
str_a = gnc_numeric_to_string(gnc_account_get_start_cleared_balance((Account*)aa));
|
||||
str_b = gnc_numeric_to_string(gnc_account_get_start_cleared_balance((Account*)ab));
|
||||
|
||||
PWARN ("starting cleared balances differ: %s vs %s", str_a, str_b);
|
||||
|
||||
g_free (str_a);
|
||||
g_free (str_b);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gnc_numeric_equal(gnc_account_get_start_reconciled_balance((Account*)aa),
|
||||
gnc_account_get_start_reconciled_balance((Account*)ab)))
|
||||
{
|
||||
char *str_a;
|
||||
char *str_b;
|
||||
|
||||
str_a = gnc_numeric_to_string(gnc_account_get_start_reconciled_balance((Account*)aa));
|
||||
str_b = gnc_numeric_to_string(gnc_account_get_start_reconciled_balance((Account*)ab));
|
||||
|
||||
PWARN ("starting reconciled balances differ: %s vs %s", str_a, str_b);
|
||||
|
||||
g_free (str_a);
|
||||
g_free (str_b);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gnc_numeric_equal(xaccAccountGetBalance(aa), xaccAccountGetBalance(ab)))
|
||||
{
|
||||
char *str_a;
|
||||
char *str_b;
|
||||
|
||||
str_a = gnc_numeric_to_string(xaccAccountGetBalance(aa));
|
||||
str_b = gnc_numeric_to_string(xaccAccountGetBalance(ab));
|
||||
|
||||
PWARN ("balances differ: %s vs %s", str_a, str_b);
|
||||
|
||||
g_free (str_a);
|
||||
g_free (str_b);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gnc_numeric_equal(xaccAccountGetClearedBalance(aa), xaccAccountGetClearedBalance(ab)))
|
||||
{
|
||||
char *str_a;
|
||||
char *str_b;
|
||||
|
||||
str_a = gnc_numeric_to_string(xaccAccountGetClearedBalance(aa));
|
||||
str_b = gnc_numeric_to_string(xaccAccountGetClearedBalance(ab));
|
||||
|
||||
PWARN ("cleared balances differ: %s vs %s", str_a, str_b);
|
||||
|
||||
g_free (str_a);
|
||||
g_free (str_b);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gnc_numeric_equal(xaccAccountGetReconciledBalance(aa), xaccAccountGetReconciledBalance(ab)))
|
||||
{
|
||||
char *str_a;
|
||||
char *str_b;
|
||||
|
||||
str_a = gnc_numeric_to_string(xaccAccountGetReconciledBalance(aa));
|
||||
str_b = gnc_numeric_to_string(xaccAccountGetReconciledBalance(ab));
|
||||
|
||||
PWARN ("reconciled balances differ: %s vs %s", str_a, str_b);
|
||||
|
||||
g_free (str_a);
|
||||
g_free (str_b);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* no parent; always compare downwards. */
|
||||
|
||||
{
|
||||
GList *la = xaccAccountGetSplitList(aa);
|
||||
GList *lb = xaccAccountGetSplitList(ab);
|
||||
|
||||
if ((la && !lb) || (!la && lb))
|
||||
{
|
||||
PWARN ("only one has splits");
|
||||
return FALSE;
|
||||
PWARN ("'%s' and '%s': types differ: %d vs %d",
|
||||
xaccAccountGetName(aa), xaccAccountGetName(ab),
|
||||
xaccAccountGetType(aa), xaccAccountGetType(ab));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(la && lb)
|
||||
if (safe_strcmp(xaccAccountGetName(aa), xaccAccountGetName(ab)) != 0)
|
||||
{
|
||||
/* presume that the splits are in the same order */
|
||||
while (la && lb)
|
||||
{
|
||||
Split *sa = (Split *) la->data;
|
||||
Split *sb = (Split *) lb->data;
|
||||
PWARN ("names differ: %s vs %s", xaccAccountGetName(aa), xaccAccountGetName(ab));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!xaccSplitEqual(sa, sb, check_guids, TRUE, FALSE))
|
||||
if (safe_strcmp(xaccAccountGetCode(aa), xaccAccountGetCode(ab)) != 0)
|
||||
{
|
||||
PWARN ("codes differ: %s vs %s", xaccAccountGetCode(aa), xaccAccountGetCode(ab));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (safe_strcmp(xaccAccountGetDescription(aa), xaccAccountGetDescription(ab)) != 0)
|
||||
{
|
||||
PWARN ("descriptions differ: %s vs %s", xaccAccountGetDescription(aa), xaccAccountGetDescription(ab));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!test_commodity_equal(xaccAccountGetCommodity(aa), xaccAccountGetCommodity(ab)))
|
||||
{
|
||||
PWARN ("commodities differ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (check_guids)
|
||||
{
|
||||
if (qof_instance_guid_compare(aa, ab) != 0)
|
||||
{
|
||||
PWARN ("splits differ");
|
||||
return(FALSE);
|
||||
gchar guid_a[33];
|
||||
gchar guid_b[33];
|
||||
|
||||
guid_to_string_buff( qof_entity_get_guid( QOF_INSTANCE(aa) ), guid_a );
|
||||
guid_to_string_buff( qof_entity_get_guid( QOF_INSTANCE(ab) ), guid_b );
|
||||
PWARN ("'%s' and '%s': GUIDs differ %s vs %s",
|
||||
xaccAccountGetName(aa), xaccAccountGetName(ab),
|
||||
guid_a, guid_b);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (kvp_frame_compare(qof_instance_get_slots(QOF_INSTANCE(aa)), qof_instance_get_slots(QOF_INSTANCE(ab))) != 0)
|
||||
{
|
||||
char *frame_a;
|
||||
char *frame_b;
|
||||
|
||||
frame_a = kvp_frame_to_string (qof_instance_get_slots(QOF_INSTANCE(aa)));
|
||||
frame_b = kvp_frame_to_string (qof_instance_get_slots(QOF_INSTANCE(ab)));
|
||||
|
||||
PWARN ("kvp frames differ:\n%s\n\nvs\n\n%s", frame_a, frame_b);
|
||||
|
||||
g_free (frame_a);
|
||||
g_free (frame_b);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gnc_numeric_equal(gnc_account_get_start_balance((Account*)aa), gnc_account_get_start_balance((Account*)ab)))
|
||||
{
|
||||
char *str_a;
|
||||
char *str_b;
|
||||
|
||||
str_a = gnc_numeric_to_string(gnc_account_get_start_balance((Account*)aa));
|
||||
str_b = gnc_numeric_to_string(gnc_account_get_start_balance((Account*)ab));
|
||||
|
||||
PWARN ("starting balances differ: %s vs %s", str_a, str_b);
|
||||
|
||||
g_free (str_a);
|
||||
g_free (str_b);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gnc_numeric_equal(gnc_account_get_start_cleared_balance((Account*)aa),
|
||||
gnc_account_get_start_cleared_balance((Account*)ab)))
|
||||
{
|
||||
char *str_a;
|
||||
char *str_b;
|
||||
|
||||
str_a = gnc_numeric_to_string(gnc_account_get_start_cleared_balance((Account*)aa));
|
||||
str_b = gnc_numeric_to_string(gnc_account_get_start_cleared_balance((Account*)ab));
|
||||
|
||||
PWARN ("starting cleared balances differ: %s vs %s", str_a, str_b);
|
||||
|
||||
g_free (str_a);
|
||||
g_free (str_b);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gnc_numeric_equal(gnc_account_get_start_reconciled_balance((Account*)aa),
|
||||
gnc_account_get_start_reconciled_balance((Account*)ab)))
|
||||
{
|
||||
char *str_a;
|
||||
char *str_b;
|
||||
|
||||
str_a = gnc_numeric_to_string(gnc_account_get_start_reconciled_balance((Account*)aa));
|
||||
str_b = gnc_numeric_to_string(gnc_account_get_start_reconciled_balance((Account*)ab));
|
||||
|
||||
PWARN ("starting reconciled balances differ: %s vs %s", str_a, str_b);
|
||||
|
||||
g_free (str_a);
|
||||
g_free (str_b);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gnc_numeric_equal(xaccAccountGetBalance(aa), xaccAccountGetBalance(ab)))
|
||||
{
|
||||
char *str_a;
|
||||
char *str_b;
|
||||
|
||||
str_a = gnc_numeric_to_string(xaccAccountGetBalance(aa));
|
||||
str_b = gnc_numeric_to_string(xaccAccountGetBalance(ab));
|
||||
|
||||
PWARN ("balances differ: %s vs %s", str_a, str_b);
|
||||
|
||||
g_free (str_a);
|
||||
g_free (str_b);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gnc_numeric_equal(xaccAccountGetClearedBalance(aa), xaccAccountGetClearedBalance(ab)))
|
||||
{
|
||||
char *str_a;
|
||||
char *str_b;
|
||||
|
||||
str_a = gnc_numeric_to_string(xaccAccountGetClearedBalance(aa));
|
||||
str_b = gnc_numeric_to_string(xaccAccountGetClearedBalance(ab));
|
||||
|
||||
PWARN ("cleared balances differ: %s vs %s", str_a, str_b);
|
||||
|
||||
g_free (str_a);
|
||||
g_free (str_b);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gnc_numeric_equal(xaccAccountGetReconciledBalance(aa), xaccAccountGetReconciledBalance(ab)))
|
||||
{
|
||||
char *str_a;
|
||||
char *str_b;
|
||||
|
||||
str_a = gnc_numeric_to_string(xaccAccountGetReconciledBalance(aa));
|
||||
str_b = gnc_numeric_to_string(xaccAccountGetReconciledBalance(ab));
|
||||
|
||||
PWARN ("reconciled balances differ: %s vs %s", str_a, str_b);
|
||||
|
||||
g_free (str_a);
|
||||
g_free (str_b);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* no parent; always compare downwards. */
|
||||
|
||||
{
|
||||
GList *la = xaccAccountGetSplitList(aa);
|
||||
GList *lb = xaccAccountGetSplitList(ab);
|
||||
|
||||
if ((la && !lb) || (!la && lb))
|
||||
{
|
||||
PWARN ("only one has splits");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
la = la->next;
|
||||
lb = lb->next;
|
||||
}
|
||||
if (la && lb)
|
||||
{
|
||||
/* presume that the splits are in the same order */
|
||||
while (la && lb)
|
||||
{
|
||||
Split *sa = (Split *) la->data;
|
||||
Split *sb = (Split *) lb->data;
|
||||
|
||||
if ((la != NULL) || (lb != NULL))
|
||||
{
|
||||
PWARN ("number of splits differs");
|
||||
return(FALSE);
|
||||
}
|
||||
if (!xaccSplitEqual(sa, sb, check_guids, TRUE, FALSE))
|
||||
{
|
||||
PWARN ("splits differ");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
la = la->next;
|
||||
lb = lb->next;
|
||||
}
|
||||
|
||||
if ((la != NULL) || (lb != NULL))
|
||||
{
|
||||
PWARN ("number of splits differs");
|
||||
return(FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!testAcctChildrenEqual(gnc_account_get_children(aa), gnc_account_get_children(ab), check_guids))
|
||||
{
|
||||
PWARN ("children differ");
|
||||
return FALSE;
|
||||
}
|
||||
if (!testAcctChildrenEqual(gnc_account_get_children(aa), gnc_account_get_children(ab), check_guids))
|
||||
{
|
||||
PWARN ("children differ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
return(TRUE);
|
||||
}
|
||||
static void
|
||||
compare_accounts( QofBook* book_1, QofBook* book_2 )
|
||||
{
|
||||
Account* root_1 = gnc_book_get_root_account( book_1 );
|
||||
Account* root_2 = gnc_book_get_root_account( book_2 );
|
||||
Account* root_2 = gnc_book_get_root_account( book_2 );
|
||||
|
||||
xaccAccountSetHidden( root_1, xaccAccountGetHidden( root_1 ) );
|
||||
do_test( testAccountEqual( root_1, root_2, TRUE ), "Accounts trees match" );
|
||||
xaccAccountSetHidden( root_1, xaccAccountGetHidden( root_1 ) );
|
||||
do_test( testAccountEqual( root_1, root_2, TRUE ), "Accounts trees match" );
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -371,37 +372,37 @@ compare_sxs( QofBook* book_1, QofBook* book_2 )
|
||||
static void
|
||||
compare_books( QofBook* book_1, QofBook* book_2 )
|
||||
{
|
||||
compare_accounts( book_1, book_2 );
|
||||
compare_pricedbs( book_1, book_2 );
|
||||
compare_txs( book_1, book_2 );
|
||||
compare_sxs( book_1, book_2 );
|
||||
compare_accounts( book_1, book_2 );
|
||||
compare_pricedbs( book_1, book_2 );
|
||||
compare_txs( book_1, book_2 );
|
||||
compare_sxs( book_1, book_2 );
|
||||
}
|
||||
|
||||
void
|
||||
test_dbi_store_and_reload( const gchar* driver, QofSession* session_1, const gchar* url )
|
||||
{
|
||||
QofSession* session_2;
|
||||
QofSession* session_3;
|
||||
QofSession* session_2;
|
||||
QofSession* session_3;
|
||||
|
||||
printf( "Testing %s\n", driver );
|
||||
printf( "Testing %s\n", driver );
|
||||
|
||||
// Save the session data
|
||||
session_2 = qof_session_new();
|
||||
qof_session_begin( session_2, url, TRUE, TRUE );
|
||||
qof_session_swap_data( session_1, session_2 );
|
||||
qof_session_save( session_2, NULL );
|
||||
// Save the session data
|
||||
session_2 = qof_session_new();
|
||||
qof_session_begin( session_2, url, TRUE, TRUE );
|
||||
qof_session_swap_data( session_1, session_2 );
|
||||
qof_session_save( session_2, NULL );
|
||||
|
||||
// Reload the session data
|
||||
session_3 = qof_session_new();
|
||||
qof_session_begin( session_3, url, FALSE, FALSE );
|
||||
qof_session_load( session_3, NULL );
|
||||
// Reload the session data
|
||||
session_3 = qof_session_new();
|
||||
qof_session_begin( session_3, url, FALSE, FALSE );
|
||||
qof_session_load( session_3, NULL );
|
||||
|
||||
// Compare with the original data
|
||||
compare_books( qof_session_get_book( session_2 ), qof_session_get_book( session_3 ) );
|
||||
qof_session_end( session_1 );
|
||||
qof_session_destroy( session_1 );
|
||||
qof_session_end( session_2 );
|
||||
qof_session_destroy( session_2 );
|
||||
qof_session_end( session_3 );
|
||||
qof_session_destroy( session_3 );
|
||||
// Compare with the original data
|
||||
compare_books( qof_session_get_book( session_2 ), qof_session_get_book( session_3 ) );
|
||||
qof_session_end( session_1 );
|
||||
qof_session_destroy( session_1 );
|
||||
qof_session_end( session_2 );
|
||||
qof_session_destroy( session_2 );
|
||||
qof_session_end( session_3 );
|
||||
qof_session_destroy( session_3 );
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _TEST_DBI_STUFF_H_
|
||||
#define _TEST_DBI_STUFF_H_
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include "qof.h"
|
||||
#include "cashobjects.h"
|
||||
@@ -40,37 +40,39 @@
|
||||
|
||||
int main (int argc, char ** argv)
|
||||
{
|
||||
gchar* filename;
|
||||
gchar* filename;
|
||||
QofSession* session_1;
|
||||
|
||||
|
||||
qof_init();
|
||||
cashobjects_register();
|
||||
qof_load_backend_library ("../.libs/", GNC_LIB_NAME);
|
||||
|
||||
// Create a session with data
|
||||
session_1 = qof_session_new();
|
||||
qof_session_begin( session_1, DBI_TEST_XML_FILENAME, FALSE, FALSE );
|
||||
qof_session_load( session_1, NULL );
|
||||
// Create a session with data
|
||||
session_1 = qof_session_new();
|
||||
qof_session_begin( session_1, DBI_TEST_XML_FILENAME, FALSE, FALSE );
|
||||
qof_session_load( session_1, NULL );
|
||||
|
||||
filename = tempnam( "/tmp", "test-sqlite3-" );
|
||||
printf( "Using filename: %s\n", filename );
|
||||
test_dbi_store_and_reload( "sqlite3", session_1, filename );
|
||||
filename = tempnam( "/tmp", "test-sqlite3-" );
|
||||
printf( "Using filename: %s\n", filename );
|
||||
test_dbi_store_and_reload( "sqlite3", session_1, filename );
|
||||
|
||||
printf( "TEST_MYSQL_URL='%s'\n", TEST_MYSQL_URL );
|
||||
if( strlen( TEST_MYSQL_URL ) > 0 ) {
|
||||
session_1 = qof_session_new();
|
||||
qof_session_begin( session_1, DBI_TEST_XML_FILENAME, FALSE, FALSE );
|
||||
qof_session_load( session_1, NULL );
|
||||
test_dbi_store_and_reload( "mysql", session_1, TEST_MYSQL_URL );
|
||||
}
|
||||
printf( "TEST_MYSQL_URL='%s'\n", TEST_MYSQL_URL );
|
||||
if ( strlen( TEST_MYSQL_URL ) > 0 )
|
||||
{
|
||||
session_1 = qof_session_new();
|
||||
qof_session_begin( session_1, DBI_TEST_XML_FILENAME, FALSE, FALSE );
|
||||
qof_session_load( session_1, NULL );
|
||||
test_dbi_store_and_reload( "mysql", session_1, TEST_MYSQL_URL );
|
||||
}
|
||||
|
||||
printf( "TEST_PGSQL_URL='%s'\n", TEST_PGSQL_URL );
|
||||
if( strlen( TEST_PGSQL_URL ) > 0 ) {
|
||||
session_1 = qof_session_new();
|
||||
qof_session_begin( session_1, DBI_TEST_XML_FILENAME, FALSE, FALSE );
|
||||
qof_session_load( session_1, NULL );
|
||||
test_dbi_store_and_reload( "pgsql", session_1, TEST_PGSQL_URL );
|
||||
}
|
||||
printf( "TEST_PGSQL_URL='%s'\n", TEST_PGSQL_URL );
|
||||
if ( strlen( TEST_PGSQL_URL ) > 0 )
|
||||
{
|
||||
session_1 = qof_session_new();
|
||||
qof_session_begin( session_1, DBI_TEST_XML_FILENAME, FALSE, FALSE );
|
||||
qof_session_load( session_1, NULL );
|
||||
test_dbi_store_and_reload( "pgsql", session_1, TEST_PGSQL_URL );
|
||||
}
|
||||
print_test_results();
|
||||
qof_close();
|
||||
exit(get_rv());
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include "qof.h"
|
||||
#include "cashobjects.h"
|
||||
|
||||
@@ -31,11 +31,11 @@
|
||||
/** @addtogroup SQLBE
|
||||
* The SQL backend core is a library which can form the core for a QOF
|
||||
* backend based on an SQL library.
|
||||
*
|
||||
*
|
||||
* @file gnc-backend-sql.h
|
||||
* @brief load and save data to SQL
|
||||
* @author Copyright (c) 2006-2008 Phil Longstaff <plongstaff@rogers.com>
|
||||
*/
|
||||
*/
|
||||
|
||||
#ifndef GNC_BACKEND_SQL_H_
|
||||
#define GNC_BACKEND_SQL_H_
|
||||
@@ -53,16 +53,17 @@ typedef struct GncSqlConnection GncSqlConnection;
|
||||
*/
|
||||
struct GncSqlBackend
|
||||
{
|
||||
QofBackend be; /**< QOF backend */
|
||||
GncSqlConnection* conn; /**< SQL connection */
|
||||
/*@ dependent @*/ QofBook *primary_book; /**< The primary, main open book */
|
||||
gboolean loading; /**< We are performing an initial load */
|
||||
gboolean in_query; /**< We are processing a query */
|
||||
gboolean is_pristine_db; /**< Are we saving to a new pristine db? */
|
||||
gint obj_total; /**< Total # of objects (for percentage calculation) */
|
||||
gint operations_done; /**< Number of operations (save/load) done */
|
||||
GHashTable* versions; /**< Version number for each table */
|
||||
const gchar* timespec_format; /**< Format string for SQL for timespec values */
|
||||
QofBackend be; /**< QOF backend */
|
||||
GncSqlConnection* conn; /**< SQL connection */
|
||||
/*@ dependent @*/
|
||||
QofBook *primary_book; /**< The primary, main open book */
|
||||
gboolean loading; /**< We are performing an initial load */
|
||||
gboolean in_query; /**< We are processing a query */
|
||||
gboolean is_pristine_db; /**< Are we saving to a new pristine db? */
|
||||
gint obj_total; /**< Total # of objects (for percentage calculation) */
|
||||
gint operations_done; /**< Number of operations (save/load) done */
|
||||
GHashTable* versions; /**< Version number for each table */
|
||||
const gchar* timespec_format; /**< Format string for SQL for timespec values */
|
||||
};
|
||||
typedef struct GncSqlBackend GncSqlBackend;
|
||||
|
||||
@@ -128,9 +129,10 @@ typedef struct GncSqlRow GncSqlRow;
|
||||
*/
|
||||
struct GncSqlStatement
|
||||
{
|
||||
void (*dispose)( /*@ only @*/ GncSqlStatement* );
|
||||
/*@ dependent @*/ gchar* (*toSql)( GncSqlStatement* );
|
||||
void (*addWhereCond)( GncSqlStatement*, QofIdTypeConst, gpointer, const GncSqlColumnTableEntry*, GValue* );
|
||||
void (*dispose)( /*@ only @*/ GncSqlStatement* );
|
||||
/*@ dependent @*/
|
||||
gchar* (*toSql)( GncSqlStatement* );
|
||||
void (*addWhereCond)( GncSqlStatement*, QofIdTypeConst, gpointer, const GncSqlColumnTableEntry*, GValue* );
|
||||
};
|
||||
#define gnc_sql_statement_dispose(STMT) \
|
||||
(STMT)->dispose(STMT)
|
||||
@@ -147,17 +149,17 @@ struct GncSqlStatement
|
||||
*/
|
||||
struct GncSqlConnection
|
||||
{
|
||||
void (*dispose)( /*@ only @*/ GncSqlConnection* );
|
||||
GncSqlResult* (*executeSelectStatement)( GncSqlConnection*, GncSqlStatement* ); /**< Returns NULL if error */
|
||||
gint (*executeNonSelectStatement)( GncSqlConnection*, GncSqlStatement* ); /**< Returns -1 if error */
|
||||
GncSqlStatement* (*createStatementFromSql)( /*@ observer @*/ GncSqlConnection*, const gchar* );
|
||||
gboolean (*doesTableExist)( GncSqlConnection*, const gchar* );
|
||||
gboolean (*beginTransaction)( GncSqlConnection* ); /**< Returns TRUE if successful, FALSE if error */
|
||||
gboolean (*rollbackTransaction)( GncSqlConnection* ); /**< Returns TRUE if successful, FALSE if error */
|
||||
gboolean (*commitTransaction)( GncSqlConnection* ); /**< Returns TRUE if successful, FALSE if error */
|
||||
gboolean (*createTable)( GncSqlConnection*, const gchar*, GList* ); /**< Returns TRUE if successful, FALSE if error */
|
||||
gboolean (*createIndex)( GncSqlConnection*, const gchar*, const gchar*, const GncSqlColumnTableEntry* ); /**< Returns TRUE if successful, FALSE if error */
|
||||
gchar* (*quoteString)( const GncSqlConnection*, gchar* );
|
||||
void (*dispose)( /*@ only @*/ GncSqlConnection* );
|
||||
GncSqlResult* (*executeSelectStatement)( GncSqlConnection*, GncSqlStatement* ); /**< Returns NULL if error */
|
||||
gint (*executeNonSelectStatement)( GncSqlConnection*, GncSqlStatement* ); /**< Returns -1 if error */
|
||||
GncSqlStatement* (*createStatementFromSql)( /*@ observer @*/ GncSqlConnection*, const gchar* );
|
||||
gboolean (*doesTableExist)( GncSqlConnection*, const gchar* );
|
||||
gboolean (*beginTransaction)( GncSqlConnection* ); /**< Returns TRUE if successful, FALSE if error */
|
||||
gboolean (*rollbackTransaction)( GncSqlConnection* ); /**< Returns TRUE if successful, FALSE if error */
|
||||
gboolean (*commitTransaction)( GncSqlConnection* ); /**< Returns TRUE if successful, FALSE if error */
|
||||
gboolean (*createTable)( GncSqlConnection*, const gchar*, GList* ); /**< Returns TRUE if successful, FALSE if error */
|
||||
gboolean (*createIndex)( GncSqlConnection*, const gchar*, const gchar*, const GncSqlColumnTableEntry* ); /**< Returns TRUE if successful, FALSE if error */
|
||||
gchar* (*quoteString)( const GncSqlConnection*, gchar* );
|
||||
};
|
||||
#define gnc_sql_connection_dispose(CONN) (CONN)->dispose(CONN)
|
||||
#define gnc_sql_connection_execute_select_statement(CONN,STMT) \
|
||||
@@ -189,8 +191,8 @@ struct GncSqlConnection
|
||||
*/
|
||||
struct GncSqlRow
|
||||
{
|
||||
const GValue* (*getValueAtColName)( GncSqlRow*, const gchar* );
|
||||
void (*dispose)( /*@ only @*/ GncSqlRow* );
|
||||
const GValue* (*getValueAtColName)( GncSqlRow*, const gchar* );
|
||||
void (*dispose)( /*@ only @*/ GncSqlRow* );
|
||||
};
|
||||
#define gnc_sql_row_get_value_at_col_name(ROW,N) \
|
||||
(ROW)->getValueAtColName(ROW,N)
|
||||
@@ -205,10 +207,10 @@ struct GncSqlRow
|
||||
*/
|
||||
struct GncSqlResult
|
||||
{
|
||||
guint (*getNumRows)( GncSqlResult* );
|
||||
guint (*getNumRows)( GncSqlResult* );
|
||||
GncSqlRow* (*getFirstRow)( GncSqlResult* );
|
||||
GncSqlRow* (*getNextRow)( GncSqlResult* );
|
||||
void (*dispose)( /*@ only @*/ GncSqlResult* );
|
||||
GncSqlRow* (*getNextRow)( GncSqlResult* );
|
||||
void (*dispose)( /*@ only @*/ GncSqlResult* );
|
||||
};
|
||||
#define gnc_sql_result_get_num_rows(RESULT) \
|
||||
(RESULT)->getNumRows(RESULT)
|
||||
@@ -235,26 +237,33 @@ struct GncSqlResult
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int version; /**< Backend version number */
|
||||
const gchar * type_name; /**< Engine object type name */
|
||||
/** Commit an instance of this object to the database
|
||||
* @return TRUE if successful, FALSE if error
|
||||
*/
|
||||
/*@ null @*/ gboolean (*commit)( GncSqlBackend* be, QofInstance* inst );
|
||||
/** Load all objects of this type from the database */
|
||||
/*@ null @*/ void (*initial_load)( GncSqlBackend* be );
|
||||
/** Create database tables for this object */
|
||||
/*@ null @*/ void (*create_tables)( GncSqlBackend* be );
|
||||
/** Compile a query on these objects */
|
||||
/*@ null @*/ gpointer (*compile_query)( GncSqlBackend* be, QofQuery* pQuery );
|
||||
/** Run a query on these objects */
|
||||
/*@ null @*/ void (*run_query)( GncSqlBackend* be, gpointer pQuery );
|
||||
/** Free a query on these objects */
|
||||
/*@ null @*/ void (*free_query)( GncSqlBackend* be, gpointer pQuery );
|
||||
/** Write all objects of this type to the database
|
||||
* @return TRUE if successful, FALSE if error
|
||||
*/
|
||||
/*@ null @*/ gboolean (*write)( GncSqlBackend* be );
|
||||
int version; /**< Backend version number */
|
||||
const gchar * type_name; /**< Engine object type name */
|
||||
/** Commit an instance of this object to the database
|
||||
* @return TRUE if successful, FALSE if error
|
||||
*/
|
||||
/*@ null @*/
|
||||
gboolean (*commit)( GncSqlBackend* be, QofInstance* inst );
|
||||
/** Load all objects of this type from the database */
|
||||
/*@ null @*/
|
||||
void (*initial_load)( GncSqlBackend* be );
|
||||
/** Create database tables for this object */
|
||||
/*@ null @*/
|
||||
void (*create_tables)( GncSqlBackend* be );
|
||||
/** Compile a query on these objects */
|
||||
/*@ null @*/
|
||||
gpointer (*compile_query)( GncSqlBackend* be, QofQuery* pQuery );
|
||||
/** Run a query on these objects */
|
||||
/*@ null @*/
|
||||
void (*run_query)( GncSqlBackend* be, gpointer pQuery );
|
||||
/** Free a query on these objects */
|
||||
/*@ null @*/
|
||||
void (*free_query)( GncSqlBackend* be, gpointer pQuery );
|
||||
/** Write all objects of this type to the database
|
||||
* @return TRUE if successful, FALSE if error
|
||||
*/
|
||||
/*@ null @*/
|
||||
gboolean (*write)( GncSqlBackend* be );
|
||||
} GncSqlObjectBackend;
|
||||
#define GNC_SQL_BACKEND "gnc:sql:1"
|
||||
#define GNC_SQL_BACKEND_VERSION 1
|
||||
@@ -262,13 +271,14 @@ typedef struct
|
||||
/**
|
||||
* Basic column type
|
||||
*/
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
BCT_STRING,
|
||||
BCT_INT,
|
||||
BCT_INT64,
|
||||
BCT_DATE,
|
||||
BCT_DOUBLE,
|
||||
BCT_DATETIME
|
||||
BCT_INT,
|
||||
BCT_INT64,
|
||||
BCT_DATE,
|
||||
BCT_DOUBLE,
|
||||
BCT_DATETIME
|
||||
} GncSqlBasicColumnType;
|
||||
|
||||
/**
|
||||
@@ -277,14 +287,15 @@ typedef enum {
|
||||
* The GncSqlColumnInfo structure contains information required to create
|
||||
* a column in a table.
|
||||
*/
|
||||
typedef struct {
|
||||
/*@ only @*/ gchar* name; /**< Column name */
|
||||
GncSqlBasicColumnType type; /**< Column basic type */
|
||||
gint size; /**< Column size (string types) */
|
||||
gboolean is_unicode; /**< Column is unicode (string types) */
|
||||
gboolean is_autoinc; /**< Column is autoinc (int type) */
|
||||
gboolean is_primary_key; /**< Column is the primary key */
|
||||
gboolean null_allowed; /**< Column allows NULL values */
|
||||
typedef struct
|
||||
{
|
||||
/*@ only @*/ gchar* name; /**< Column name */
|
||||
GncSqlBasicColumnType type; /**< Column basic type */
|
||||
gint size; /**< Column size (string types) */
|
||||
gboolean is_unicode; /**< Column is unicode (string types) */
|
||||
gboolean is_autoinc; /**< Column is autoinc (int type) */
|
||||
gboolean is_primary_key; /**< Column is the primary key */
|
||||
gboolean null_allowed; /**< Column allows NULL values */
|
||||
} GncSqlColumnInfo;
|
||||
|
||||
// Type for conversion of db row to object.
|
||||
@@ -321,38 +332,44 @@ typedef struct {
|
||||
* The database description for an object consists of an array of
|
||||
* GncSqlColumnTableEntry objects, with a final member having col_name == NULL.
|
||||
*/
|
||||
struct GncSqlColumnTableEntry {
|
||||
/*@ dependent @*/ const gchar* col_name; /**< Column name */
|
||||
const gchar* col_type; /**< Column type */
|
||||
gint size; /**< Column size in bytes, for string columns */
|
||||
struct GncSqlColumnTableEntry
|
||||
{
|
||||
/*@ dependent @*/ const gchar* col_name; /**< Column name */
|
||||
const gchar* col_type; /**< Column type */
|
||||
gint size; /**< Column size in bytes, for string columns */
|
||||
#define COL_PKEY 0x01 /**< The column is a primary key */
|
||||
#define COL_NNUL 0x02 /**< The column may not contain a NULL value */
|
||||
#define COL_UNIQUE 0x04 /**< The column must contain unique values */
|
||||
#define COL_AUTOINC 0x08 /**< The column is an auto-incrementing int */
|
||||
gint flags; /**< Column flags */
|
||||
/*@ null @*/ const gchar* gobj_param_name; /**< If non-null, g_object param name */
|
||||
/*@ null @*/ const gchar* qof_param_name; /**< If non-null, qof parameter name */
|
||||
/*@ null @*/ QofAccessFunc getter; /**< General access function */
|
||||
/*@ null @*/ QofSetterFunc setter; /**< General setter function */
|
||||
gint flags; /**< Column flags */
|
||||
/*@ null @*/
|
||||
const gchar* gobj_param_name; /**< If non-null, g_object param name */
|
||||
/*@ null @*/
|
||||
const gchar* qof_param_name; /**< If non-null, qof parameter name */
|
||||
/*@ null @*/
|
||||
QofAccessFunc getter; /**< General access function */
|
||||
/*@ null @*/
|
||||
QofSetterFunc setter; /**< General setter function */
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
OP_DB_INSERT,
|
||||
OP_DB_UPDATE,
|
||||
OP_DB_DELETE
|
||||
typedef enum
|
||||
{
|
||||
OP_DB_INSERT,
|
||||
OP_DB_UPDATE,
|
||||
OP_DB_DELETE
|
||||
} E_DB_OPERATION;
|
||||
|
||||
typedef void (*GNC_SQL_LOAD_FN)( const GncSqlBackend* be,
|
||||
GncSqlRow* row,
|
||||
/*@ null @*/ QofSetterFunc setter, gpointer pObject,
|
||||
const GncSqlColumnTableEntry* table );
|
||||
GncSqlRow* row,
|
||||
/*@ null @*/ QofSetterFunc setter, gpointer pObject,
|
||||
const GncSqlColumnTableEntry* table );
|
||||
typedef void (*GNC_SQL_ADD_COL_INFO_TO_LIST_FN)( const GncSqlBackend* be,
|
||||
const GncSqlColumnTableEntry* table_row,
|
||||
GList** pList );
|
||||
const GncSqlColumnTableEntry* table_row,
|
||||
GList** pList );
|
||||
typedef void (*GNC_SQL_ADD_COLNAME_TO_LIST_FN)( const GncSqlColumnTableEntry* table_row, GList** pList );
|
||||
typedef void (*GNC_SQL_ADD_GVALUE_TO_SLIST_FN)( const GncSqlBackend* be,
|
||||
QofIdTypeConst obj_name, const gpointer pObject,
|
||||
const GncSqlColumnTableEntry* table_row, GSList** pList );
|
||||
QofIdTypeConst obj_name, const gpointer pObject,
|
||||
const GncSqlColumnTableEntry* table_row, GSList** pList );
|
||||
|
||||
/**
|
||||
* @struct GncSqlColumnTypeHandler
|
||||
@@ -362,27 +379,28 @@ typedef void (*GNC_SQL_ADD_GVALUE_TO_SLIST_FN)( const GncSqlBackend* be,
|
||||
*
|
||||
* A column type maps a property value to one or more columns in the database.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* Routine to load a value into an object from the database row.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* Routine to load a value into an object from the database row.
|
||||
*/
|
||||
GNC_SQL_LOAD_FN load_fn;
|
||||
|
||||
/**
|
||||
* Routine to add a GncSqlColumnInfo structure for the column type to a
|
||||
* GList.
|
||||
*/
|
||||
/**
|
||||
* Routine to add a GncSqlColumnInfo structure for the column type to a
|
||||
* GList.
|
||||
*/
|
||||
GNC_SQL_ADD_COL_INFO_TO_LIST_FN add_col_info_to_list_fn;
|
||||
|
||||
/**
|
||||
* Routine to add a column name string for the column type to a GList.
|
||||
*/
|
||||
/**
|
||||
* Routine to add a column name string for the column type to a GList.
|
||||
*/
|
||||
GNC_SQL_ADD_COLNAME_TO_LIST_FN add_colname_to_list_fn;
|
||||
|
||||
/**
|
||||
* Routine to add a GValue for the property to a GSList.
|
||||
*/
|
||||
GNC_SQL_ADD_GVALUE_TO_SLIST_FN add_gvalue_to_slist_fn;
|
||||
/**
|
||||
* Routine to add a GValue for the property to a GSList.
|
||||
*/
|
||||
GNC_SQL_ADD_GVALUE_TO_SLIST_FN add_gvalue_to_slist_fn;
|
||||
} GncSqlColumnTypeHandler;
|
||||
|
||||
/**
|
||||
@@ -392,7 +410,8 @@ typedef struct {
|
||||
* @param table_row DB table column
|
||||
* @return Access function
|
||||
*/
|
||||
/*@ null @*/ QofAccessFunc gnc_sql_get_getter( QofIdTypeConst obj_name, const GncSqlColumnTableEntry* table_row );
|
||||
/*@ null @*/
|
||||
QofAccessFunc gnc_sql_get_getter( QofIdTypeConst obj_name, const GncSqlColumnTableEntry* table_row );
|
||||
|
||||
/**
|
||||
* Adds a column name to a list. If the column type spans multiple columns,
|
||||
@@ -415,11 +434,11 @@ void gnc_sql_add_colname_to_list( const GncSqlColumnTableEntry* table_row, GList
|
||||
* @return TRUE if successful, FALSE if not
|
||||
*/
|
||||
gboolean gnc_sql_do_db_operation( GncSqlBackend* be,
|
||||
E_DB_OPERATION op,
|
||||
const gchar* table_name,
|
||||
QofIdTypeConst obj_name,
|
||||
gpointer pObject,
|
||||
const GncSqlColumnTableEntry* table );
|
||||
E_DB_OPERATION op,
|
||||
const gchar* table_name,
|
||||
QofIdTypeConst obj_name,
|
||||
gpointer pObject,
|
||||
const GncSqlColumnTableEntry* table );
|
||||
|
||||
/**
|
||||
* Executes an SQL SELECT statement and returns the result rows. If an error
|
||||
@@ -430,7 +449,8 @@ gboolean gnc_sql_do_db_operation( GncSqlBackend* be,
|
||||
* @param statement Statement
|
||||
* @return Results, or NULL if an error has occured
|
||||
*/
|
||||
/*@ null @*/ GncSqlResult* gnc_sql_execute_select_statement( GncSqlBackend* be, GncSqlStatement* statement );
|
||||
/*@ null @*/
|
||||
GncSqlResult* gnc_sql_execute_select_statement( GncSqlBackend* be, GncSqlStatement* statement );
|
||||
|
||||
/**
|
||||
* Executes an SQL SELECT statement from an SQL char string and returns the
|
||||
@@ -441,7 +461,8 @@ gboolean gnc_sql_do_db_operation( GncSqlBackend* be,
|
||||
* @param sql SQL SELECT string
|
||||
* @return Results, or NULL if an error has occured
|
||||
*/
|
||||
/*@ null @*/ GncSqlResult* gnc_sql_execute_select_sql( GncSqlBackend* be, const gchar* sql );
|
||||
/*@ null @*/
|
||||
GncSqlResult* gnc_sql_execute_select_sql( GncSqlBackend* be, const gchar* sql );
|
||||
|
||||
/**
|
||||
* Executes an SQL non-SELECT statement from an SQL char string.
|
||||
@@ -459,7 +480,8 @@ gint gnc_sql_execute_nonselect_sql( GncSqlBackend* be, const gchar* sql );
|
||||
* @param sql SQL char string
|
||||
* @return Statement
|
||||
*/
|
||||
/*@ null @*/ GncSqlStatement* gnc_sql_create_statement_from_sql( GncSqlBackend* be, const gchar* sql );
|
||||
/*@ null @*/
|
||||
GncSqlStatement* gnc_sql_create_statement_from_sql( GncSqlBackend* be, const gchar* sql );
|
||||
|
||||
/**
|
||||
* Loads a Gnucash object from the database.
|
||||
@@ -471,8 +493,8 @@ gint gnc_sql_execute_nonselect_sql( GncSqlBackend* be, const gchar* sql );
|
||||
* @param table DB table description
|
||||
*/
|
||||
void gnc_sql_load_object( const GncSqlBackend* be, GncSqlRow* row,
|
||||
/*@ null @*/ QofIdTypeConst obj_name, gpointer pObject,
|
||||
const GncSqlColumnTableEntry* table );
|
||||
/*@ null @*/ QofIdTypeConst obj_name, gpointer pObject,
|
||||
const GncSqlColumnTableEntry* table );
|
||||
|
||||
/**
|
||||
* Checks whether an object is in the database or not.
|
||||
@@ -485,9 +507,9 @@ void gnc_sql_load_object( const GncSqlBackend* be, GncSqlRow* row,
|
||||
* @return TRUE if the object is in the database, FALSE otherwise
|
||||
*/
|
||||
gboolean gnc_sql_object_is_it_in_db( GncSqlBackend* be,
|
||||
const gchar* table_name,
|
||||
QofIdTypeConst obj_name, const gpointer pObject,
|
||||
const GncSqlColumnTableEntry* table );
|
||||
const gchar* table_name,
|
||||
QofIdTypeConst obj_name, const gpointer pObject,
|
||||
const GncSqlColumnTableEntry* table );
|
||||
|
||||
/**
|
||||
* Returns the version number for a DB table.
|
||||
@@ -507,8 +529,8 @@ gint gnc_sql_get_table_version( const GncSqlBackend* be, const gchar* table_name
|
||||
* @return TRUE if successful, FALSE if unsuccessful
|
||||
*/
|
||||
gboolean gnc_sql_set_table_version( GncSqlBackend* be,
|
||||
const gchar* table_name,
|
||||
gint table_version );
|
||||
const gchar* table_name,
|
||||
gint table_version );
|
||||
|
||||
/**
|
||||
* Creates a table in the database
|
||||
@@ -520,9 +542,9 @@ gboolean gnc_sql_set_table_version( GncSqlBackend* be,
|
||||
* @return TRUE if successful, FALSE if unsuccessful
|
||||
*/
|
||||
gboolean gnc_sql_create_table( GncSqlBackend* be,
|
||||
const gchar* table_name,
|
||||
gint table_version,
|
||||
const GncSqlColumnTableEntry* col_table );
|
||||
const gchar* table_name,
|
||||
gint table_version,
|
||||
const GncSqlColumnTableEntry* col_table );
|
||||
|
||||
/**
|
||||
* Creates a temporary table in the database. A temporary table does not
|
||||
@@ -534,8 +556,8 @@ gboolean gnc_sql_create_table( GncSqlBackend* be,
|
||||
* @return TRUE if successful, FALSE if unsuccessful
|
||||
*/
|
||||
gboolean gnc_sql_create_temp_table( const GncSqlBackend* be,
|
||||
const gchar* table_name,
|
||||
const GncSqlColumnTableEntry* col_table );
|
||||
const gchar* table_name,
|
||||
const GncSqlColumnTableEntry* col_table );
|
||||
|
||||
/**
|
||||
* Creates an index in the database
|
||||
@@ -547,7 +569,7 @@ gboolean gnc_sql_create_temp_table( const GncSqlBackend* be,
|
||||
* @return TRUE if successful, FALSE if unsuccessful
|
||||
*/
|
||||
gboolean gnc_sql_create_index( const GncSqlBackend* be, const gchar* index_name,
|
||||
const gchar* table_name, const GncSqlColumnTableEntry* col_table );
|
||||
const gchar* table_name, const GncSqlColumnTableEntry* col_table );
|
||||
|
||||
/**
|
||||
* Loads the object guid from a database row. The table must have a column
|
||||
@@ -557,7 +579,8 @@ gboolean gnc_sql_create_index( const GncSqlBackend* be, const gchar* index_name,
|
||||
* @param row Database row
|
||||
* @return GUID
|
||||
*/
|
||||
/*@ dependent @*//*@ null @*/ const GUID* gnc_sql_load_guid( const GncSqlBackend* be, GncSqlRow* row );
|
||||
/*@ dependent @*//*@ null @*/
|
||||
const GUID* gnc_sql_load_guid( const GncSqlBackend* be, GncSqlRow* row );
|
||||
|
||||
/**
|
||||
* Loads the transaction guid from a database row. The table must have a column
|
||||
@@ -567,7 +590,8 @@ gboolean gnc_sql_create_index( const GncSqlBackend* be, const gchar* index_name,
|
||||
* @param row Database row
|
||||
* @return GUID
|
||||
*/
|
||||
/*@ dependent @*//*@ null @*/ const GUID* gnc_sql_load_tx_guid( const GncSqlBackend* be, GncSqlRow* row );
|
||||
/*@ dependent @*//*@ null @*/
|
||||
const GUID* gnc_sql_load_tx_guid( const GncSqlBackend* be, GncSqlRow* row );
|
||||
|
||||
/**
|
||||
* Creates a basic SELECT statement for a table.
|
||||
@@ -576,8 +600,9 @@ gboolean gnc_sql_create_index( const GncSqlBackend* be, const gchar* index_name,
|
||||
* @param table_name Table name
|
||||
* @return Statement
|
||||
*/
|
||||
/*@ null @*/ GncSqlStatement* gnc_sql_create_select_statement( GncSqlBackend* be,
|
||||
const gchar* table_name );
|
||||
/*@ null @*/
|
||||
GncSqlStatement* gnc_sql_create_select_statement( GncSqlBackend* be,
|
||||
const gchar* table_name );
|
||||
|
||||
/**
|
||||
* Registers a column handler for a new column type.
|
||||
@@ -597,8 +622,8 @@ void gnc_sql_register_col_type_handler( const gchar* colType, const GncSqlColumn
|
||||
* @param pList List
|
||||
*/
|
||||
void gnc_sql_add_gvalue_objectref_guid_to_slist( const GncSqlBackend* be,
|
||||
QofIdTypeConst obj_name, const gpointer pObject,
|
||||
const GncSqlColumnTableEntry* table_row, GSList** pList );
|
||||
QofIdTypeConst obj_name, const gpointer pObject,
|
||||
const GncSqlColumnTableEntry* table_row, GSList** pList );
|
||||
|
||||
/**
|
||||
* Adds a column info structure for an object reference GUID to the end of a
|
||||
@@ -609,7 +634,7 @@ void gnc_sql_add_gvalue_objectref_guid_to_slist( const GncSqlBackend* be,
|
||||
* @param pList List
|
||||
*/
|
||||
void gnc_sql_add_objectref_guid_col_info_to_list( const GncSqlBackend* be,
|
||||
const GncSqlColumnTableEntry* table_row, GList** pList );
|
||||
const GncSqlColumnTableEntry* table_row, GList** pList );
|
||||
|
||||
/**
|
||||
* Appends the ascii strings for a list of GUIDs to the end of an SQL string.
|
||||
@@ -629,8 +654,8 @@ guint gnc_sql_append_guid_list_to_sql( GString* str, GList* list, guint maxCount
|
||||
* @param pList List
|
||||
*/
|
||||
void gnc_sql_add_subtable_colnames_to_list( const GncSqlColumnTableEntry* table_row,
|
||||
const GncSqlColumnTableEntry* subtable,
|
||||
GList** pList );
|
||||
const GncSqlColumnTableEntry* subtable,
|
||||
GList** pList );
|
||||
|
||||
/**
|
||||
* Returns a string corresponding to the SQL representation of a GValue. The
|
||||
@@ -668,7 +693,7 @@ void gnc_sql_finalize_version_info( GncSqlBackend* be );
|
||||
* @return TRUE if successful, FALSE if not
|
||||
*/
|
||||
gboolean gnc_sql_commit_standard_item( GncSqlBackend* be, QofInstance* inst, const gchar* tableName,
|
||||
QofIdTypeConst obj_name, const GncSqlColumnTableEntry* col_table );
|
||||
QofIdTypeConst obj_name, const GncSqlColumnTableEntry* col_table );
|
||||
|
||||
/**
|
||||
* Gets an integer value (of any size) from a GValue.
|
||||
@@ -698,17 +723,19 @@ gchar* gnc_sql_convert_timespec_to_string( const GncSqlBackend* be, Timespec ts
|
||||
* @param col_table Column table
|
||||
*/
|
||||
void gnc_sql_upgrade_table( GncSqlBackend* be, const gchar* table_name,
|
||||
const GncSqlColumnTableEntry* col_table );
|
||||
const GncSqlColumnTableEntry* col_table );
|
||||
|
||||
void _retrieve_guid_( gpointer pObject, /*@ null @*/ gpointer pValue );
|
||||
|
||||
/*@ null @*/ gpointer gnc_sql_compile_query( QofBackend* pBEnd, QofQuery* pQuery );
|
||||
/*@ null @*/
|
||||
gpointer gnc_sql_compile_query( QofBackend* pBEnd, QofQuery* pQuery );
|
||||
void gnc_sql_free_query( QofBackend* pBEnd, gpointer pQuery );
|
||||
void gnc_sql_run_query( QofBackend* pBEnd, gpointer pQuery );
|
||||
|
||||
typedef struct {
|
||||
/*@ dependent @*/ GncSqlBackend* be;
|
||||
gboolean is_ok;
|
||||
typedef struct
|
||||
{
|
||||
/*@ dependent @*/ GncSqlBackend* be;
|
||||
gboolean is_ok;
|
||||
} write_objects_t;
|
||||
|
||||
#endif /* GNC_BACKEND_SQL_H_ */
|
||||
|
||||
@@ -35,8 +35,10 @@
|
||||
gboolean gnc_sql_recurrence_save( GncSqlBackend* be, const GUID* guid, const Recurrence* pRecurrence );
|
||||
void gnc_sql_recurrence_save_list( GncSqlBackend* be, const GUID* guid, GList* schedule );
|
||||
gboolean gnc_sql_recurrence_delete( GncSqlBackend* be, const GUID* guid );
|
||||
/*@ null @*/ Recurrence* gnc_sql_recurrence_load( GncSqlBackend* be, const GUID* guid );
|
||||
/*@ null @*/ GList* gnc_sql_recurrence_load_list( GncSqlBackend* be, const GUID* guid );
|
||||
/*@ null @*/
|
||||
Recurrence* gnc_sql_recurrence_load( GncSqlBackend* be, const GUID* guid );
|
||||
/*@ null @*/
|
||||
GList* gnc_sql_recurrence_load_list( GncSqlBackend* be, const GUID* guid );
|
||||
|
||||
void gnc_sql_init_recurrence_handler( void );
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
* @return TRUE if successful, FALSE if error
|
||||
*/
|
||||
gboolean gnc_sql_slots_save( GncSqlBackend* be, const GUID* guid,
|
||||
gboolean is_infant, KvpFrame* pFrame );
|
||||
gboolean is_infant, KvpFrame* pFrame );
|
||||
|
||||
/**
|
||||
* gnc_sql_slots_delete - Deletes slots for an object from the db.
|
||||
@@ -83,7 +83,7 @@ void gnc_sql_slots_load_for_list( GncSqlBackend* be, GList* list );
|
||||
typedef QofInstance* (*BookLookupFn)( const GUID* guid, const QofBook* book );
|
||||
|
||||
void gnc_sql_slots_load_for_sql_subquery( GncSqlBackend* be, const gchar* subquery,
|
||||
BookLookupFn lookup_fn );
|
||||
BookLookupFn lookup_fn );
|
||||
|
||||
void gnc_sql_init_slots_handler( void );
|
||||
|
||||
|
||||
@@ -66,11 +66,12 @@ void gnc_sql_transaction_load_tx_for_account( GncSqlBackend* be, Account* accoun
|
||||
*/
|
||||
void gnc_sql_transaction_load_all_tx( GncSqlBackend* be );
|
||||
|
||||
typedef struct {
|
||||
Account* acct;
|
||||
gnc_numeric balance;
|
||||
gnc_numeric cleared_balance;
|
||||
gnc_numeric reconciled_balance;
|
||||
typedef struct
|
||||
{
|
||||
Account* acct;
|
||||
gnc_numeric balance;
|
||||
gnc_numeric cleared_balance;
|
||||
gnc_numeric reconciled_balance;
|
||||
} acct_balances_t;
|
||||
|
||||
/**
|
||||
@@ -80,6 +81,7 @@ typedef struct {
|
||||
* @param be SQL backend
|
||||
* @return GSList of acct_balances_t structures
|
||||
*/
|
||||
/*@ null @*/ GSList* gnc_sql_get_account_balances_slist( GncSqlBackend* be );
|
||||
/*@ null @*/
|
||||
GSList* gnc_sql_get_account_balances_slist( GncSqlBackend* be );
|
||||
|
||||
#endif /* GNC_TRANSACTION_SQL_H_ */
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include "qof.h"
|
||||
#include "cashobjects.h"
|
||||
@@ -35,11 +35,11 @@ int main( int argc, char ** argv )
|
||||
{
|
||||
qof_init();
|
||||
cashobjects_register();
|
||||
gnc_sql_init( NULL );
|
||||
/* do_test(
|
||||
qof_load_backend_library ("../.libs/", GNC_LIB_NAME),
|
||||
" loading gnc-backend-gda GModule failed");
|
||||
*/
|
||||
gnc_sql_init( NULL );
|
||||
/* do_test(
|
||||
qof_load_backend_library ("../.libs/", GNC_LIB_NAME),
|
||||
" loading gnc-backend-gda GModule failed");
|
||||
*/
|
||||
print_test_results();
|
||||
qof_close();
|
||||
exit( get_rv() );
|
||||
|
||||
@@ -715,9 +715,11 @@ gnc_xml_be_write_to_file(FileBackend *fbe,
|
||||
tmp_name ? tmp_name : "(null)",
|
||||
strerror(errno) ? strerror(errno) : "");
|
||||
/* already in an error just flow on through */
|
||||
} else {
|
||||
/* Use a generic write error code */
|
||||
qof_backend_set_error(be, ERR_FILEIO_WRITE_ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use a generic write error code */
|
||||
qof_backend_set_error(be, ERR_FILEIO_WRITE_ERROR);
|
||||
}
|
||||
g_free(tmp_name);
|
||||
LEAVE("");
|
||||
|
||||
@@ -160,7 +160,7 @@ write_book_parts(FILE *out, QofBook *book)
|
||||
xmlFreeNode (domnode);
|
||||
|
||||
if (ferror(out) || fprintf(out, "\n") < 0)
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
|
||||
if (qof_book_get_slots(book))
|
||||
{
|
||||
@@ -172,7 +172,7 @@ write_book_parts(FILE *out, QofBook *book)
|
||||
xmlFreeNode(kvpnode);
|
||||
|
||||
if (ferror(out) || fprintf(out, "\n") < 0)
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -971,12 +971,12 @@ write_book(FILE *out, QofBook *book, sixtp_gdv2 *gd)
|
||||
qof_object_foreach_backend (GNC_FILE_BACKEND, write_counts_cb, &be_data);
|
||||
|
||||
if (ferror(out)
|
||||
|| !write_commodities(out, book, gd)
|
||||
|| !write_pricedb(out, book, gd)
|
||||
|| !write_accounts(out, book, gd)
|
||||
|| !write_transactions(out, book, gd)
|
||||
|| !write_template_transaction_data(out, book, gd)
|
||||
|| !write_schedXactions(out, book, gd))
|
||||
|| !write_commodities(out, book, gd)
|
||||
|| !write_pricedb(out, book, gd)
|
||||
|| !write_accounts(out, book, gd)
|
||||
|| !write_transactions(out, book, gd)
|
||||
|| !write_template_transaction_data(out, book, gd)
|
||||
|| !write_schedXactions(out, book, gd))
|
||||
|
||||
return FALSE;
|
||||
|
||||
@@ -1093,9 +1093,9 @@ write_transactions(FILE *out, QofBook *book, sixtp_gdv2 *gd)
|
||||
be_data.out = out;
|
||||
be_data.gd = gd;
|
||||
return 0 ==
|
||||
xaccAccountTreeForEachTransaction(gnc_book_get_root_account(book),
|
||||
xml_add_trn_data,
|
||||
(gpointer) &be_data);
|
||||
xaccAccountTreeForEachTransaction(gnc_book_get_root_account(book),
|
||||
xml_add_trn_data,
|
||||
(gpointer) &be_data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -1111,9 +1111,9 @@ write_template_transaction_data( FILE *out, QofBook *book, sixtp_gdv2 *gd )
|
||||
if ( gnc_account_n_descendants(ra) > 0 )
|
||||
{
|
||||
if (fprintf(out, "<%s>\n", TEMPLATE_TRANSACTION_TAG) < 0
|
||||
|| !write_account_tree(out, ra, gd)
|
||||
|| xaccAccountTreeForEachTransaction(ra, xml_add_trn_data, (gpointer)&be_data)
|
||||
|| fprintf(out, "</%s>\n", TEMPLATE_TRANSACTION_TAG) < 0)
|
||||
|| !write_account_tree(out, ra, gd)
|
||||
|| xaccAccountTreeForEachTransaction(ra, xml_add_trn_data, (gpointer)&be_data)
|
||||
|| fprintf(out, "</%s>\n", TEMPLATE_TRANSACTION_TAG) < 0)
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1195,23 +1195,23 @@ static gboolean
|
||||
write_v2_header (FILE *out)
|
||||
{
|
||||
if (fprintf(out, "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n") < 0
|
||||
|| fprintf(out, "<" GNC_V2_STRING) < 0
|
||||
|| fprintf(out, "<" GNC_V2_STRING) < 0
|
||||
|
||||
|| !gnc_xml2_write_namespace_decl (out, "gnc")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "act")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "book")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "cd")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "cmdty")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "price")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "slot")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "split")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "sx")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "trn")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "ts")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "fs")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "bgt")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "recurrence")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "lot"))
|
||||
|| !gnc_xml2_write_namespace_decl (out, "gnc")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "act")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "book")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "cd")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "cmdty")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "price")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "slot")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "split")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "sx")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "trn")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "ts")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "fs")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "bgt")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "recurrence")
|
||||
|| !gnc_xml2_write_namespace_decl (out, "lot"))
|
||||
|
||||
return FALSE;
|
||||
|
||||
@@ -1234,7 +1234,7 @@ gnc_book_write_to_xml_filehandle_v2(QofBook *book, FILE *out)
|
||||
if (!out) return FALSE;
|
||||
|
||||
if (!write_v2_header(out)
|
||||
|| !write_counts(out, "book", 1, NULL))
|
||||
|| !write_counts(out, "book", 1, NULL))
|
||||
return FALSE;
|
||||
|
||||
be = qof_book_get_backend(book);
|
||||
@@ -1250,7 +1250,7 @@ gnc_book_write_to_xml_filehandle_v2(QofBook *book, FILE *out)
|
||||
qof_book_get_collection(book, GNC_ID_BUDGET));
|
||||
|
||||
if (!write_book(out, book, gd)
|
||||
|| fprintf(out, "</" GNC_V2_STRING ">\n\n") < 0)
|
||||
|| fprintf(out, "</" GNC_V2_STRING ">\n\n") < 0)
|
||||
success = FALSE;
|
||||
|
||||
g_free(gd);
|
||||
@@ -1278,7 +1278,7 @@ gnc_book_write_accounts_to_xml_filehandle_v2(QofBackend *be, QofBook *book, FILE
|
||||
ncom = gnc_commodity_table_get_size(table);
|
||||
|
||||
if (!write_v2_header(out)
|
||||
|| !write_counts(out, "commodity", ncom, "account", nacc, NULL))
|
||||
|| !write_counts(out, "commodity", ncom, "account", nacc, NULL))
|
||||
return FALSE;
|
||||
|
||||
gd = gnc_sixtp_gdv2_new(book, TRUE, file_rw_feedback, be->percentage);
|
||||
@@ -1286,8 +1286,8 @@ gnc_book_write_accounts_to_xml_filehandle_v2(QofBackend *be, QofBook *book, FILE
|
||||
gd->counter.accounts_total = nacc;
|
||||
|
||||
if (!write_commodities(out, book, gd)
|
||||
|| !write_accounts(out, book, gd)
|
||||
|| fprintf(out, "</" GNC_V2_STRING ">\n\n") < 0)
|
||||
|| !write_accounts(out, book, gd)
|
||||
|| fprintf(out, "</" GNC_V2_STRING ">\n\n") < 0)
|
||||
success = FALSE;
|
||||
|
||||
g_free(gd);
|
||||
@@ -1511,8 +1511,8 @@ gnc_book_write_to_xml_file_v2(
|
||||
|
||||
/* Try to write as much as possible */
|
||||
if (!out
|
||||
|| !gnc_book_write_to_xml_filehandle_v2(book, out)
|
||||
|| !write_emacs_trailer(out))
|
||||
|| !gnc_book_write_to_xml_filehandle_v2(book, out)
|
||||
|| !write_emacs_trailer(out))
|
||||
success = FALSE;
|
||||
|
||||
/* Close the output stream */
|
||||
@@ -1545,8 +1545,8 @@ gnc_book_write_accounts_to_xml_file_v2(
|
||||
|
||||
/* Try to write as much as possible */
|
||||
if (!out
|
||||
|| !gnc_book_write_accounts_to_xml_filehandle_v2 (be, book, out)
|
||||
|| !write_emacs_trailer(out))
|
||||
|| !gnc_book_write_accounts_to_xml_filehandle_v2 (be, book, out)
|
||||
|| !write_emacs_trailer(out))
|
||||
success = FALSE;
|
||||
|
||||
/* Close the output stream */
|
||||
@@ -1554,7 +1554,8 @@ gnc_book_write_accounts_to_xml_file_v2(
|
||||
success = FALSE;
|
||||
|
||||
if (!success
|
||||
&& qof_backend_get_error(be) == ERR_BACKEND_NO_ERR) {
|
||||
&& qof_backend_get_error(be) == ERR_BACKEND_NO_ERR)
|
||||
{
|
||||
|
||||
/* Use a generic write error code */
|
||||
qof_backend_set_error(be, ERR_FILEIO_WRITE_ERROR);
|
||||
|
||||
@@ -81,11 +81,11 @@ gnc_print_unstable_message(void)
|
||||
if (!is_development_version) return;
|
||||
|
||||
g_print("\n\n%s%s%s%s%s\n%s%s\n\n",
|
||||
_("This is a development version. It may or may not work.\n"),
|
||||
_("Report bugs and other problems to gnucash-devel@gnucash.org.\n"),
|
||||
_("You can also lookup and file bug reports at http://bugzilla.gnome.org\n"),
|
||||
_("The last stable version was "), "GnuCash 2.2.9",
|
||||
_("The next stable version will be "), "GnuCash 2.4");
|
||||
_("This is a development version. It may or may not work.\n"),
|
||||
_("Report bugs and other problems to gnucash-devel@gnucash.org.\n"),
|
||||
_("You can also lookup and file bug reports at http://bugzilla.gnome.org\n"),
|
||||
_("The last stable version was "), "GnuCash 2.2.9",
|
||||
_("The next stable version will be "), "GnuCash 2.4");
|
||||
}
|
||||
|
||||
/* Priority of paths: The default is set at build time. It may be
|
||||
@@ -100,7 +100,7 @@ static void
|
||||
environment_override()
|
||||
{
|
||||
const char *path;
|
||||
|
||||
|
||||
if ((path = g_getenv("GNC_CONFIG_PATH")))
|
||||
config_path = g_strdup(path);
|
||||
if ((path = g_getenv("GNC_SHARE_PATH")))
|
||||
@@ -126,9 +126,11 @@ try_load_config_array(const gchar *fns[])
|
||||
gchar *filename;
|
||||
int i;
|
||||
|
||||
for (i = 0; fns[i]; i++) {
|
||||
for (i = 0; fns[i]; i++)
|
||||
{
|
||||
filename = gnc_build_dotgnucash_path(fns[i]);
|
||||
if (gfec_try_load(filename)) {
|
||||
if (gfec_try_load(filename))
|
||||
{
|
||||
g_free(filename);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -136,7 +138,7 @@ try_load_config_array(const gchar *fns[])
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
update_message(const gchar *msg)
|
||||
{
|
||||
@@ -164,14 +166,20 @@ load_user_config(void)
|
||||
{
|
||||
/* Don't continue adding to this list. When 2.0 rolls around bump
|
||||
the 1.4 (unnumbered) files off the list. */
|
||||
static const gchar *user_config_files[] = {
|
||||
"config-2.0.user", "config-1.8.user", "config-1.6.user",
|
||||
"config.user", NULL };
|
||||
static const gchar *auto_config_files[] = {
|
||||
static const gchar *user_config_files[] =
|
||||
{
|
||||
"config-2.0.user", "config-1.8.user", "config-1.6.user",
|
||||
"config.user", NULL
|
||||
};
|
||||
static const gchar *auto_config_files[] =
|
||||
{
|
||||
"config-2.0.auto", "config-1.8.auto", "config-1.6.auto",
|
||||
"config.auto", NULL};
|
||||
static const gchar *saved_report_files[] = {
|
||||
"saved-reports-2.4", "saved-reports-2.0", NULL};
|
||||
"config.auto", NULL
|
||||
};
|
||||
static const gchar *saved_report_files[] =
|
||||
{
|
||||
"saved-reports-2.4", "saved-reports-2.0", NULL
|
||||
};
|
||||
static const gchar *stylesheet_files[] = { "stylesheets-2.0", NULL};
|
||||
static int is_user_config_loaded = FALSE;
|
||||
|
||||
@@ -198,14 +206,14 @@ load_user_config(void)
|
||||
* with lots of '?v's and it doesn't allow us to describe the
|
||||
* [DATAFILE] argument in the usage. Weighing those factors, we're
|
||||
* just going to use popt directly.
|
||||
*
|
||||
*
|
||||
* Glib-2.6 introduced GOptionContext and GOptionGroup, which are
|
||||
* meant to replace popt usage. In Gnome-2.14, the popt usage is
|
||||
* offically deprecated, and the GNOME_PARAM_GOPTION_CONTEXT can be
|
||||
* used.
|
||||
*/
|
||||
|
||||
static void
|
||||
static void
|
||||
gnucash_command_line(int *argc, char **argv)
|
||||
{
|
||||
char *p;
|
||||
@@ -213,98 +221,126 @@ gnucash_command_line(int *argc, char **argv)
|
||||
char *namespace_regexp = NULL;
|
||||
GError *error = NULL;
|
||||
GOptionContext *context;
|
||||
GOptionEntry options[] = {
|
||||
{"version", 'v', 0, G_OPTION_ARG_NONE, &gnucash_show_version,
|
||||
_("Show GnuCash version"), NULL},
|
||||
GOptionEntry options[] =
|
||||
{
|
||||
{
|
||||
"version", 'v', 0, G_OPTION_ARG_NONE, &gnucash_show_version,
|
||||
_("Show GnuCash version"), NULL
|
||||
},
|
||||
|
||||
{"debug", '\0', 0, G_OPTION_ARG_NONE, &debugging,
|
||||
_("Enable debugging mode: increasing logging to provide deep detail."), NULL},
|
||||
{
|
||||
"debug", '\0', 0, G_OPTION_ARG_NONE, &debugging,
|
||||
_("Enable debugging mode: increasing logging to provide deep detail."), NULL
|
||||
},
|
||||
|
||||
{"extra", '\0', 0, G_OPTION_ARG_NONE, &extra,
|
||||
_("Enable extra/development/debugging features."), NULL},
|
||||
{
|
||||
"extra", '\0', 0, G_OPTION_ARG_NONE, &extra,
|
||||
_("Enable extra/development/debugging features."), NULL
|
||||
},
|
||||
|
||||
{"log", '\0', 0, G_OPTION_ARG_STRING_ARRAY, &log_flags,
|
||||
_("Log level overrides, of the form \"log.ger.path={debug,info,warn,crit,error}\""),
|
||||
NULL},
|
||||
{
|
||||
"log", '\0', 0, G_OPTION_ARG_STRING_ARRAY, &log_flags,
|
||||
_("Log level overrides, of the form \"log.ger.path={debug,info,warn,crit,error}\""),
|
||||
NULL
|
||||
},
|
||||
|
||||
{"logto", '\0', 0, G_OPTION_ARG_STRING, &log_to_filename,
|
||||
_("File to log into; defaults to \"/tmp/gnucash.trace\"; can be \"stderr\" or \"stdout\"."),
|
||||
NULL},
|
||||
{
|
||||
"logto", '\0', 0, G_OPTION_ARG_STRING, &log_to_filename,
|
||||
_("File to log into; defaults to \"/tmp/gnucash.trace\"; can be \"stderr\" or \"stdout\"."),
|
||||
NULL
|
||||
},
|
||||
|
||||
#if 0
|
||||
{"loglevel", '\0', 0, G_OPTION_ARG_INT, &loglevel,
|
||||
/* Translators: This is the command line option autohelp text; see popt(3) */
|
||||
_("Set the logging level from 0 (least) to 6 (most)"),
|
||||
/* Translators: Argument description for autohelp; see
|
||||
http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */
|
||||
_("LOGLEVEL")},
|
||||
{
|
||||
"loglevel", '\0', 0, G_OPTION_ARG_INT, &loglevel,
|
||||
/* Translators: This is the command line option autohelp text; see popt(3) */
|
||||
_("Set the logging level from 0 (least) to 6 (most)"),
|
||||
/* Translators: Argument description for autohelp; see
|
||||
http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */
|
||||
_("LOGLEVEL")
|
||||
},
|
||||
#endif // 0
|
||||
|
||||
{"nofile", '\0', 0, G_OPTION_ARG_NONE, &nofile,
|
||||
_("Do not load the last file opened"), NULL},
|
||||
{
|
||||
"nofile", '\0', 0, G_OPTION_ARG_NONE, &nofile,
|
||||
_("Do not load the last file opened"), NULL
|
||||
},
|
||||
|
||||
{"config-path", '\0', 0, G_OPTION_ARG_STRING, &config_path,
|
||||
_("Set configuration path"),
|
||||
/* Translators: Argument description for autohelp; see
|
||||
http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */
|
||||
_("CONFIGPATH")},
|
||||
{
|
||||
"config-path", '\0', 0, G_OPTION_ARG_STRING, &config_path,
|
||||
_("Set configuration path"),
|
||||
/* Translators: Argument description for autohelp; see
|
||||
http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */
|
||||
_("CONFIGPATH")
|
||||
},
|
||||
|
||||
{"share-path", '\0', 0, G_OPTION_ARG_STRING, &share_path,
|
||||
_("Set shared data file search path"),
|
||||
/* Translators: Argument description for autohelp; see
|
||||
http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */
|
||||
_("SHAREPATH")},
|
||||
{"doc-path", '\0', 0, G_OPTION_ARG_STRING, &help_path,
|
||||
_("Set the search path for documentation files"),
|
||||
/* Translators: Argument description for autohelp; see
|
||||
http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */
|
||||
_("DOCPATH")},
|
||||
{"gconf-path", '\0', 0, G_OPTION_ARG_STRING, &gconf_path,
|
||||
_("Set the prefix path for gconf queries"),
|
||||
/* Translators: Argument description for autohelp; see
|
||||
http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */
|
||||
_("GCONFPATH")},
|
||||
{"add-price-quotes", '\0', 0, G_OPTION_ARG_STRING, &add_quotes_file,
|
||||
_("Add price quotes to given GnuCash datafile"),
|
||||
/* Translators: Argument description for autohelp; see
|
||||
http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */
|
||||
_("FILE")},
|
||||
{"namespace", '\0', 0, G_OPTION_ARG_STRING, &namespace_regexp,
|
||||
_("Regular expression determining which namespace commodities will be retrieved"),
|
||||
/* Translators: Argument description for autohelp; see
|
||||
http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */
|
||||
_("REGEXP")},
|
||||
{
|
||||
"share-path", '\0', 0, G_OPTION_ARG_STRING, &share_path,
|
||||
_("Set shared data file search path"),
|
||||
/* Translators: Argument description for autohelp; see
|
||||
http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */
|
||||
_("SHAREPATH")
|
||||
},
|
||||
{
|
||||
"doc-path", '\0', 0, G_OPTION_ARG_STRING, &help_path,
|
||||
_("Set the search path for documentation files"),
|
||||
/* Translators: Argument description for autohelp; see
|
||||
http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */
|
||||
_("DOCPATH")
|
||||
},
|
||||
{
|
||||
"gconf-path", '\0', 0, G_OPTION_ARG_STRING, &gconf_path,
|
||||
_("Set the prefix path for gconf queries"),
|
||||
/* Translators: Argument description for autohelp; see
|
||||
http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */
|
||||
_("GCONFPATH")
|
||||
},
|
||||
{
|
||||
"add-price-quotes", '\0', 0, G_OPTION_ARG_STRING, &add_quotes_file,
|
||||
_("Add price quotes to given GnuCash datafile"),
|
||||
/* Translators: Argument description for autohelp; see
|
||||
http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */
|
||||
_("FILE")
|
||||
},
|
||||
{
|
||||
"namespace", '\0', 0, G_OPTION_ARG_STRING, &namespace_regexp,
|
||||
_("Regular expression determining which namespace commodities will be retrieved"),
|
||||
/* Translators: Argument description for autohelp; see
|
||||
http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */
|
||||
_("REGEXP")
|
||||
},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
/* Pretend that argv[0] is "gnucash" */
|
||||
if ((p = strstr(argv[0], "-bin"))) *p = '\0';
|
||||
if ((p = strstr(argv[0], "-bin"))) * p = '\0';
|
||||
|
||||
context = g_option_context_new (" [datafile]");
|
||||
g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
|
||||
g_option_context_add_group (context, gtk_get_option_group (FALSE));
|
||||
if (!g_option_context_parse (context, argc, &argv, &error))
|
||||
{
|
||||
g_warning("Error parsing command line arguments: [%s]; try `gnucash --help` for available options.", error->message);
|
||||
exit(1);
|
||||
g_warning("Error parsing command line arguments: [%s]; try `gnucash --help` for available options.", error->message);
|
||||
exit(1);
|
||||
}
|
||||
g_option_context_free (context);
|
||||
if (error)
|
||||
g_error_free(error);
|
||||
g_error_free(error);
|
||||
|
||||
if (*argc > 0)
|
||||
file_to_load = argv[1];
|
||||
file_to_load = argv[1];
|
||||
|
||||
if (gnucash_show_version) {
|
||||
if (gnucash_show_version)
|
||||
{
|
||||
if (is_development_version)
|
||||
{
|
||||
/* Translators: %s is the version number */
|
||||
g_print(_("GnuCash %s development version"), VERSION);
|
||||
/* Translators: %s is the version number */
|
||||
g_print(_("GnuCash %s development version"), VERSION);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Translators: %s is the version number */
|
||||
g_print(_("GnuCash %s"), VERSION);
|
||||
/* Translators: %s is the version number */
|
||||
g_print(_("GnuCash %s"), VERSION);
|
||||
}
|
||||
g_print("\n");
|
||||
/* Translators: 1st %s is the build date; 2nd %s is the SVN
|
||||
@@ -326,11 +362,13 @@ static void
|
||||
load_gnucash_modules()
|
||||
{
|
||||
int i, len;
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
gchar * name;
|
||||
int version;
|
||||
gboolean optional;
|
||||
} modules[] = {
|
||||
} modules[] =
|
||||
{
|
||||
{ "gnucash/app-utils", 0, FALSE },
|
||||
{ "gnucash/engine", 0, FALSE },
|
||||
{ "gnucash/register/ledger-core", 0, FALSE },
|
||||
@@ -350,17 +388,19 @@ load_gnucash_modules()
|
||||
{ "gnucash/report/report-gnome", 0, FALSE },
|
||||
{ "gnucash/business-gnome", 0, TRUE }
|
||||
};
|
||||
|
||||
|
||||
/* module initializations go here */
|
||||
len = sizeof(modules) / sizeof(*modules);
|
||||
for (i = 0; i < len; i++) {
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
gnc_update_splash_screen(modules[i].name, GNC_SPLASH_PERCENTAGE_UNKNOWN);
|
||||
if (modules[i].optional)
|
||||
gnc_module_load_optional(modules[i].name, modules[i].version);
|
||||
else
|
||||
gnc_module_load(modules[i].name, modules[i].version);
|
||||
}
|
||||
if (!gnc_engine_is_initialized()) {
|
||||
if (!gnc_engine_is_initialized())
|
||||
{
|
||||
/* On Windows this check used to fail anyway, see
|
||||
* https://lists.gnucash.org/pipermail/gnucash-devel/2006-September/018529.html
|
||||
* but more recently it seems to work as expected
|
||||
@@ -377,7 +417,7 @@ inner_main_add_price_quotes(void *closure, int argc, char **argv)
|
||||
QofSession *session = NULL;
|
||||
|
||||
scm_c_eval_string("(debug-set! stack 200000)");
|
||||
|
||||
|
||||
mod = scm_c_resolve_module("gnucash price-quotes");
|
||||
scm_set_current_module(mod);
|
||||
|
||||
@@ -386,9 +426,10 @@ inner_main_add_price_quotes(void *closure, int argc, char **argv)
|
||||
qof_event_suspend();
|
||||
scm_c_eval_string("(gnc:price-quotes-install-sources)");
|
||||
|
||||
if (!gnc_quote_source_fq_installed()) {
|
||||
if (!gnc_quote_source_fq_installed())
|
||||
{
|
||||
g_print("%s", _("No quotes retrieved. Finance::Quote isn't "
|
||||
"installed properly.\n"));
|
||||
"installed properly.\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -409,7 +450,8 @@ inner_main_add_price_quotes(void *closure, int argc, char **argv)
|
||||
if (qof_session_get_error(session) != ERR_BACKEND_NO_ERR) goto fail;
|
||||
|
||||
qof_session_destroy(session);
|
||||
if (!scm_is_true(scm_result)) {
|
||||
if (!scm_is_true(scm_result))
|
||||
{
|
||||
g_warning("Failed to add quotes to %s.", add_quotes_file);
|
||||
goto fail;
|
||||
}
|
||||
@@ -417,7 +459,7 @@ inner_main_add_price_quotes(void *closure, int argc, char **argv)
|
||||
qof_event_resume();
|
||||
gnc_shutdown(0);
|
||||
return;
|
||||
fail:
|
||||
fail:
|
||||
if (session && qof_session_get_error(session) != ERR_BACKEND_NO_ERR)
|
||||
g_warning("Session Error: %s", qof_session_get_error_message(session));
|
||||
qof_event_resume();
|
||||
@@ -441,7 +483,7 @@ inner_main (void *closure, int argc, char **argv)
|
||||
GError *error = NULL;
|
||||
|
||||
scm_c_eval_string("(debug-set! stack 200000)");
|
||||
|
||||
|
||||
main_mod = scm_c_resolve_module("gnucash main");
|
||||
scm_set_current_module(main_mod);
|
||||
|
||||
@@ -469,15 +511,16 @@ inner_main (void *closure, int argc, char **argv)
|
||||
/* Install Price Quote Sources */
|
||||
gnc_update_splash_screen(_("Checking Finance::Quote..."), GNC_SPLASH_PERCENTAGE_UNKNOWN);
|
||||
scm_c_use_module("gnucash price-quotes");
|
||||
scm_c_eval_string("(gnc:price-quotes-install-sources)");
|
||||
scm_c_eval_string("(gnc:price-quotes-install-sources)");
|
||||
|
||||
gnc_hook_run(HOOK_STARTUP, NULL);
|
||||
|
||||
if (!nofile && (fn = get_file_to_load())) {
|
||||
|
||||
if (!nofile && (fn = get_file_to_load()))
|
||||
{
|
||||
gnc_update_splash_screen(_("Loading data..."), GNC_SPLASH_PERCENTAGE_UNKNOWN);
|
||||
gnc_file_open_file(fn);
|
||||
g_free(fn);
|
||||
}
|
||||
}
|
||||
else if (gnc_gconf_get_bool("dialogs/new_user", "first_startup", &error)
|
||||
&& !error)
|
||||
{
|
||||
@@ -500,62 +543,62 @@ inner_main (void *closure, int argc, char **argv)
|
||||
static void
|
||||
gnc_log_init()
|
||||
{
|
||||
if (log_to_filename != NULL)
|
||||
{
|
||||
qof_log_init_filename_special(log_to_filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* initialize logging to our file. */
|
||||
gchar *tracefilename;
|
||||
tracefilename = g_build_filename(g_get_tmp_dir(), "gnucash.trace",
|
||||
(gchar *)NULL);
|
||||
qof_log_init_filename(tracefilename);
|
||||
g_free(tracefilename);
|
||||
}
|
||||
if (log_to_filename != NULL)
|
||||
{
|
||||
qof_log_init_filename_special(log_to_filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* initialize logging to our file. */
|
||||
gchar *tracefilename;
|
||||
tracefilename = g_build_filename(g_get_tmp_dir(), "gnucash.trace",
|
||||
(gchar *)NULL);
|
||||
qof_log_init_filename(tracefilename);
|
||||
g_free(tracefilename);
|
||||
}
|
||||
|
||||
// set a reasonable default.
|
||||
qof_log_set_default(QOF_LOG_WARNING);
|
||||
// set a reasonable default.
|
||||
qof_log_set_default(QOF_LOG_WARNING);
|
||||
|
||||
gnc_log_default();
|
||||
gnc_log_default();
|
||||
|
||||
if (gnc_is_debugging())
|
||||
{
|
||||
qof_log_set_level("", QOF_LOG_INFO);
|
||||
qof_log_set_level("qof", QOF_LOG_INFO);
|
||||
qof_log_set_level("gnc", QOF_LOG_INFO);
|
||||
}
|
||||
if (gnc_is_debugging())
|
||||
{
|
||||
qof_log_set_level("", QOF_LOG_INFO);
|
||||
qof_log_set_level("qof", QOF_LOG_INFO);
|
||||
qof_log_set_level("gnc", QOF_LOG_INFO);
|
||||
}
|
||||
|
||||
{
|
||||
gchar *log_config_filename;
|
||||
log_config_filename = gnc_build_dotgnucash_path("log.conf");
|
||||
if (g_file_test(log_config_filename, G_FILE_TEST_EXISTS))
|
||||
qof_log_parse_log_config(log_config_filename);
|
||||
g_free(log_config_filename);
|
||||
}
|
||||
{
|
||||
gchar *log_config_filename;
|
||||
log_config_filename = gnc_build_dotgnucash_path("log.conf");
|
||||
if (g_file_test(log_config_filename, G_FILE_TEST_EXISTS))
|
||||
qof_log_parse_log_config(log_config_filename);
|
||||
g_free(log_config_filename);
|
||||
}
|
||||
|
||||
if (log_flags != NULL)
|
||||
{
|
||||
int i = 0;
|
||||
for (; log_flags[i] != NULL; i++)
|
||||
{
|
||||
QofLogLevel level;
|
||||
gchar **parts = NULL;
|
||||
if (log_flags != NULL)
|
||||
{
|
||||
int i = 0;
|
||||
for (; log_flags[i] != NULL; i++)
|
||||
{
|
||||
QofLogLevel level;
|
||||
gchar **parts = NULL;
|
||||
|
||||
gchar *log_opt = log_flags[i];
|
||||
parts = g_strsplit(log_opt, "=", 2);
|
||||
if (parts == NULL || parts[0] == NULL || parts[1] == NULL)
|
||||
{
|
||||
g_warning("string [%s] not parseable", log_opt);
|
||||
continue;
|
||||
}
|
||||
gchar *log_opt = log_flags[i];
|
||||
parts = g_strsplit(log_opt, "=", 2);
|
||||
if (parts == NULL || parts[0] == NULL || parts[1] == NULL)
|
||||
{
|
||||
g_warning("string [%s] not parseable", log_opt);
|
||||
continue;
|
||||
}
|
||||
|
||||
level = qof_log_level_from_string(parts[1]);
|
||||
qof_log_set_level(parts[0], level);
|
||||
g_strfreev(parts);
|
||||
}
|
||||
}
|
||||
}
|
||||
level = qof_log_level_from_string(parts[1]);
|
||||
qof_log_set_level(parts[0], level);
|
||||
g_strfreev(parts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char ** argv)
|
||||
@@ -568,7 +611,8 @@ main(int argc, char ** argv)
|
||||
#ifdef ENABLE_BINRELOC
|
||||
{
|
||||
GError *binreloc_error = NULL;
|
||||
if (!gbr_init(&binreloc_error)) {
|
||||
if (!gbr_init(&binreloc_error))
|
||||
{
|
||||
g_print("main: Error on gbr_init: %s\n", binreloc_error->message);
|
||||
g_error_free(binreloc_error);
|
||||
}
|
||||
@@ -591,7 +635,7 @@ main(int argc, char ** argv)
|
||||
|
||||
qof_log_init();
|
||||
qof_log_set_default(QOF_LOG_INFO);
|
||||
|
||||
|
||||
environment_override();
|
||||
gnucash_command_line(&argc, argv);
|
||||
gnc_print_unstable_message();
|
||||
@@ -599,7 +643,8 @@ main(int argc, char ** argv)
|
||||
|
||||
gnc_module_system_init();
|
||||
|
||||
if (add_quotes_file) {
|
||||
if (add_quotes_file)
|
||||
{
|
||||
gchar *prefix = gnc_path_get_prefix ();
|
||||
gchar *pkgsysconfdir = gnc_path_get_pkgsysconfdir ();
|
||||
gchar *pkgdatadir = gnc_path_get_pkgdatadir ();
|
||||
@@ -609,11 +654,11 @@ main(int argc, char ** argv)
|
||||
gnome_program_init(
|
||||
"gnucash", VERSION, LIBGNOME_MODULE,
|
||||
argc, argv,
|
||||
GNOME_PARAM_APP_PREFIX, prefix,
|
||||
GNOME_PARAM_APP_SYSCONFDIR, pkgsysconfdir,
|
||||
GNOME_PARAM_APP_DATADIR, pkgdatadir,
|
||||
GNOME_PARAM_APP_LIBDIR, pkglibdir,
|
||||
GNOME_PARAM_NONE);
|
||||
GNOME_PARAM_APP_PREFIX, prefix,
|
||||
GNOME_PARAM_APP_SYSCONFDIR, pkgsysconfdir,
|
||||
GNOME_PARAM_APP_DATADIR, pkgdatadir,
|
||||
GNOME_PARAM_APP_LIBDIR, pkglibdir,
|
||||
GNOME_PARAM_NONE);
|
||||
g_free (prefix);
|
||||
g_free (pkgsysconfdir);
|
||||
g_free (pkgdatadir);
|
||||
|
||||
@@ -58,47 +58,49 @@ int libgncmod_business_core_gnc_module_age = 0;
|
||||
char *
|
||||
libgncmod_business_core_gnc_module_path(void)
|
||||
{
|
||||
return g_strdup("gnucash/business-core");
|
||||
return g_strdup("gnucash/business-core");
|
||||
}
|
||||
|
||||
char *
|
||||
libgncmod_business_core_gnc_module_description(void)
|
||||
{
|
||||
return g_strdup("The GnuCash business core");
|
||||
return g_strdup("The GnuCash business core");
|
||||
}
|
||||
|
||||
int
|
||||
libgncmod_business_core_gnc_module_init(int refcount)
|
||||
{
|
||||
/* load the engine (we depend on it) */
|
||||
if(!gnc_module_load("gnucash/engine", 0)) {
|
||||
return FALSE;
|
||||
}
|
||||
/* load the engine (we depend on it) */
|
||||
if (!gnc_module_load("gnucash/engine", 0))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(refcount == 0)
|
||||
{
|
||||
/* initialize known types */
|
||||
gncInvoiceRegister ();
|
||||
gncJobRegister ();
|
||||
gncBillTermRegister ();
|
||||
gncCustomerRegister ();
|
||||
gncAddressRegister ();
|
||||
gncEmployeeRegister ();
|
||||
gncEntryRegister ();
|
||||
gncOrderRegister ();
|
||||
gncOwnerRegister ();
|
||||
gncTaxTableRegister ();
|
||||
gncVendorRegister ();
|
||||
}
|
||||
if (refcount == 0)
|
||||
{
|
||||
/* initialize known types */
|
||||
gncInvoiceRegister ();
|
||||
gncJobRegister ();
|
||||
gncBillTermRegister ();
|
||||
gncCustomerRegister ();
|
||||
gncAddressRegister ();
|
||||
gncEmployeeRegister ();
|
||||
gncEntryRegister ();
|
||||
gncOrderRegister ();
|
||||
gncOwnerRegister ();
|
||||
gncTaxTableRegister ();
|
||||
gncVendorRegister ();
|
||||
}
|
||||
|
||||
scm_init_sw_business_core_module();
|
||||
scm_c_eval_string("(use-modules (sw_business_core))");
|
||||
scm_c_eval_string("(use-modules (gnucash business-core))");
|
||||
scm_init_sw_business_core_module();
|
||||
scm_c_eval_string("(use-modules (sw_business_core))");
|
||||
scm_c_eval_string("(use-modules (gnucash business-core))");
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
libgncmod_business_core_gnc_module_end(int refcount) {
|
||||
return TRUE;
|
||||
libgncmod_business_core_gnc_module_end(int refcount)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -78,12 +78,16 @@ libgncmod_business_backend_sql_gnc_module_description(void)
|
||||
int
|
||||
libgncmod_business_backend_sql_gnc_module_init(int refcount)
|
||||
{
|
||||
if(!gnc_engine_is_initialized()) { return FALSE; }
|
||||
if (!gnc_engine_is_initialized())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bus_core = gnc_module_load( "gnucash/business-core", 0 );
|
||||
if( !bus_core ) return FALSE;
|
||||
if ( !bus_core ) return FALSE;
|
||||
|
||||
if( refcount == 0 ) {
|
||||
if ( refcount == 0 )
|
||||
{
|
||||
/* Initialize our pointers into the backend subsystem */
|
||||
gnc_address_sql_initialize();
|
||||
gnc_billterm_sql_initialize();
|
||||
@@ -93,8 +97,8 @@ libgncmod_business_backend_sql_gnc_module_init(int refcount)
|
||||
gnc_invoice_sql_initialize();
|
||||
gnc_job_sql_initialize();
|
||||
gnc_order_sql_initialize();
|
||||
gnc_owner_sql_initialize();
|
||||
gnc_taxtable_sql_initialize();
|
||||
gnc_owner_sql_initialize();
|
||||
gnc_taxtable_sql_initialize();
|
||||
gnc_vendor_sql_initialize();
|
||||
}
|
||||
|
||||
@@ -106,11 +110,13 @@ libgncmod_business_backend_sql_gnc_module_end(int refcount)
|
||||
{
|
||||
int unload = TRUE;
|
||||
|
||||
if( bus_core ) {
|
||||
if ( bus_core )
|
||||
{
|
||||
unload = gnc_module_unload( bus_core );
|
||||
}
|
||||
}
|
||||
|
||||
if( refcount == 0 ) {
|
||||
if ( refcount == 0 )
|
||||
{
|
||||
bus_core = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,53 +60,58 @@ static GNCModule file;
|
||||
char *
|
||||
libgncmod_business_backend_xml_gnc_module_path(void)
|
||||
{
|
||||
return g_strdup("gnucash/business-core-xml");
|
||||
return g_strdup("gnucash/business-core-xml");
|
||||
}
|
||||
|
||||
char *
|
||||
libgncmod_business_backend_xml_gnc_module_description(void)
|
||||
{
|
||||
return g_strdup("The XML (v2) parsers for GnuCash business objects");
|
||||
return g_strdup("The XML (v2) parsers for GnuCash business objects");
|
||||
}
|
||||
|
||||
int
|
||||
libgncmod_business_backend_xml_gnc_module_init(int refcount)
|
||||
{
|
||||
if(!gnc_engine_is_initialized()) { return FALSE; }
|
||||
if (!gnc_engine_is_initialized())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bus_core = gnc_module_load("gnucash/business-core", 0);
|
||||
if(!bus_core) return FALSE;
|
||||
bus_core = gnc_module_load("gnucash/business-core", 0);
|
||||
if (!bus_core) return FALSE;
|
||||
|
||||
if (refcount == 0) {
|
||||
/* Initialize our pointers into the backend subsystem */
|
||||
gnc_address_xml_initialize ();
|
||||
gnc_billterm_xml_initialize ();
|
||||
gnc_customer_xml_initialize ();
|
||||
gnc_employee_xml_initialize ();
|
||||
gnc_entry_xml_initialize ();
|
||||
gnc_invoice_xml_initialize ();
|
||||
gnc_job_xml_initialize ();
|
||||
gnc_order_xml_initialize ();
|
||||
gnc_owner_xml_initialize ();
|
||||
gnc_taxtable_xml_initialize ();
|
||||
gnc_vendor_xml_initialize ();
|
||||
}
|
||||
if (refcount == 0)
|
||||
{
|
||||
/* Initialize our pointers into the backend subsystem */
|
||||
gnc_address_xml_initialize ();
|
||||
gnc_billterm_xml_initialize ();
|
||||
gnc_customer_xml_initialize ();
|
||||
gnc_employee_xml_initialize ();
|
||||
gnc_entry_xml_initialize ();
|
||||
gnc_invoice_xml_initialize ();
|
||||
gnc_job_xml_initialize ();
|
||||
gnc_order_xml_initialize ();
|
||||
gnc_owner_xml_initialize ();
|
||||
gnc_taxtable_xml_initialize ();
|
||||
gnc_vendor_xml_initialize ();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
libgncmod_business_backend_xml_gnc_module_end(int refcount)
|
||||
{
|
||||
int unload = TRUE;
|
||||
int unload = TRUE;
|
||||
|
||||
if (bus_core)
|
||||
unload = gnc_module_unload(bus_core);
|
||||
if (bus_core)
|
||||
unload = gnc_module_unload(bus_core);
|
||||
|
||||
if (refcount == 0) {
|
||||
bus_core = NULL;
|
||||
file = NULL;
|
||||
}
|
||||
if (refcount == 0)
|
||||
{
|
||||
bus_core = NULL;
|
||||
file = NULL;
|
||||
}
|
||||
|
||||
return unload;
|
||||
return unload;
|
||||
}
|
||||
|
||||
@@ -63,82 +63,89 @@ int libgncmod_business_gnome_gnc_module_age = 0;
|
||||
char *
|
||||
libgncmod_business_gnome_gnc_module_path(void)
|
||||
{
|
||||
return g_strdup("gnucash/business-gnome");
|
||||
return g_strdup("gnucash/business-gnome");
|
||||
}
|
||||
|
||||
char *
|
||||
libgncmod_business_gnome_gnc_module_description(void)
|
||||
{
|
||||
return g_strdup("The GnuCash business module GNOME UI");
|
||||
return g_strdup("The GnuCash business module GNOME UI");
|
||||
}
|
||||
|
||||
int
|
||||
libgncmod_business_gnome_gnc_module_init(int refcount)
|
||||
{
|
||||
/* load business-core: we depend on it -- and it depends on the engine */
|
||||
if (!gnc_module_load ("gnucash/business-core", 0)) {
|
||||
return FALSE;
|
||||
}
|
||||
/* We also depend on app-utils, gnome-utils, and gnome-search modules */
|
||||
if (!gnc_module_load ("gnucash/app-utils", 0)) {
|
||||
return FALSE;
|
||||
}
|
||||
if (!gnc_module_load ("gnucash/gnome-utils", 0)) {
|
||||
return FALSE;
|
||||
}
|
||||
if (!gnc_module_load ("gnucash/gnome-search", 0)) {
|
||||
return FALSE;
|
||||
}
|
||||
if (!gnc_module_load ("gnucash/report/report-gnome", 0)) {
|
||||
return FALSE;
|
||||
}
|
||||
// if (!libgncmod_business_gnome_gnc_module_load ("gnucash/report/standard-reports", 0)) {
|
||||
// return FALSE;
|
||||
// }
|
||||
/* load business-core: we depend on it -- and it depends on the engine */
|
||||
if (!gnc_module_load ("gnucash/business-core", 0))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
/* We also depend on app-utils, gnome-utils, and gnome-search modules */
|
||||
if (!gnc_module_load ("gnucash/app-utils", 0))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!gnc_module_load ("gnucash/gnome-utils", 0))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!gnc_module_load ("gnucash/gnome-search", 0))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!gnc_module_load ("gnucash/report/report-gnome", 0))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
// if (!libgncmod_business_gnome_gnc_module_load ("gnucash/report/standard-reports", 0)) {
|
||||
// return FALSE;
|
||||
// }
|
||||
|
||||
scm_c_eval_string("(use-modules (gnucash business-gnome))");
|
||||
scm_c_eval_string("(use-modules (gnucash report business-reports))");
|
||||
scm_c_eval_string("(use-modules (gnucash business-gnome))");
|
||||
scm_c_eval_string("(use-modules (gnucash report business-reports))");
|
||||
|
||||
// temp code until gnc:url-type is wrapped
|
||||
/*
|
||||
{
|
||||
SCM wct_gnc_url_type = scm_c_eval_string("<gnc:url-type>");
|
||||
SCM tmp;
|
||||
// temp code until gnc:url-type is wrapped
|
||||
/*
|
||||
{
|
||||
SCM wct_gnc_url_type = scm_c_eval_string("<gnc:url-type>");
|
||||
SCM tmp;
|
||||
|
||||
tmp = gw_wcp_assimilate_ptr(GNC_CUSTOMER_MODULE_NAME, wct_gnc_url_type);
|
||||
scm_c_define("gnc:url-type-customer", tmp);
|
||||
tmp = gw_wcp_assimilate_ptr(GNC_VENDOR_MODULE_NAME, wct_gnc_url_type);
|
||||
scm_c_define("gnc:url-type-vendor", tmp);
|
||||
tmp = gw_wcp_assimilate_ptr(GNC_EMPLOYEE_MODULE_NAME, wct_gnc_url_type);
|
||||
scm_c_define("gnc:url-type-employee", tmp);
|
||||
tmp = gw_wcp_assimilate_ptr(GNC_INVOICE_MODULE_NAME, wct_gnc_url_type);
|
||||
scm_c_define("gnc:url-type-invoice", tmp);
|
||||
tmp = gw_wcp_assimilate_ptr(URL_TYPE_OWNERREPORT, wct_gnc_url_type);
|
||||
scm_c_define("gnc:url-type-ownerreport", tmp);
|
||||
}
|
||||
*/
|
||||
tmp = gw_wcp_assimilate_ptr(GNC_CUSTOMER_MODULE_NAME, wct_gnc_url_type);
|
||||
scm_c_define("gnc:url-type-customer", tmp);
|
||||
tmp = gw_wcp_assimilate_ptr(GNC_VENDOR_MODULE_NAME, wct_gnc_url_type);
|
||||
scm_c_define("gnc:url-type-vendor", tmp);
|
||||
tmp = gw_wcp_assimilate_ptr(GNC_EMPLOYEE_MODULE_NAME, wct_gnc_url_type);
|
||||
scm_c_define("gnc:url-type-employee", tmp);
|
||||
tmp = gw_wcp_assimilate_ptr(GNC_INVOICE_MODULE_NAME, wct_gnc_url_type);
|
||||
scm_c_define("gnc:url-type-invoice", tmp);
|
||||
tmp = gw_wcp_assimilate_ptr(URL_TYPE_OWNERREPORT, wct_gnc_url_type);
|
||||
scm_c_define("gnc:url-type-ownerreport", tmp);
|
||||
}
|
||||
*/
|
||||
|
||||
if (refcount == 0) {
|
||||
/* Register the Owner search type */
|
||||
gnc_search_core_register_type (GNC_OWNER_MODULE_NAME,
|
||||
(GNCSearchCoreNew) gnc_search_owner_new);
|
||||
gnc_business_urls_initialize ();
|
||||
gnc_business_options_gnome_initialize ();
|
||||
if (refcount == 0)
|
||||
{
|
||||
/* Register the Owner search type */
|
||||
gnc_search_core_register_type (GNC_OWNER_MODULE_NAME,
|
||||
(GNCSearchCoreNew) gnc_search_owner_new);
|
||||
gnc_business_urls_initialize ();
|
||||
gnc_business_options_gnome_initialize ();
|
||||
|
||||
gnc_plugin_manager_add_plugin (gnc_plugin_manager_get (),
|
||||
gnc_plugin_business_new ());
|
||||
gnc_plugin_manager_add_plugin (gnc_plugin_manager_get (),
|
||||
gnc_plugin_business_new ());
|
||||
|
||||
gnc_hook_add_dangler(HOOK_BOOK_OPENED,
|
||||
(GFunc)gnc_invoice_remind_bills_due_cb, NULL);
|
||||
gnc_hook_add_dangler(HOOK_BOOK_OPENED,
|
||||
(GFunc)gnc_invoice_remind_bills_due_cb, NULL);
|
||||
|
||||
gnc_preferences_add_page("businessprefs.glade", "business_prefs",
|
||||
_("Business"));
|
||||
}
|
||||
gnc_preferences_add_page("businessprefs.glade", "business_prefs",
|
||||
_("Business"));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
libgncmod_business_gnome_gnc_module_end(int refcount) {
|
||||
return TRUE;
|
||||
libgncmod_business_gnome_gnc_module_end(int refcount)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -43,39 +43,42 @@ int libgncmod_business_utils_gnc_module_age = 0;
|
||||
char *
|
||||
libgncmod_business_utils_gnc_module_path(void)
|
||||
{
|
||||
return g_strdup("gnucash/business-utils");
|
||||
return g_strdup("gnucash/business-utils");
|
||||
}
|
||||
|
||||
char *
|
||||
libgncmod_business_utils_gnc_module_description(void)
|
||||
{
|
||||
return g_strdup("The GnuCash business utilities module");
|
||||
return g_strdup("The GnuCash business utilities module");
|
||||
}
|
||||
|
||||
int
|
||||
libgncmod_business_utils_gnc_module_init(int refcount)
|
||||
{
|
||||
/* load the business-core (we depend on it) */
|
||||
if (!gnc_module_load("gnucash/business-core", 0)) {
|
||||
return FALSE;
|
||||
}
|
||||
/* load the business-core (we depend on it) */
|
||||
if (!gnc_module_load("gnucash/business-core", 0))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Load the application utils.. */
|
||||
if (!gnc_module_load("gnucash/app-utils", 0)) {
|
||||
return FALSE;
|
||||
}
|
||||
/* Load the application utils.. */
|
||||
if (!gnc_module_load("gnucash/app-utils", 0))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(refcount == 0)
|
||||
{
|
||||
/* initialize known types */
|
||||
}
|
||||
if (refcount == 0)
|
||||
{
|
||||
/* initialize known types */
|
||||
}
|
||||
|
||||
scm_c_eval_string("(use-modules (gnucash business-utils))");
|
||||
scm_c_eval_string("(use-modules (gnucash business-utils))");
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
libgncmod_business_utils_gnc_module_end(int refcount) {
|
||||
return TRUE;
|
||||
libgncmod_business_utils_gnc_module_end(int refcount)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -44,37 +44,41 @@ int libgncmod_dialog_tax_table_gnc_module_age = 0;
|
||||
char *
|
||||
libgncmod_dialog_tax_table_gnc_module_path(void)
|
||||
{
|
||||
return g_strdup("gnucash/dialog-tax-table");
|
||||
return g_strdup("gnucash/dialog-tax-table");
|
||||
}
|
||||
|
||||
char *
|
||||
libgncmod_dialog_tax_table_gnc_module_description(void)
|
||||
{
|
||||
return g_strdup("The GnuCash tax-table GNOME UI module");
|
||||
return g_strdup("The GnuCash tax-table GNOME UI module");
|
||||
}
|
||||
|
||||
int
|
||||
libgncmod_dialog_tax_table_gnc_module_init(int refcount)
|
||||
{
|
||||
/* load business-core: we depend on it -- and it depends on the engine */
|
||||
if (!gnc_module_load ("gnucash/business-core", 0)) {
|
||||
return FALSE;
|
||||
}
|
||||
/* We also depend on app-utils and gnome-utils modules */
|
||||
if (!gnc_module_load ("gnucash/app-utils", 0)) {
|
||||
return FALSE;
|
||||
}
|
||||
if (!gnc_module_load ("gnucash/gnome-utils", 0)) {
|
||||
return FALSE;
|
||||
}
|
||||
/* load business-core: we depend on it -- and it depends on the engine */
|
||||
if (!gnc_module_load ("gnucash/business-core", 0))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
/* We also depend on app-utils and gnome-utils modules */
|
||||
if (!gnc_module_load ("gnucash/app-utils", 0))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!gnc_module_load ("gnucash/gnome-utils", 0))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
scm_init_sw_dialog_tax_table_module();
|
||||
scm_c_eval_string("(use-modules (sw_dialog_tax_table))");
|
||||
scm_init_sw_dialog_tax_table_module();
|
||||
scm_c_eval_string("(use-modules (sw_dialog_tax_table))");
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
libgncmod_dialog_tax_table_gnc_module_end(int refcount) {
|
||||
return TRUE;
|
||||
libgncmod_dialog_tax_table_gnc_module_end(int refcount)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ amort_sched_ptr amort_opt(
|
||||
var_store value;
|
||||
numeric_ptr nval;
|
||||
struct tm *times_E,
|
||||
*times_I;
|
||||
*times_I;
|
||||
|
||||
/* print amortization options */
|
||||
times_E = (struct tm *)calloc(1, sizeof(struct tm));
|
||||
|
||||
@@ -37,16 +37,16 @@ void prt_amortization_schedule(
|
||||
FILE *ofile) /* output file */
|
||||
{
|
||||
unsigned j,
|
||||
jj,
|
||||
prec = amortsched->prec,
|
||||
jj,
|
||||
prec = amortsched->prec,
|
||||
option = amortsched->option,
|
||||
fv_case = amortsched->fv_case;
|
||||
fv_case = amortsched->fv_case;
|
||||
unsigned char datel[100],
|
||||
summary = amortsched->summary;
|
||||
summary = amortsched->summary;
|
||||
struct tm *times_E,
|
||||
*times_I;
|
||||
*times_I;
|
||||
amort_sched_yr_ptr amortyr,
|
||||
prst_yr;
|
||||
prst_yr;
|
||||
sched_pmt_ptr pmtsched = NULL;
|
||||
yearly_summary_ptr annual_summary;
|
||||
|
||||
|
||||
@@ -254,15 +254,15 @@ int main(int argc, char **argv, char **env)
|
||||
var_store_ptr value_list;
|
||||
numeric_ptr nval;
|
||||
unsigned compute,
|
||||
jj,
|
||||
yrE,
|
||||
monthE,
|
||||
dayE,
|
||||
yrI,
|
||||
monthI,
|
||||
dayI;
|
||||
jj,
|
||||
yrE,
|
||||
monthE,
|
||||
dayE,
|
||||
yrI,
|
||||
monthI,
|
||||
dayI;
|
||||
struct tm *times_E,
|
||||
*times_I;
|
||||
*times_I;
|
||||
void *parse_env;
|
||||
amort_sched amortsched;
|
||||
financial_info fininfo;
|
||||
|
||||
@@ -1532,7 +1532,7 @@ fip (unsigned per, double eint, double pv, double pmt, double fv, unsigned bep)
|
||||
double CC = _C (eint, pmt, bep);
|
||||
double D = (AA + 1.0) / (1.0 + eint);
|
||||
g_return_val_if_fail(CC != 0.0, 0.0);
|
||||
return (double) per *(pv + CC) * D - (AA * CC) / eint;
|
||||
return (double) per * (pv + CC) * D - (AA * CC) / eint;
|
||||
} /* fip */
|
||||
|
||||
void
|
||||
@@ -1621,13 +1621,13 @@ Amortization_init (amort_sched_ptr amortsched)
|
||||
unsigned new_n;
|
||||
unsigned prec = amortsched->prec;
|
||||
unsigned long s,
|
||||
d,
|
||||
days_to_yr_end,
|
||||
Eff_Date_jdn =
|
||||
julian_day_number (amortsched->year_E, amortsched->month_E,
|
||||
amortsched->day_E), Init_Date_jdn =
|
||||
julian_day_number (amortsched->year_I, amortsched->month_I,
|
||||
amortsched->day_I);
|
||||
d,
|
||||
days_to_yr_end,
|
||||
Eff_Date_jdn =
|
||||
julian_day_number (amortsched->year_E, amortsched->month_E,
|
||||
amortsched->day_E), Init_Date_jdn =
|
||||
julian_day_number (amortsched->year_I, amortsched->month_I,
|
||||
amortsched->day_I);
|
||||
|
||||
amortsched->Eff_Date_jdn = Eff_Date_jdn;
|
||||
amortsched->Init_Date_jdn = Init_Date_jdn;
|
||||
|
||||
@@ -39,6 +39,6 @@ parser_env_ptr init_parser(
|
||||
void *negate_numeric(void *value),
|
||||
void free_numeric(void *numeric_value),
|
||||
void *func_op( const char *fname,
|
||||
int argc, void **argv ) );
|
||||
int argc, void **argv ) );
|
||||
|
||||
#endif
|
||||
|
||||
@@ -91,16 +91,16 @@ void *trans_numeric(
|
||||
{
|
||||
double dblval = 0.0;
|
||||
int exp = 0,
|
||||
dchr,
|
||||
err = 0,
|
||||
base = 10;
|
||||
dchr,
|
||||
err = 0,
|
||||
base = 10;
|
||||
long int inum = 0;
|
||||
unsigned long msdec = 0,
|
||||
lsdec = 0,
|
||||
msscale = 1;
|
||||
lsdec = 0,
|
||||
msscale = 1;
|
||||
unsigned radix = 0,
|
||||
sign = 0,
|
||||
digit_cnt = 0;
|
||||
sign = 0,
|
||||
digit_cnt = 0;
|
||||
const char *strinit = str;
|
||||
numeric_ptr rslt = NULL;
|
||||
|
||||
@@ -306,8 +306,8 @@ void *numeric_ops(
|
||||
void *r_value)
|
||||
{
|
||||
numeric_ptr lval = (numeric_ptr)l_value,
|
||||
rval = (numeric_ptr)r_value,
|
||||
rslt = (op_symbol == ASN_OP) ? lval : (numeric_ptr)calloc(1, sizeof(numeric));
|
||||
rval = (numeric_ptr)r_value,
|
||||
rslt = (op_symbol == ASN_OP) ? lval : (numeric_ptr)calloc(1, sizeof(numeric));
|
||||
|
||||
switch ( op_symbol )
|
||||
{
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
* in an inconsistent state. If they are not used in the proper
|
||||
* setting, they can leave the account structures in an inconsistent
|
||||
* state. Thus, these methods should never be used outside of
|
||||
* the engine, which is why they are "hidden" here.
|
||||
* the engine, which is why they are "hidden" here.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
/** STRUCTS *********************************************************/
|
||||
|
||||
/** This is the data that describes an account.
|
||||
/** This is the data that describes an account.
|
||||
*
|
||||
* This is the *private* header for the account structure.
|
||||
* No one outside of the engine should ever include this file.
|
||||
@@ -52,7 +52,7 @@
|
||||
/** \struct Account */
|
||||
struct account_s
|
||||
{
|
||||
QofInstance inst;
|
||||
QofInstance inst;
|
||||
};
|
||||
|
||||
/* Set the account's GUID. This should only be done when reading
|
||||
|
||||
@@ -43,8 +43,8 @@
|
||||
DEFINE_ENUM(FreqType, ENUM_LIST_TYPE) /**< \enum FreqType
|
||||
Frequency specification.
|
||||
|
||||
For BI_WEEKLY, use weekly[2]
|
||||
SEMI_MONTHLY, use composite
|
||||
For BI_WEEKLY, use weekly[2]
|
||||
SEMI_MONTHLY, use composite
|
||||
YEARLY, monthly[12] */
|
||||
|
||||
AS_STRING_DEC(FreqType, ENUM_LIST_TYPE)
|
||||
@@ -63,14 +63,14 @@ FROM_STRING_DEC(FreqType, ENUM_LIST_TYPE)
|
||||
_(UIFREQ_TRI_ANUALLY,) /**< Repeat three times a year. */ \
|
||||
_(UIFREQ_SEMI_YEARLY,) /**< Repeat twice a year. */ \
|
||||
_(UIFREQ_YEARLY,) /**< Repeat once a year. */ \
|
||||
_(UIFREQ_NUM_UI_FREQSPECS,)
|
||||
_(UIFREQ_NUM_UI_FREQSPECS,)
|
||||
|
||||
DEFINE_ENUM( UIFreqType, ENUM_LIST_UI) /**< \enum UIFreqType
|
||||
|
||||
* The user's conception of the frequency. It is expected that this
|
||||
* list will grow, while the former ::FreqType will not. */
|
||||
|
||||
AS_STRING_DEC(UIFreqType, ENUM_LIST_UI)
|
||||
AS_STRING_DEC(UIFreqType, ENUM_LIST_UI)
|
||||
FROM_STRING_DEC(UIFreqType, ENUM_LIST_UI)
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -6,24 +6,24 @@
|
||||
*/
|
||||
#define xaccGUIDNew(guid,book) \
|
||||
qof_instance_guid_new (qof_book_get_entity_table (book), (guid))
|
||||
|
||||
|
||||
#define xaccGUIDNULL guid_null
|
||||
#define xaccGUIDMalloc guid_malloc
|
||||
#define xaccGUIDFree guid_free
|
||||
|
||||
#define GNCIdTypeConst QofIdTypeConst
|
||||
#define GNCIdType QofIdType
|
||||
#define GNCEntityTable QofInstanceTable
|
||||
#define xaccGUIDTypeEntityTable qof_guid_type
|
||||
#define xaccGUIDNULL guid_null
|
||||
#define xaccGUIDMalloc guid_malloc
|
||||
#define xaccGUIDFree guid_free
|
||||
|
||||
#define xaccEntityTableNew qof_instance_new
|
||||
#define xaccEntityTableDestroy qof_instance_destroy
|
||||
#define xaccGUIDNewEntityTable qof_instance_guid_new
|
||||
#define xaccLookupEntity qof_instance_lookup
|
||||
#define xaccStoreEntity qof_instance_store
|
||||
#define xaccRemoveEntity qof_instance_remove
|
||||
#define xaccForeachEntity qof_instance_foreach
|
||||
#define GNCIdTypeConst QofIdTypeConst
|
||||
#define GNCIdType QofIdType
|
||||
#define GNCEntityTable QofInstanceTable
|
||||
#define xaccGUIDTypeEntityTable qof_guid_type
|
||||
|
||||
#define foreachObjectCB QofInstanceForeachCB
|
||||
#define xaccEntityTableNew qof_instance_new
|
||||
#define xaccEntityTableDestroy qof_instance_destroy
|
||||
#define xaccGUIDNewEntityTable qof_instance_guid_new
|
||||
#define xaccLookupEntity qof_instance_lookup
|
||||
#define xaccStoreEntity qof_instance_store
|
||||
#define xaccRemoveEntity qof_instance_remove
|
||||
#define xaccForeachEntity qof_instance_foreach
|
||||
|
||||
#define foreachObjectCB QofInstanceForeachCB
|
||||
|
||||
|
||||
@@ -45,26 +45,26 @@
|
||||
* book will have a copy of every account in the open book,
|
||||
* and that these copies will have new GUID's issued to them.
|
||||
* Thus, every account has a 'twin' in the other book.
|
||||
*
|
||||
* This routine will also create 'equity transactions' in
|
||||
*
|
||||
* This routine will also create 'equity transactions' in
|
||||
* order to preserve the balances on accounts. For any
|
||||
* account that is not of income, expense, trading or equity type,
|
||||
* this routine wil find the closing balance of each account
|
||||
* in the closed book. It will then create an 'equity
|
||||
* transaction' in the open book, creating an opening balance
|
||||
* between an equity account and the twin account to the
|
||||
* transaction' in the open book, creating an opening balance
|
||||
* between an equity account and the twin account to the
|
||||
* closed account. The 'memo' field will be used to set
|
||||
* the description in the equity transaction. Typically,
|
||||
* you will want to set this field to _("Opening Balance").
|
||||
*
|
||||
* The equity_account argument is supposed to indicate the
|
||||
* The equity_account argument is supposed to indicate the
|
||||
* equity account in the open book into which the opening
|
||||
* balances will be placed. This argument may be NULL,
|
||||
* if it is NULL, then a search algorithm will be used to
|
||||
* find a suitable equity account. If NULL, this routine
|
||||
* searches for the 'nearest' account of GNCAccountType ACCT_TYPE_EQUITY
|
||||
* among its siblings, or the siblings of its parents. It
|
||||
* does not search downwards. If it does not find such an
|
||||
* if it is NULL, then a search algorithm will be used to
|
||||
* find a suitable equity account. If NULL, this routine
|
||||
* searches for the 'nearest' account of GNCAccountType ACCT_TYPE_EQUITY
|
||||
* among its siblings, or the siblings of its parents. It
|
||||
* does not search downwards. If it does not find such an
|
||||
* account, it will create one, hanging off the top-most group.
|
||||
*
|
||||
* This routine also populates a number of KVP values in
|
||||
@@ -73,49 +73,49 @@
|
||||
* to safely re-open and re-close a closed book. In particular,
|
||||
* if a closed book is re-opened, the 'equity transaction'
|
||||
* would need to be adjusted.
|
||||
*
|
||||
*
|
||||
* The kvp values that are set are:
|
||||
*
|
||||
* Implemented in the closed book:
|
||||
* /book/close-date Latest date in this book. Must not change.
|
||||
* /book/log-date Date on which user called this routine.
|
||||
* /book/next-book GUID of next book (the still-open book).
|
||||
*
|
||||
*
|
||||
* Implemented in still-open book:
|
||||
* /book/open-date Earliest date in this book.
|
||||
* /book/prev-book GUID of previous book (the closed book).
|
||||
*
|
||||
*
|
||||
* Implemented in the balancing transaction:
|
||||
* /book/closed-acct GUID of account whose balance was brought forward
|
||||
* /book/closed-book GUID of book whose balance was brought forward
|
||||
*
|
||||
*
|
||||
* Implemented in the closed account:
|
||||
* /book/balancing-trans GUID of equity-balancing transaction.
|
||||
* /book/next-book GUID of equity-balancing book.
|
||||
* /book/next-acct GUID of twin of this account in the open book.
|
||||
*
|
||||
*
|
||||
* Implemented in the still-open account:
|
||||
* /book/prev-acct GUID of twin of this account in the closed book.
|
||||
* /book/prev-book GUID of previous book (the closed book)
|
||||
*
|
||||
*
|
||||
*/
|
||||
QofBook * gnc_book_close_period (QofBook *, Timespec,
|
||||
Account *equity_acct,
|
||||
QofBook * gnc_book_close_period (QofBook *, Timespec,
|
||||
Account *equity_acct,
|
||||
const char *memo);
|
||||
|
||||
/** The gnc_book_partition_txn() uses the result of the indicated query
|
||||
* to move a set of transactions from the "src" book to the "dest"
|
||||
* book. Before moving the transactions, it will first place a
|
||||
* copy of all of the accounts in "src" into "dest". This is done
|
||||
* book. Before moving the transactions, it will first place a
|
||||
* copy of all of the accounts in "src" into "dest". This is done
|
||||
* in order to ensure that all of the moved transactions will have
|
||||
* the corrrect set of accounts to reference. The transactions
|
||||
* that will be moved are precisely those specified by the query.
|
||||
* Any query that returns a list of transactions will work to
|
||||
* partition a book; however, its expected that this routine will
|
||||
* mostly serve as a utility to break up a book into accounting
|
||||
* periods.
|
||||
* Any query that returns a list of transactions will work to
|
||||
* partition a book; however, its expected that this routine will
|
||||
* mostly serve as a utility to break up a book into accounting
|
||||
* periods.
|
||||
*
|
||||
* This routine intentionally does not copy scheduled/recurring
|
||||
* This routine intentionally does not copy scheduled/recurring
|
||||
* transactions.
|
||||
*
|
||||
* This routine will also copy closed lots to the destination book.
|
||||
@@ -131,33 +131,33 @@ QofBook * gnc_book_close_period (QofBook *, Timespec,
|
||||
* The GUID of its sibling is placed in the 'gemini' KVP value
|
||||
* (See kvp_doc.txt for more detail). Transactions and splits
|
||||
* are moved without reassigning them a new GUID. Note they
|
||||
* are removed from one book's entity table and placed into the
|
||||
* are removed from one book's entity table and placed into the
|
||||
* other book: Once moved, they won't be findable in the entity
|
||||
* table of the old book.
|
||||
*
|
||||
* Known Bugs:
|
||||
*
|
||||
* Known Bugs:
|
||||
* When this routine copies accounts, it does not check to see
|
||||
* if they already exist in the 'dest' book; it should.
|
||||
* For the current usage, this bug aint important, and I'm too
|
||||
* if they already exist in the 'dest' book; it should.
|
||||
* For the current usage, this bug aint important, and I'm too
|
||||
* lazy to fix it.
|
||||
*/
|
||||
void gnc_book_partition_txn (QofBook *dest, QofBook *src, QofQuery *);
|
||||
|
||||
/** The gnc_book_partition_pricedb() routine uses te result of the
|
||||
* indicated query to move a set of prices from the "src" book
|
||||
* indicated query to move a set of prices from the "src" book
|
||||
* to the "dest" book. The query passed into it must be set up
|
||||
* to return a list of prices.
|
||||
*/
|
||||
void gnc_book_partition_pricedb (QofBook *dest, QofBook *src, QofQuery *);
|
||||
|
||||
/** The gnc_book_insert_trans_clobber() routine takes an existing
|
||||
* transaction that is located in one book, and moves it to
|
||||
* another book. It moves all of the splits as well. In the
|
||||
* course of the move, the transaction is literally deleted
|
||||
* from the first book as its placed into the second. The
|
||||
* transaction and split GUID's are not changed in the move.
|
||||
* This routine assumes that twin accounts already exist in
|
||||
* both books (and can be located with the standard twining
|
||||
/** The gnc_book_insert_trans_clobber() routine takes an existing
|
||||
* transaction that is located in one book, and moves it to
|
||||
* another book. It moves all of the splits as well. In the
|
||||
* course of the move, the transaction is literally deleted
|
||||
* from the first book as its placed into the second. The
|
||||
* transaction and split GUID's are not changed in the move.
|
||||
* This routine assumes that twin accounts already exist in
|
||||
* both books (and can be located with the standard twining
|
||||
* proceedure).
|
||||
*
|
||||
* Note that this routine does *not* move the lots that any
|
||||
@@ -171,7 +171,7 @@ void gnc_book_partition_pricedb (QofBook *dest, QofBook *src, QofQuery *);
|
||||
* merely moves the transaction and split GUID's to the new
|
||||
* books' entity tables, and not much else.
|
||||
*
|
||||
* The gnc_book_insert_lot() routine, as above, but for lots ...
|
||||
* The gnc_book_insert_lot() routine, as above, but for lots ...
|
||||
*/
|
||||
|
||||
void gnc_book_insert_trans (QofBook *book, Transaction *trans);
|
||||
|
||||
@@ -63,23 +63,24 @@ typedef QofQuery Query;
|
||||
|
||||
#define xaccQueryEqual qof_query_equal
|
||||
|
||||
typedef enum {
|
||||
QUERY_TXN_MATCH_ALL=1, /* match all accounts */
|
||||
QUERY_TXN_MATCH_ANY=2 /* match any account */
|
||||
typedef enum
|
||||
{
|
||||
QUERY_TXN_MATCH_ALL = 1, /* match all accounts */
|
||||
QUERY_TXN_MATCH_ANY = 2 /* match any account */
|
||||
} query_txn_match_t;
|
||||
|
||||
/* After the query has been set up, call one of these to run the query.
|
||||
/* After the query has been set up, call one of these to run the query.
|
||||
* XXX The routines below should be replaced by a query
|
||||
* that explicitly asks for a list of the desired item.
|
||||
*
|
||||
* The xaccQueryGetSplits() routine returns all splits matching the
|
||||
* The xaccQueryGetSplits() routine returns all splits matching the
|
||||
* query. Any given split will appear at most once in the result;
|
||||
* however, several splits from one transaction may appear in the list.
|
||||
* The caller MUST NOT change the GList.
|
||||
*
|
||||
* The xaccQueryGetSplitsUniqueTrans() routine returns splits matching
|
||||
* the query, but only one matching split per transaction will be
|
||||
* returned. In other words, any given transaction will be
|
||||
* the query, but only one matching split per transaction will be
|
||||
* returned. In other words, any given transaction will be
|
||||
* represented at most once in the returned list. The caller must
|
||||
* free the GList.
|
||||
*
|
||||
@@ -91,17 +92,17 @@ typedef enum {
|
||||
* The xaccQueryGetLots() routine is just like GetTransactions() except
|
||||
* it returns a list of Lots.
|
||||
*
|
||||
* query_txn_match_t describes how to match accounts when querying
|
||||
* query_txn_match_t describes how to match accounts when querying
|
||||
* for transactions with xaccQueryGetTransactions().
|
||||
* What is the difference between 'ANY' and 'ALL', you
|
||||
* What is the difference between 'ANY' and 'ALL', you
|
||||
* may ask? First, let us recall that a transaction consists
|
||||
* of splits, and each split belongs to exactly one account.
|
||||
* Specifying "MATCH_ALL" means that *every* account that
|
||||
* shows up in the query must also show up in some split in
|
||||
* the transaction (in order for that transaction to be
|
||||
* Specifying "MATCH_ALL" means that *every* account that
|
||||
* shows up in the query must also show up in some split in
|
||||
* the transaction (in order for that transaction to be
|
||||
* selected). By contrast, specifying 'ANY' means that
|
||||
* any account in the query must show up in some split
|
||||
* in the transaction (in order for the transaction to
|
||||
* in the transaction (in order for the transaction to
|
||||
* be selected). Thus, 'ANY' acts as a boolean-OR when
|
||||
* matching accounts, whereas 'AND' acts as a boolean-AND
|
||||
* for matching accounts. Whew. Got that?
|
||||
@@ -112,7 +113,7 @@ TransList * xaccQueryGetTransactions(Query * q, query_txn_match_t type);
|
||||
LotList * xaccQueryGetLots(Query * q, query_txn_match_t type);
|
||||
|
||||
/*******************************************************************
|
||||
* match-adding API
|
||||
* match-adding API
|
||||
*******************************************************************/
|
||||
|
||||
void xaccQueryAddAccountMatch(Query *, AccountList *,
|
||||
@@ -124,9 +125,9 @@ void xaccQueryAddAccountGUIDMatch(Query *, AccountGUIDList *,
|
||||
void xaccQueryAddSingleAccountMatch(Query *, Account *, QofQueryOp);
|
||||
|
||||
void xaccQueryAddStringMatch (Query* q, const char *matchstring,
|
||||
gboolean case_sens, gboolean use_regexp,
|
||||
gboolean case_sens, gboolean use_regexp,
|
||||
QofQueryOp op,
|
||||
const char * path, ...);
|
||||
const char * path, ...);
|
||||
void
|
||||
xaccQueryAddDescriptionMatch(Query *q, const char *m, gboolean c, gboolean r,
|
||||
QofQueryOp o);
|
||||
@@ -152,15 +153,15 @@ void
|
||||
xaccQueryAddBalanceMatch(Query *q, QofQueryCompare bal, QofQueryOp op);
|
||||
|
||||
void xaccQueryAddNumericMatch (Query *q, gnc_numeric amount,
|
||||
QofNumericMatch sign, QofQueryCompare how,
|
||||
QofQueryOp op, const char * path, ...);
|
||||
QofNumericMatch sign, QofQueryCompare how,
|
||||
QofQueryOp op, const char * path, ...);
|
||||
|
||||
/** The DateMatch queries match transactions whose posted date
|
||||
* is in a date range. If use_start is TRUE, then a matching
|
||||
* posted date will be greater than the start date. If
|
||||
* use_end is TRUE, then a match occurs for posted dates earlier
|
||||
* than the end date. If both flags are set, then *both*
|
||||
* conditions must hold ('and'). If neither flag is set, then
|
||||
* posted date will be greater than the start date. If
|
||||
* use_end is TRUE, then a match occurs for posted dates earlier
|
||||
* than the end date. If both flags are set, then *both*
|
||||
* conditions must hold ('and'). If neither flag is set, then
|
||||
* all transactions are matched.
|
||||
*/
|
||||
|
||||
@@ -168,29 +169,30 @@ void xaccQueryAddDateMatch(Query * q, gboolean use_start,
|
||||
int sday, int smonth, int syear,
|
||||
gboolean use_end, int eday, int emonth, int eyear,
|
||||
QofQueryOp op);
|
||||
void xaccQueryAddDateMatchTS(Query * q,
|
||||
void xaccQueryAddDateMatchTS(Query * q,
|
||||
gboolean use_start, Timespec sts,
|
||||
gboolean use_end, Timespec ets,
|
||||
QofQueryOp op);
|
||||
void xaccQueryAddDateMatchTT(Query * q,
|
||||
void xaccQueryAddDateMatchTT(Query * q,
|
||||
gboolean use_start, time_t stt,
|
||||
gboolean use_end, time_t ett,
|
||||
QofQueryOp op);
|
||||
void xaccQueryGetDateMatchTS (Query * q,
|
||||
Timespec * sts,
|
||||
Timespec * ets);
|
||||
void xaccQueryGetDateMatchTT (Query * q,
|
||||
time_t * stt,
|
||||
time_t * ett);
|
||||
void xaccQueryGetDateMatchTS (Query * q,
|
||||
Timespec * sts,
|
||||
Timespec * ets);
|
||||
void xaccQueryGetDateMatchTT (Query * q,
|
||||
time_t * stt,
|
||||
time_t * ett);
|
||||
|
||||
typedef enum {
|
||||
CLEARED_NONE = 0x0000,
|
||||
CLEARED_NO = 0x0001,
|
||||
CLEARED_CLEARED = 0x0002,
|
||||
CLEARED_RECONCILED = 0x0004,
|
||||
CLEARED_FROZEN = 0x0008,
|
||||
CLEARED_VOIDED = 0x0010,
|
||||
CLEARED_ALL = 0x001F
|
||||
typedef enum
|
||||
{
|
||||
CLEARED_NONE = 0x0000,
|
||||
CLEARED_NO = 0x0001,
|
||||
CLEARED_CLEARED = 0x0002,
|
||||
CLEARED_RECONCILED = 0x0004,
|
||||
CLEARED_FROZEN = 0x0008,
|
||||
CLEARED_VOIDED = 0x0010,
|
||||
CLEARED_ALL = 0x001F
|
||||
} cleared_match_t;
|
||||
|
||||
void xaccQueryAddClearedMatch(Query * q, cleared_match_t how, QofQueryOp op);
|
||||
@@ -203,7 +205,7 @@ void xaccQueryAddKVPMatch(Query *q, GSList *path, const KvpValue *value,
|
||||
QofQueryOp op);
|
||||
|
||||
/*******************************************************************
|
||||
* compatibility interface with old Query API
|
||||
* compatibility interface with old Query API
|
||||
*******************************************************************/
|
||||
time_t xaccQueryGetEarliestDateFound(Query * q);
|
||||
time_t xaccQueryGetLatestDateFound(Query * q);
|
||||
|
||||
@@ -1,68 +1,68 @@
|
||||
|
||||
#include "qof.h"
|
||||
|
||||
#define QueryPredData_t QofQueryPredData*
|
||||
#define QueryPredData_t QofQueryPredData*
|
||||
|
||||
#define gncQueryStringPredicate qof_query_string_predicate
|
||||
#define gncQueryDatePredicate qof_query_date_predicate
|
||||
#define gncQueryNumericPredicate qof_query_numeric_predicate
|
||||
#define gncQueryGUIDPredicate qof_query_guid_predicate
|
||||
#define gncQueryInt32Predicate qof_query_int32_predicate
|
||||
#define gncQueryInt64Predicate qof_query_int64_predicate
|
||||
#define gncQueryDoublePredicate qof_query_double_predicate
|
||||
#define gncQueryBooleanPredicate qof_query_boolean_predicate
|
||||
#define gncQueryCharPredicate qof_query_char_predicate
|
||||
#define gncQueryKVPPredicate qof_query_kvp_predicate
|
||||
#define gncQueryCorePredicateFree qof_query_core_predicate_free
|
||||
#define gncQueryStringPredicate qof_query_string_predicate
|
||||
#define gncQueryDatePredicate qof_query_date_predicate
|
||||
#define gncQueryNumericPredicate qof_query_numeric_predicate
|
||||
#define gncQueryGUIDPredicate qof_query_guid_predicate
|
||||
#define gncQueryInt32Predicate qof_query_int32_predicate
|
||||
#define gncQueryInt64Predicate qof_query_int64_predicate
|
||||
#define gncQueryDoublePredicate qof_query_double_predicate
|
||||
#define gncQueryBooleanPredicate qof_query_boolean_predicate
|
||||
#define gncQueryCharPredicate qof_query_char_predicate
|
||||
#define gncQueryKVPPredicate qof_query_kvp_predicate
|
||||
#define gncQueryCorePredicateFree qof_query_core_predicate_free
|
||||
|
||||
#define COMPARE_LT QOF_COMPARE_LT
|
||||
#define COMPARE_LTE QOF_COMPARE_LTE
|
||||
#define COMPARE_EQUAL QOF_COMPARE_EQUAL
|
||||
#define COMPARE_GT QOF_COMPARE_GT
|
||||
#define COMPARE_GTE QOF_COMPARE_GTE
|
||||
#define COMPARE_NEQ QOF_COMPARE_NEQ
|
||||
#define COMPARE_LT QOF_COMPARE_LT
|
||||
#define COMPARE_LTE QOF_COMPARE_LTE
|
||||
#define COMPARE_EQUAL QOF_COMPARE_EQUAL
|
||||
#define COMPARE_GT QOF_COMPARE_GT
|
||||
#define COMPARE_GTE QOF_COMPARE_GTE
|
||||
#define COMPARE_NEQ QOF_COMPARE_NEQ
|
||||
|
||||
#define STRING_MATCH_NORMAL QOF_STRING_MATCH_NORMAL
|
||||
#define STRING_MATCH_CASEINSENSITIVE QOF_STRING_MATCH_CASEINSENSITIVE
|
||||
#define STRING_MATCH_NORMAL QOF_STRING_MATCH_NORMAL
|
||||
#define STRING_MATCH_CASEINSENSITIVE QOF_STRING_MATCH_CASEINSENSITIVE
|
||||
|
||||
#define DATE_MATCH_NORMAL QOF_DATE_MATCH_NORMAL
|
||||
#define DATE_MATCH_ROUNDED QOF_DATE_MATCH_ROUNDED
|
||||
#define DATE_MATCH_NORMAL QOF_DATE_MATCH_NORMAL
|
||||
#define DATE_MATCH_ROUNDED QOF_DATE_MATCH_ROUNDED
|
||||
|
||||
#define NUMERIC_MATCH_ANY QOF_NUMERIC_MATCH_ANY
|
||||
#define NUMERIC_MATCH_CREDIT QOF_NUMERIC_MATCH_CREDIT
|
||||
#define NUMERIC_MATCH_DEBIT QOF_NUMERIC_MATCH_DEBIT
|
||||
#define NUMERIC_MATCH_ANY QOF_NUMERIC_MATCH_ANY
|
||||
#define NUMERIC_MATCH_CREDIT QOF_NUMERIC_MATCH_CREDIT
|
||||
#define NUMERIC_MATCH_DEBIT QOF_NUMERIC_MATCH_DEBIT
|
||||
|
||||
#define GUID_MATCH_ANY QOF_GUID_MATCH_ANY
|
||||
#define GUID_MATCH_NONE QOF_GUID_MATCH_NONE
|
||||
#define GUID_MATCH_NULL QOF_GUID_MATCH_NULL
|
||||
#define GUID_MATCH_ALL QOF_GUID_MATCH_ALL
|
||||
#define GUID_MATCH_LIST_ANY QOF_GUID_MATCH_LIST_ANY
|
||||
#define GUID_MATCH_ANY QOF_GUID_MATCH_ANY
|
||||
#define GUID_MATCH_NONE QOF_GUID_MATCH_NONE
|
||||
#define GUID_MATCH_NULL QOF_GUID_MATCH_NULL
|
||||
#define GUID_MATCH_ALL QOF_GUID_MATCH_ALL
|
||||
#define GUID_MATCH_LIST_ANY QOF_GUID_MATCH_LIST_ANY
|
||||
|
||||
#define CHAR_MATCH_ANY QOF_CHAR_MATCH_ANY
|
||||
#define CHAR_MATCH_NONE QOF_CHAR_MATCH_NONE
|
||||
#define CHAR_MATCH_ANY QOF_CHAR_MATCH_ANY
|
||||
#define CHAR_MATCH_NONE QOF_CHAR_MATCH_NONE
|
||||
|
||||
#define char_match_t QofCharMatch
|
||||
#define guid_match_t QofGuidMatch
|
||||
#define numeric_match_t QofNumericMatch
|
||||
#define date_match_t QofDateMatch
|
||||
#define string_match_t QofStringMatch
|
||||
#define query_compare_t QofQueryCompare
|
||||
#define char_match_t QofCharMatch
|
||||
#define guid_match_t QofGuidMatch
|
||||
#define numeric_match_t QofNumericMatch
|
||||
#define date_match_t QofDateMatch
|
||||
#define string_match_t QofStringMatch
|
||||
#define query_compare_t QofQueryCompare
|
||||
|
||||
#define gncQueryCoreInit qof_query_core_init
|
||||
#define gncQueryCoreShutdown qof_query_core_shutdown
|
||||
#define gncQueryCoreGetPredicate qof_query_core_get_predicate
|
||||
#define gncQueryCoreGetCompare qof_query_core_get_compare
|
||||
|
||||
#define gncQueryCorePredicateEqual qof_query_core_predicate_equal
|
||||
|
||||
#define QUERYCORE_GUID QOF_TYPE_GUID
|
||||
#define QUERYCORE_DEBCRED QOF_TYPE_DEBCRED
|
||||
#define QUERYCORE_BOOLEAN QOF_TYPE_BOOLEAN
|
||||
#define QUERYCORE_NUMERIC QOF_TYPE_NUMERIC
|
||||
#define QUERYCORE_STRING QOF_TYPE_STRING
|
||||
#define QUERYCORE_DATE QOF_TYPE_DATE
|
||||
#define QUERYCORE_INT64 QOF_TYPE_INT64
|
||||
#define QUERYCORE_DOUBLE QOF_TYPE_DOUBLE
|
||||
#define gncQueryCoreInit qof_query_core_init
|
||||
#define gncQueryCoreShutdown qof_query_core_shutdown
|
||||
#define gncQueryCoreGetPredicate qof_query_core_get_predicate
|
||||
#define gncQueryCoreGetCompare qof_query_core_get_compare
|
||||
|
||||
#define QueryAccess QofAccessFunc
|
||||
#define gncQueryCoreToString qof_query_core_to_string
|
||||
#define gncQueryCorePredicateEqual qof_query_core_predicate_equal
|
||||
|
||||
#define QUERYCORE_GUID QOF_TYPE_GUID
|
||||
#define QUERYCORE_DEBCRED QOF_TYPE_DEBCRED
|
||||
#define QUERYCORE_BOOLEAN QOF_TYPE_BOOLEAN
|
||||
#define QUERYCORE_NUMERIC QOF_TYPE_NUMERIC
|
||||
#define QUERYCORE_STRING QOF_TYPE_STRING
|
||||
#define QUERYCORE_DATE QOF_TYPE_DATE
|
||||
#define QUERYCORE_INT64 QOF_TYPE_INT64
|
||||
#define QUERYCORE_DOUBLE QOF_TYPE_DOUBLE
|
||||
|
||||
#define QueryAccess QofAccessFunc
|
||||
#define gncQueryCoreToString qof_query_core_to_string
|
||||
|
||||
@@ -1,48 +1,48 @@
|
||||
#include "qof.h"
|
||||
|
||||
|
||||
#define QUERY_AND QOF_QUERY_AND
|
||||
#define QUERY_OR QOF_QUERY_OR
|
||||
#define QUERY_NAND QOF_QUERY_NAND
|
||||
#define QUERY_NOR QOF_QUERY_NOR
|
||||
#define QUERY_XOR QOF_QUERY_XOR
|
||||
#define QUERY_PARAM_BOOK QOF_PARAM_BOOK
|
||||
#define QUERY_PARAM_GUID QOF_PARAM_GUID
|
||||
#define QUERY_PARAM_ACTIVE QOF_PARAM_ACTIVE
|
||||
#define QUERY_AND QOF_QUERY_AND
|
||||
#define QUERY_OR QOF_QUERY_OR
|
||||
#define QUERY_NAND QOF_QUERY_NAND
|
||||
#define QUERY_NOR QOF_QUERY_NOR
|
||||
#define QUERY_XOR QOF_QUERY_XOR
|
||||
#define QUERY_PARAM_BOOK QOF_PARAM_BOOK
|
||||
#define QUERY_PARAM_GUID QOF_PARAM_GUID
|
||||
#define QUERY_PARAM_ACTIVE QOF_PARAM_ACTIVE
|
||||
|
||||
#define querynew_s _QofQuery
|
||||
#define QueryNew QofQuery
|
||||
#define QueryOp QofQueryOp
|
||||
#define query_new_term _QofQueryTerm
|
||||
#define query_new_sort _QofSortFunc
|
||||
#define querynew_s _QofQuery
|
||||
#define QueryNew QofQuery
|
||||
#define QueryOp QofQueryOp
|
||||
#define query_new_term _QofQueryTerm
|
||||
#define query_new_sort _QofSortFunc
|
||||
|
||||
#define gncQueryBuildParamList qof_query_build_param_list
|
||||
#define gncQueryCreate qof_query_create
|
||||
#define gncQueryCreateFor qof_query_create_for
|
||||
#define gncQueryDestroy qof_query_destroy
|
||||
#define gncQuerySearchFor qof_query_search_for
|
||||
#define gncQuerySetBook qof_query_set_book
|
||||
#define gncQueryAddTerm qof_query_add_term
|
||||
#define gncQueryAddGUIDMatch qof_query_add_guid_match
|
||||
#define gncQueryAddGUIDListMatch qof_query_add_guid_list_match
|
||||
#define gncQueryAddBooleanMatch qof_query_add_boolean_match
|
||||
#define gncQueryRun qof_query_run
|
||||
#define gncQueryLastRun qof_query_last_run
|
||||
#define gncQueryClear qof_query_clear
|
||||
#define gncQueryPurgeTerms qof_query_purge_terms
|
||||
#define gncQueryHasTerms qof_query_has_terms
|
||||
#define gncQueryNumTerms qof_query_num_terms
|
||||
#define gncQueryHasTermType qof_query_has_term_type
|
||||
#define gncQueryCopy qof_query_copy
|
||||
#define gncQueryInvert qof_query_invert
|
||||
#define gncQueryMerge qof_query_merge
|
||||
#define gncQueryMergeInPlace qof_query_merge_in_place
|
||||
#define gncQuerySetSortOrder qof_query_set_sort_order
|
||||
#define gncQuerySetSortOptions qof_query_set_sort_options
|
||||
#define gncQuerySetSortIncreasing qof_query_set_sort_increasing
|
||||
#define gncQuerySetMaxResults qof_query_set_max_results
|
||||
#define gncQueryEqual qof_query_equal
|
||||
#define gncQueryPrint qof_query_print
|
||||
#define gncQueryGetSearchFor qof_query_get_search_for
|
||||
#define gncQueryGetBooks qof_query_get_books
|
||||
#define gncQueryBuildParamList qof_query_build_param_list
|
||||
#define gncQueryCreate qof_query_create
|
||||
#define gncQueryCreateFor qof_query_create_for
|
||||
#define gncQueryDestroy qof_query_destroy
|
||||
#define gncQuerySearchFor qof_query_search_for
|
||||
#define gncQuerySetBook qof_query_set_book
|
||||
#define gncQueryAddTerm qof_query_add_term
|
||||
#define gncQueryAddGUIDMatch qof_query_add_guid_match
|
||||
#define gncQueryAddGUIDListMatch qof_query_add_guid_list_match
|
||||
#define gncQueryAddBooleanMatch qof_query_add_boolean_match
|
||||
#define gncQueryRun qof_query_run
|
||||
#define gncQueryLastRun qof_query_last_run
|
||||
#define gncQueryClear qof_query_clear
|
||||
#define gncQueryPurgeTerms qof_query_purge_terms
|
||||
#define gncQueryHasTerms qof_query_has_terms
|
||||
#define gncQueryNumTerms qof_query_num_terms
|
||||
#define gncQueryHasTermType qof_query_has_term_type
|
||||
#define gncQueryCopy qof_query_copy
|
||||
#define gncQueryInvert qof_query_invert
|
||||
#define gncQueryMerge qof_query_merge
|
||||
#define gncQueryMergeInPlace qof_query_merge_in_place
|
||||
#define gncQuerySetSortOrder qof_query_set_sort_order
|
||||
#define gncQuerySetSortOptions qof_query_set_sort_options
|
||||
#define gncQuerySetSortIncreasing qof_query_set_sort_increasing
|
||||
#define gncQuerySetMaxResults qof_query_set_max_results
|
||||
#define gncQueryEqual qof_query_equal
|
||||
#define gncQueryPrint qof_query_print
|
||||
#define gncQueryGetSearchFor qof_query_get_search_for
|
||||
#define gncQueryGetBooks qof_query_get_books
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
|
||||
#include "qof.h"
|
||||
|
||||
#define query_object_def _QofParam
|
||||
#define QueryObjectDef QofParam
|
||||
#define QuerySort QofSortFunc
|
||||
#define query_object_def _QofParam
|
||||
#define QueryObjectDef QofParam
|
||||
#define QuerySort QofSortFunc
|
||||
|
||||
#define gncQueryObjectRegister qof_class_register
|
||||
#define gncQueryObjectParameterType qof_class_get_parameter_type
|
||||
#define gncQueryObjectGetParameterGetter qof_class_get_parameter_getter
|
||||
#define gncQueryObjectGetParameter qof_class_get_parameter
|
||||
#define gncQueryObjectRegister qof_class_register
|
||||
#define gncQueryObjectParameterType qof_class_get_parameter_type
|
||||
#define gncQueryObjectGetParameterGetter qof_class_get_parameter_getter
|
||||
#define gncQueryObjectGetParameter qof_class_get_parameter
|
||||
|
||||
|
||||
@@ -24,123 +24,136 @@
|
||||
#ifndef GNUCASH_QUERY_P_H
|
||||
#define GNUCASH_QUERY_P_H
|
||||
|
||||
#include "Query.h"
|
||||
#include "Query.h"
|
||||
|
||||
#if 0
|
||||
|
||||
typedef struct {
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
typedef struct
|
||||
{
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
} BasePredicateData;
|
||||
|
||||
typedef struct {
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
acct_match_t how;
|
||||
AccountList *accounts;
|
||||
AccountGUIDList *account_guids;
|
||||
typedef struct
|
||||
{
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
acct_match_t how;
|
||||
AccountList *accounts;
|
||||
AccountGUIDList *account_guids;
|
||||
} AccountPredicateData;
|
||||
|
||||
typedef struct {
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
amt_match_t how;
|
||||
amt_match_sgn_t amt_sgn;
|
||||
double amount;
|
||||
typedef struct
|
||||
{
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
amt_match_t how;
|
||||
amt_match_sgn_t amt_sgn;
|
||||
double amount;
|
||||
} AmountPredicateData;
|
||||
|
||||
typedef struct {
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
balance_match_t how;
|
||||
typedef struct
|
||||
{
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
balance_match_t how;
|
||||
} BalancePredicateData;
|
||||
|
||||
typedef struct {
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
book_match_t how;
|
||||
BookList *books;
|
||||
BookGUIDList *book_guids;
|
||||
typedef struct
|
||||
{
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
book_match_t how;
|
||||
BookList *books;
|
||||
BookGUIDList *book_guids;
|
||||
} BookPredicateData;
|
||||
|
||||
typedef struct {
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
cleared_match_t how;
|
||||
typedef struct
|
||||
{
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
cleared_match_t how;
|
||||
} ClearedPredicateData;
|
||||
|
||||
typedef struct {
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
GUID guid;
|
||||
QofIdType id_type;
|
||||
typedef struct
|
||||
{
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
GUID guid;
|
||||
QofIdType id_type;
|
||||
} GUIDPredicateData;
|
||||
|
||||
typedef struct {
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
int use_start;
|
||||
Timespec start;
|
||||
int use_end;
|
||||
Timespec end;
|
||||
typedef struct
|
||||
{
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
int use_start;
|
||||
Timespec start;
|
||||
int use_end;
|
||||
Timespec end;
|
||||
} DatePredicateData;
|
||||
|
||||
typedef struct {
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
kvp_match_t how;
|
||||
kvp_match_where_t where;
|
||||
GSList *path;
|
||||
KvpValue *value;
|
||||
typedef struct
|
||||
{
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
kvp_match_t how;
|
||||
kvp_match_where_t where;
|
||||
GSList *path;
|
||||
KvpValue *value;
|
||||
} KVPPredicateData;
|
||||
|
||||
typedef struct {
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
int how;
|
||||
int data;
|
||||
typedef struct
|
||||
{
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
int how;
|
||||
int data;
|
||||
} MiscPredicateData;
|
||||
|
||||
typedef struct {
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
int case_sens;
|
||||
int use_regexp;
|
||||
char *matchstring;
|
||||
regex_t compiled;
|
||||
typedef struct
|
||||
{
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
int case_sens;
|
||||
int use_regexp;
|
||||
char *matchstring;
|
||||
regex_t compiled;
|
||||
} StringPredicateData;
|
||||
|
||||
typedef union {
|
||||
pd_type_t type;
|
||||
BasePredicateData base;
|
||||
AccountPredicateData acct;
|
||||
AmountPredicateData amount;
|
||||
BalancePredicateData balance;
|
||||
BookPredicateData book;
|
||||
ClearedPredicateData cleared;
|
||||
DatePredicateData date;
|
||||
GUIDPredicateData guid;
|
||||
KVPPredicateData kvp;
|
||||
StringPredicateData str;
|
||||
MiscPredicateData misc;
|
||||
typedef union
|
||||
{
|
||||
pd_type_t type;
|
||||
BasePredicateData base;
|
||||
AccountPredicateData acct;
|
||||
AmountPredicateData amount;
|
||||
BalancePredicateData balance;
|
||||
BookPredicateData book;
|
||||
ClearedPredicateData cleared;
|
||||
DatePredicateData date;
|
||||
GUIDPredicateData guid;
|
||||
KVPPredicateData kvp;
|
||||
StringPredicateData str;
|
||||
MiscPredicateData misc;
|
||||
} PredicateData;
|
||||
|
||||
typedef int (* Predicate)(Split * to_test, PredicateData * test_data);
|
||||
|
||||
typedef struct {
|
||||
PredicateData data;
|
||||
Predicate p;
|
||||
typedef struct
|
||||
{
|
||||
PredicateData data;
|
||||
Predicate p;
|
||||
} QueryTerm;
|
||||
|
||||
void xaccQueryAddMiscMatch(Query * q, Predicate p, int how, int data,
|
||||
|
||||
@@ -44,7 +44,8 @@
|
||||
#include "Account.h"
|
||||
#include "gnc-numeric.h"
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
PERIOD_ONCE, /* Not a true period at all, but convenient here. */
|
||||
PERIOD_DAY,
|
||||
PERIOD_WEEK,
|
||||
@@ -57,7 +58,8 @@ typedef enum {
|
||||
PERIOD_INVALID = -1,
|
||||
} PeriodType;
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
WEEKEND_ADJ_NONE,
|
||||
WEEKEND_ADJ_BACK, /* Previous weekday */
|
||||
WEEKEND_ADJ_FORWARD, /* Next weekday */
|
||||
@@ -67,16 +69,17 @@ typedef enum {
|
||||
|
||||
/* Recurrences represent both the phase and period of a recurring event. */
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
GDate start; /* First date in the recurrence; specifies phase. */
|
||||
PeriodType ptype; /* see PeriodType enum */
|
||||
guint16 mult; /* a period multiplier */
|
||||
WeekendAdjust wadj; /* see WeekendAdjust enum */
|
||||
WeekendAdjust wadj; /* see WeekendAdjust enum */
|
||||
} Recurrence;
|
||||
|
||||
|
||||
/* recurrenceSet() will enforce internal consistency by overriding
|
||||
inconsistent inputs so that 'r' will _always_ end up being a valid
|
||||
inconsistent inputs so that 'r' will _always_ end up being a valid
|
||||
recurrence.
|
||||
|
||||
- if the period type is invalid, PERIOD_MONTH is used.
|
||||
@@ -138,8 +141,8 @@ time_t recurrenceGetPeriodTime(const Recurrence *r, guint n, gboolean end);
|
||||
* @return the amount that an Account's value changed between the beginning
|
||||
* and end of the nth instance of the Recurrence.
|
||||
**/
|
||||
gnc_numeric recurrenceGetAccountPeriodValue(const Recurrence *r,
|
||||
Account *acct, guint n);
|
||||
gnc_numeric recurrenceGetAccountPeriodValue(const Recurrence *r,
|
||||
Account *acct, guint n);
|
||||
|
||||
/** @return the earliest of the next occurances -- a "composite" recurrence **/
|
||||
void recurrenceListNextInstance(const GList *r, const GDate *refDate,
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
* See src/doc/books.txt for design overview.
|
||||
* @author Copyright (c) 2003 Linas Vepstas <linas@linas.org>
|
||||
* @author Copyright (c) 2006 Joshua Sled <jsled@asynchronous.org>
|
||||
*
|
||||
*
|
||||
* XXX currently, this is crufty, it should be modified to use
|
||||
* entities a bit more whole-heartedly than it does.
|
||||
**/
|
||||
@@ -46,15 +46,16 @@ typedef struct _SchedXactionsClass SchedXactionsClass;
|
||||
#include "SchedXaction.h"
|
||||
#include "qof.h"
|
||||
|
||||
struct xaccSchedXactionsDef {
|
||||
QofInstance inst;
|
||||
GList* sx_list;
|
||||
gboolean sx_notsaved;
|
||||
struct xaccSchedXactionsDef
|
||||
{
|
||||
QofInstance inst;
|
||||
GList* sx_list;
|
||||
gboolean sx_notsaved;
|
||||
};
|
||||
|
||||
struct _SchedXactionsClass
|
||||
{
|
||||
QofInstanceClass parent_class;
|
||||
QofInstanceClass parent_class;
|
||||
};
|
||||
|
||||
/* --- type macros --- */
|
||||
@@ -80,7 +81,8 @@ void gnc_sxes_add_sx(SchedXactions* sxes, SchedXaction* sx);
|
||||
void gnc_sxes_del_sx(SchedXactions* sxes, SchedXaction* sx);
|
||||
|
||||
/** Returns the template group from the book. **/
|
||||
/*@ dependent @*/ Account *gnc_book_get_template_root(const QofBook *book);
|
||||
/*@ dependent @*/
|
||||
Account *gnc_book_get_template_root(const QofBook *book);
|
||||
|
||||
/** @return The list of SXes which reference the given Account. Caller should free this list. **/
|
||||
GList* gnc_sx_get_sxes_referencing_account(QofBook *book, Account *acct);
|
||||
|
||||
@@ -70,13 +70,13 @@ const char *gnc_ttsplitinfo_get_memo(TTSplitInfo *split_i);
|
||||
void gnc_ttsplitinfo_set_credit_formula(TTSplitInfo *split_i,
|
||||
const char *credit_formula);
|
||||
void gnc_ttsplitinfo_set_credit_formula_numeric(TTSplitInfo *split_i,
|
||||
gnc_numeric credit_formula);
|
||||
gnc_numeric credit_formula);
|
||||
const char *gnc_ttsplitinfo_get_credit_formula(TTSplitInfo *split_i);
|
||||
|
||||
void gnc_ttsplitinfo_set_debit_formula(TTSplitInfo *split_i,
|
||||
const char *debit_formula);
|
||||
void gnc_ttsplitinfo_set_debit_formula_numeric(TTSplitInfo *split_i,
|
||||
gnc_numeric debit_formula);
|
||||
gnc_numeric debit_formula);
|
||||
const char *gnc_ttsplitinfo_get_debit_formula(TTSplitInfo *split_i);
|
||||
|
||||
void gnc_ttsplitinfo_set_account(TTSplitInfo *split_i, Account *acc);
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
@addtogroup SchedXaction Scheduled/Periodic/Recurring Transactions
|
||||
|
||||
Scheduled Transactions provide a framework for remembering
|
||||
information about a transactions that are set to occur in the
|
||||
information about a transactions that are set to occur in the
|
||||
future, either once or periodically.
|
||||
@{ */
|
||||
/**
|
||||
@@ -86,48 +86,49 @@ typedef struct _SchedXaction SchedXaction;
|
||||
**/
|
||||
struct _SchedXaction
|
||||
{
|
||||
QofInstance inst;
|
||||
gchar *name;
|
||||
QofInstance inst;
|
||||
gchar *name;
|
||||
|
||||
GList *schedule;
|
||||
|
||||
GDate last_date;
|
||||
|
||||
GDate start_date;
|
||||
/* if end_date is invalid, then no end. */
|
||||
GDate end_date;
|
||||
GList *schedule;
|
||||
|
||||
/* if num_occurances_total == 0, then no limit */
|
||||
gint num_occurances_total;
|
||||
/* reminaing occurances are as-of the 'last_date'. */
|
||||
gint num_occurances_remain;
|
||||
GDate last_date;
|
||||
|
||||
/* the current instance-count of the SX. */
|
||||
gint instance_num;
|
||||
|
||||
gboolean enabled;
|
||||
gboolean autoCreateOption;
|
||||
gboolean autoCreateNotify;
|
||||
gint advanceCreateDays;
|
||||
gint advanceRemindDays;
|
||||
|
||||
Account *template_acct;
|
||||
|
||||
/** The list of deferred SX instances. This list is of temporalStateData
|
||||
* instances. */
|
||||
GList /* <temporalStateData*> */ *deferredList;
|
||||
GDate start_date;
|
||||
/* if end_date is invalid, then no end. */
|
||||
GDate end_date;
|
||||
|
||||
/* if num_occurances_total == 0, then no limit */
|
||||
gint num_occurances_total;
|
||||
/* reminaing occurances are as-of the 'last_date'. */
|
||||
gint num_occurances_remain;
|
||||
|
||||
/* the current instance-count of the SX. */
|
||||
gint instance_num;
|
||||
|
||||
gboolean enabled;
|
||||
gboolean autoCreateOption;
|
||||
gboolean autoCreateNotify;
|
||||
gint advanceCreateDays;
|
||||
gint advanceRemindDays;
|
||||
|
||||
Account *template_acct;
|
||||
|
||||
/** The list of deferred SX instances. This list is of temporalStateData
|
||||
* instances. */
|
||||
GList /* <temporalStateData*> */ *deferredList;
|
||||
};
|
||||
|
||||
struct _SchedXactionClass
|
||||
{
|
||||
QofInstanceClass parent_class;
|
||||
QofInstanceClass parent_class;
|
||||
};
|
||||
|
||||
/** Just the variable temporal bits from the SX structure. */
|
||||
typedef struct _temporalStateData {
|
||||
GDate last_date;
|
||||
gint num_occur_rem;
|
||||
gint num_inst;
|
||||
typedef struct _temporalStateData
|
||||
{
|
||||
GDate last_date;
|
||||
gint num_occur_rem;
|
||||
gint num_inst;
|
||||
} temporalStateData;
|
||||
|
||||
#define xaccSchedXactionSetGUID(X,G) qof_instance_set_guid(QOF_INSTANCE(X),(G))
|
||||
@@ -148,7 +149,8 @@ void gnc_sx_begin_edit (SchedXaction *sx);
|
||||
void gnc_sx_commit_edit (SchedXaction *sx);
|
||||
|
||||
/** @return GList<Recurrence*> **/
|
||||
/*@ dependent @*/ GList* gnc_sx_get_schedule(const SchedXaction *sx);
|
||||
/*@ dependent @*/
|
||||
GList* gnc_sx_get_schedule(const SchedXaction *sx);
|
||||
/** @param[in] schedule A GList<Recurrence*> **/
|
||||
void gnc_sx_set_schedule(SchedXaction *sx, /*@ null @*//*@ only @*/ GList *schedule);
|
||||
|
||||
@@ -314,12 +316,12 @@ gboolean SXRegister (void);
|
||||
#define xaccSchedXactionGetSlots(X) qof_instance_get_slots(QOF_INSTANCE(X))
|
||||
|
||||
/** \deprecated to be replaced with 'dirty' kvp's */
|
||||
KvpValue *xaccSchedXactionGetSlot( const SchedXaction *sx,
|
||||
const char *slot );
|
||||
KvpValue *xaccSchedXactionGetSlot( const SchedXaction *sx,
|
||||
const char *slot );
|
||||
/** \deprecated to be replaced with 'dirty' kvp's */
|
||||
void xaccSchedXactionSetSlot( SchedXaction *sx,
|
||||
const char *slot,
|
||||
const KvpValue *value );
|
||||
void xaccSchedXactionSetSlot( SchedXaction *sx,
|
||||
const char *slot,
|
||||
const KvpValue *value );
|
||||
|
||||
|
||||
#endif /* XACC_SCHEDXACTION_H */
|
||||
|
||||
@@ -30,19 +30,19 @@
|
||||
compatibility with older versions of GnuCash, and to fix
|
||||
or at least paper over possible current problems.
|
||||
|
||||
It is typically expected that the scrub routines are run
|
||||
It is typically expected that the scrub routines are run
|
||||
over newly imported data, as well as during data file input.
|
||||
|
||||
|
||||
In some cases, it is entirely appropriate to invoke these
|
||||
routines from the GUI, to validate that the user input
|
||||
through the GUI is in a format that the system likes.
|
||||
routines from the GUI, to validate that the user input
|
||||
through the GUI is in a format that the system likes.
|
||||
This includes things like balancing individual transactions,
|
||||
or assigning splits to lots, so that capital gains can be
|
||||
or assigning splits to lots, so that capital gains can be
|
||||
computed.
|
||||
@{ */
|
||||
|
||||
/** @file Scrub.h
|
||||
* @brief convert single-entry accounts to clean double-entry
|
||||
* @brief convert single-entry accounts to clean double-entry
|
||||
* @author Created by Linas Vepstas December 1998
|
||||
* @author Copyright (c) 1998-2000, 2003 Linas Vepstas <linas@linas.org>
|
||||
*/
|
||||
@@ -53,7 +53,7 @@
|
||||
#include "gnc-engine.h"
|
||||
|
||||
/** @name Double-Entry Scrubbing
|
||||
Convert single-entry accounts to clean double-entry
|
||||
Convert single-entry accounts to clean double-entry
|
||||
|
||||
Provides a set of functions and utilities for checking and
|
||||
repairing (formerly called 'scrubbing clean') single-entry accounts
|
||||
@@ -64,29 +64,29 @@
|
||||
|
||||
The ScrubOrphans() methods search for transacations that contain
|
||||
splits that do not have a parent account. These "orphaned splits"
|
||||
are placed into an "orphan account" which the user will have to
|
||||
are placed into an "orphan account" which the user will have to
|
||||
go into and clean up. Kind of like the unix "Lost+Found" directory
|
||||
for orphaned inodes.
|
||||
for orphaned inodes.
|
||||
@{ */
|
||||
|
||||
/** The xaccTransScrubOrphans() method scrubs only the splits in the
|
||||
* given transaction.
|
||||
* given transaction.
|
||||
*/
|
||||
void xaccTransScrubOrphans (Transaction *trans);
|
||||
|
||||
/** The xaccAccountScrubOrphans() method performs this scrub only for the
|
||||
/** The xaccAccountScrubOrphans() method performs this scrub only for the
|
||||
* indicated account, and not for any of its children.
|
||||
*/
|
||||
void xaccAccountScrubOrphans (Account *acc);
|
||||
|
||||
/** The xaccAccountTreeScrubOrphans() method performs this scrub for the
|
||||
/** The xaccAccountTreeScrubOrphans() method performs this scrub for the
|
||||
* indicated account and its children.
|
||||
*/
|
||||
void xaccAccountTreeScrubOrphans (Account *acc);
|
||||
|
||||
/** The xaccSplitScrub method ensures that if this split has the same
|
||||
* commodity and currency, then it will have the same amount and value.
|
||||
* If the commodity is the currency, the split->amount is set to the
|
||||
* commodity and currency, then it will have the same amount and value.
|
||||
* If the commodity is the currency, the split->amount is set to the
|
||||
* split value. In addition, if this split is an orphan, that is
|
||||
* fixed first. If the split account doesn't have a commodity declared,
|
||||
* an attempt is made to fix that first.
|
||||
@@ -94,7 +94,7 @@ void xaccAccountTreeScrubOrphans (Account *acc);
|
||||
void xaccSplitScrub (Split *split);
|
||||
|
||||
/** The xacc*ScrubSplits() calls xaccSplitScrub() on each split
|
||||
* in the respective structure: transaction, account,
|
||||
* in the respective structure: transaction, account,
|
||||
* account & it's children, account-group.
|
||||
*/
|
||||
void xaccTransScrubSplits (Transaction *trans);
|
||||
@@ -118,8 +118,8 @@ void xaccTransScrubCurrency (Transaction *trans);
|
||||
|
||||
/** The xaccTransScrubCurrencyFromSplits method fixes transactions
|
||||
* where the currency doesn't match the currency used in the splits
|
||||
* in the transaction. If all splits where the amount equals the
|
||||
* value and where the commodity is a currency have the same
|
||||
* in the transaction. If all splits where the amount equals the
|
||||
* value and where the commodity is a currency have the same
|
||||
* currency, it sets the transaction's currency to that if it is
|
||||
* anything else. If the splits don't match that description the
|
||||
* transaction currency is not changed. */
|
||||
|
||||
@@ -35,13 +35,13 @@
|
||||
#include "gnc-engine.h"
|
||||
|
||||
/** @name Lot Management Routines
|
||||
* Provides the low-level API for checking and repairing ('scrubbing
|
||||
* clean') the usage of Lots and lot balances in stock and commodity
|
||||
* accounts. Broken lots are repaired using a first-in, first-out
|
||||
* Provides the low-level API for checking and repairing ('scrubbing
|
||||
* clean') the usage of Lots and lot balances in stock and commodity
|
||||
* accounts. Broken lots are repaired using a first-in, first-out
|
||||
* (FIFO) accounting schedule.
|
||||
*
|
||||
* This is a 'low-level' API in the sense that each routine accomplishes
|
||||
* only one particular task needed to clean up a Lot. To clean up a
|
||||
*
|
||||
* This is a 'low-level' API in the sense that each routine accomplishes
|
||||
* only one particular task needed to clean up a Lot. To clean up a
|
||||
* Lot as a whole, you almost certainly want to use one of the
|
||||
* high-level API routines from the Scrub3.h file.
|
||||
@{ */
|
||||
@@ -49,11 +49,11 @@
|
||||
/** The xaccAccountAssignLots() routine will walk over all of
|
||||
* the splits in an account, and make sure that each belongs
|
||||
* to a lot. Currently, the default (and only implemented)
|
||||
* assignment policy is a FIFO policy: Any splits that are
|
||||
* assignment policy is a FIFO policy: Any splits that are
|
||||
* not in a lot will be used to close the oldest open lot(s).
|
||||
* If there are no open lots, a new lot will be started.
|
||||
* If there are no open lots, a new lot will be started.
|
||||
* By trying to close the oldest lots, this effectively
|
||||
* implements a FIFO acounting policy.
|
||||
* implements a FIFO acounting policy.
|
||||
*/
|
||||
void xaccAccountAssignLots (Account *acc);
|
||||
|
||||
@@ -61,20 +61,20 @@ void xaccAccountAssignLots (Account *acc);
|
||||
* indicated lot until the lot balance goes to zero, or until
|
||||
* there are no suitable (i.e. unassigned) splits left in the
|
||||
* account. It uses the default accounting policy to choose
|
||||
* the splits to fill out the lot.
|
||||
* the splits to fill out the lot.
|
||||
*/
|
||||
void xaccLotFill (GNCLot *lot);
|
||||
|
||||
/** The xaccLotScrubDoubleBalance() routine examines the indicated
|
||||
* lot. If it is open, it does nothing. If it is closed,
|
||||
* it then verifies that the lot is 'double balanced'.
|
||||
* By 'double balance', we mean that both the sum of the
|
||||
* split amounts is zero, and that the sum of the split
|
||||
* it then verifies that the lot is 'double balanced'.
|
||||
* By 'double balance', we mean that both the sum of the
|
||||
* split amounts is zero, and that the sum of the split
|
||||
* values is zero. If the lot is closed and the sum of the
|
||||
* values is not zero, the lot is considered to have a
|
||||
* 'realized gain or loss' that hadn't been correctly handled.
|
||||
* values is not zero, the lot is considered to have a
|
||||
* 'realized gain or loss' that hadn't been correctly handled.
|
||||
* This routine then creates a balancing transaction to so
|
||||
* as to record the realized gain/loss, adds it to the lot,
|
||||
* as to record the realized gain/loss, adds it to the lot,
|
||||
* and adds it to a gain/loss account. If there is no default
|
||||
* gain/loss account, it creates one.
|
||||
*/
|
||||
@@ -88,7 +88,7 @@ void xaccLotScrubDoubleBalance (GNCLot *lot);
|
||||
* of each so that they all have the same price.
|
||||
*
|
||||
* There is a bit of a problem with the interpretation of 'rounding
|
||||
* errors' because there are pathological corner cases of small
|
||||
* errors' because there are pathological corner cases of small
|
||||
* amounts. So this routine is loose, hopefully loose enough so
|
||||
* that the user can manually fine tune without having this routine
|
||||
* clobber thier work.
|
||||
@@ -96,7 +96,7 @@ void xaccLotScrubDoubleBalance (GNCLot *lot);
|
||||
* This routine ignores price differences smaller than 1/maxmult.
|
||||
* This routine ignores price differences when the split with a crazy
|
||||
* price involes only a small amount: specifically, an amount that
|
||||
* is less than maxamtscu/amount.denom.
|
||||
* is less than maxamtscu/amount.denom.
|
||||
*
|
||||
* Reasonable/recommended values might be maxmult=3, maxamtscu = 2.
|
||||
*/
|
||||
@@ -107,16 +107,16 @@ void xaccScrubSubSplitPrice (Split *split, int maxmult, int maxamtscu);
|
||||
* split, but are no longer needed to be kept separate. Splits
|
||||
* might be split up if they need to be divided over multiple
|
||||
* lots; they can be merged back together if the lots change.
|
||||
* In particular, two sub-splits may be merged if they are in
|
||||
* In particular, two sub-splits may be merged if they are in
|
||||
* the same lot, or in no lot. Note that, by definition, all
|
||||
* subsplits belong to the same transaction.
|
||||
*
|
||||
* The routine returns TRUE if a merger was performed, else
|
||||
* it returns FALSE.
|
||||
*
|
||||
* The xaccScrubMergeTransSubSplits() routine does the same, except
|
||||
* The routine returns TRUE if a merger was performed, else
|
||||
* it returns FALSE.
|
||||
*
|
||||
* The xaccScrubMergeTransSubSplits() routine does the same, except
|
||||
* that it does it for all of the splits in the transaction.
|
||||
* The xaccScrubMergeLotSubSplits() routine does the same, except
|
||||
* The xaccScrubMergeLotSubSplits() routine does the same, except
|
||||
* that it does it for all of the splits in the lot.
|
||||
*/
|
||||
gboolean xaccScrubMergeSubSplits (Split *split);
|
||||
|
||||
@@ -35,15 +35,15 @@
|
||||
#include "gnc-engine.h"
|
||||
|
||||
/** @name High-Level Lot Constraint
|
||||
* Provides the high-level API for checking and repairing ('scrubbing
|
||||
* clean') the usage of Lots and Cap Gains transactions in stock and
|
||||
* commodity accounts.
|
||||
* Provides the high-level API for checking and repairing ('scrubbing
|
||||
* clean') the usage of Lots and Cap Gains transactions in stock and
|
||||
* commodity accounts.
|
||||
@{ */
|
||||
|
||||
/** The xaccScrubLot() routine makes sure that the indicated lot is
|
||||
* self-consistent and properly balanced, and fixes it if its not.
|
||||
* This is an important routine to call if the amount of any split
|
||||
* in the lot is changed. That's because (obviously) changing
|
||||
* in the lot is changed. That's because (obviously) changing
|
||||
* split values is gaurenteed to throw off lot balances.
|
||||
* This routine may end up closing the lot, or at least trying
|
||||
* to. It will also cause cap gains to be recomputed.
|
||||
@@ -58,12 +58,12 @@ gboolean xaccScrubLot (GNCLot *lot);
|
||||
* in the account is assigned to a lot, and that then, every
|
||||
* lot is self-consistent (by calling xaccScrubLot() on each lot).
|
||||
*
|
||||
* This routine is the primary routine for ensuring that the
|
||||
* lot structure, and the cap-gains for an account are in good
|
||||
* This routine is the primary routine for ensuring that the
|
||||
* lot structure, and the cap-gains for an account are in good
|
||||
* order.
|
||||
*
|
||||
* Most GUI routines will want to use one of these xacc[*]ScrubLots()
|
||||
* routines, instead of the various component routines, since it will
|
||||
* routines, instead of the various component routines, since it will
|
||||
* usually makes sense to work only with these high-level routines.
|
||||
*/
|
||||
void xaccAccountScrubLots (Account *acc);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* This is the *private* header for the scrub routines.
|
||||
* No one outside of the engine should ever include this file.
|
||||
*
|
||||
* Copyright (C) 2003, Linas Vepstas <linas@linas.org>
|
||||
* Copyright (C) 2003, Linas Vepstas <linas@linas.org>
|
||||
*/
|
||||
|
||||
#ifndef XACC_SCRUB_P_H
|
||||
@@ -33,9 +33,9 @@
|
||||
#include "gnc-engine.h"
|
||||
|
||||
/* Utility to make account by name. Not for public use. */
|
||||
Account * xaccScrubUtilityGetOrMakeAccount (Account *root,
|
||||
gnc_commodity * currency, const char *accname,
|
||||
GNCAccountType acctype, gboolean placeholder);
|
||||
Account * xaccScrubUtilityGetOrMakeAccount (Account *root,
|
||||
gnc_commodity * currency, const char *accname,
|
||||
GNCAccountType acctype, gboolean placeholder);
|
||||
|
||||
|
||||
#endif /* XACC_SCRUB_P_H */
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
/** @addtogroup Engine
|
||||
@{ */
|
||||
/** @addtogroup Transaction Financial Transactions
|
||||
A good overview of transactions, splits and accounts can be
|
||||
A good overview of transactions, splits and accounts can be
|
||||
found in the texinfo documentation, together with an overview of
|
||||
how to use this API.
|
||||
|
||||
@{ */
|
||||
/** @file Split.h
|
||||
/** @file Split.h
|
||||
@brief API for Transactions and Splits (journal entries)
|
||||
@author Copyright (C) 1997 Robin D. Clark
|
||||
@author Copyright (C) 1997-2001 Linas Vepstas <linas@linas.org>
|
||||
@@ -134,7 +134,7 @@ GNCLot * xaccSplitGetLot (const Split *split);
|
||||
void xaccSplitSetLot(Split* split, GNCLot* lot);
|
||||
|
||||
|
||||
/** Returns the KvpFrame slots of this split for direct editing.
|
||||
/** Returns the KvpFrame slots of this split for direct editing.
|
||||
*
|
||||
* Split slots are used to store arbitrary strings, numbers, and
|
||||
* structures which aren't members of the transaction struct. See
|
||||
@@ -156,7 +156,7 @@ void xaccSplitSetMemo (Split *split, const char *memo);
|
||||
/** Returns the memo string. */
|
||||
const char * xaccSplitGetMemo (const Split *split);
|
||||
|
||||
/** The Action is an arbitrary user-assigned string.
|
||||
/** The Action is an arbitrary user-assigned string.
|
||||
* The action field is an arbitrary user-assigned value.
|
||||
* It is meant to be a very short (one to ten character) string that
|
||||
* signifies the "type" of this split, such as e.g. Buy, Sell, Div,
|
||||
@@ -186,15 +186,15 @@ void xaccSplitSetDateReconciledSecs (Split *split, time_t time);
|
||||
void xaccSplitSetDateReconciledTS (Split *split, Timespec *ts);
|
||||
/** Get the date on which this split was reconciled by having it
|
||||
* written into the Timespec that 'ts' is pointing to. */
|
||||
void xaccSplitGetDateReconciledTS (const Split *split,
|
||||
Timespec *ts);
|
||||
void xaccSplitGetDateReconciledTS (const Split *split,
|
||||
Timespec *ts);
|
||||
/** Returns the date (as Timespec) on which this split was reconciled. */
|
||||
Timespec xaccSplitRetDateReconciledTS (const Split *split);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
/** @name Split amount getters/setters
|
||||
/** @name Split amount getters/setters
|
||||
*
|
||||
* 'value' vs. 'amount' of a Split: The 'value' is the amount of the
|
||||
* _transaction_ balancing commodity (i.e. currency) involved,
|
||||
@@ -202,7 +202,7 @@ Timespec xaccSplitRetDateReconciledTS (const Split *split);
|
||||
@{
|
||||
*/
|
||||
|
||||
/** The xaccSplitSetAmount() method sets the amount in the account's
|
||||
/** The xaccSplitSetAmount() method sets the amount in the account's
|
||||
* commodity that the split should have.
|
||||
*
|
||||
* The following four setter functions set the prices and amounts.
|
||||
@@ -213,30 +213,30 @@ Timespec xaccSplitRetDateReconciledTS (const Split *split);
|
||||
* IMPORTANT: The split should be parented by an account before
|
||||
* any of these routines are invoked! This is because the actual
|
||||
* setting of amounts/values requires SCU settings from the account.
|
||||
* If these are not available, then amounts/values will be set to
|
||||
* If these are not available, then amounts/values will be set to
|
||||
* -1/0, which is an invalid value. I believe this order dependency
|
||||
* is a bug, but I'm too lazy to find, fix & test at the moment ...
|
||||
* is a bug, but I'm too lazy to find, fix & test at the moment ...
|
||||
*
|
||||
* @note If you use this on a newly created transaction, make sure
|
||||
* that the 'value' is also set so that it doesn't remain zero.
|
||||
*/
|
||||
void xaccSplitSetAmount (Split *split, gnc_numeric amount);
|
||||
|
||||
/** Returns the amount of the split in the account's commodity.
|
||||
/** Returns the amount of the split in the account's commodity.
|
||||
* Note that for cap-gains splits, this is slaved to the transaction
|
||||
* that is causing the gains to occur.
|
||||
*/
|
||||
gnc_numeric xaccSplitGetAmount (const Split * split);
|
||||
|
||||
/** The xaccSplitSetValue() method sets the value of this split in the
|
||||
* transaction's commodity.
|
||||
* transaction's commodity.
|
||||
*
|
||||
* @note If you use this on a newly created transaction, make sure
|
||||
* that the 'amount' is also set so that it doesn't remain zero.
|
||||
*/
|
||||
void xaccSplitSetValue (Split *split, gnc_numeric value);
|
||||
|
||||
/** Returns the value of this split in the transaction's commodity.
|
||||
/** Returns the value of this split in the transaction's commodity.
|
||||
* Note that for cap-gains splits, this is slaved to the transaction
|
||||
* that is causing the gains to occur.
|
||||
*/
|
||||
@@ -247,9 +247,9 @@ gnc_numeric xaccSplitGetValue (const Split * split);
|
||||
* routine that is equivalent to a xaccSplitSetSharePrice() followed
|
||||
* by and xaccSplitSetAmount(), except that it incurs the processing
|
||||
* overhead of balancing only once, instead of twice. */
|
||||
void xaccSplitSetSharePriceAndAmount (Split *split,
|
||||
gnc_numeric price,
|
||||
gnc_numeric amount);
|
||||
void xaccSplitSetSharePriceAndAmount (Split *split,
|
||||
gnc_numeric price,
|
||||
gnc_numeric amount);
|
||||
|
||||
/** Returns the price of the split, that is, the value divided by the
|
||||
* amount. If the amount is zero, returns a gnc_numeric of value
|
||||
@@ -259,7 +259,7 @@ gnc_numeric xaccSplitGetSharePrice (const Split * split);
|
||||
/** Depending on the base_currency, set either the value or the amount
|
||||
* of this split or both: If the base_currency is the transaction's
|
||||
* commodity, set the value. If it is the account's commodity, set the
|
||||
* amount. If both, set both.
|
||||
* amount. If both, set both.
|
||||
*
|
||||
* @note <b>WATCH OUT:</b> When using this function and the
|
||||
* transaction's and account's commodities are different, the amount
|
||||
@@ -278,24 +278,24 @@ void xaccSplitSetBaseValue (Split *split, gnc_numeric value,
|
||||
* return the amount. If it is neither print a warning message and
|
||||
* return gnc_numeric_zero().
|
||||
*/
|
||||
gnc_numeric xaccSplitGetBaseValue (const Split *split,
|
||||
gnc_numeric xaccSplitGetBaseValue (const Split *split,
|
||||
const gnc_commodity * base_currency);
|
||||
|
||||
/** Returns the running balance up to and including the indicated split.
|
||||
/** Returns the running balance up to and including the indicated split.
|
||||
* The balance is the currency-denominated balance. For accounts
|
||||
* with non-unit share prices, it is correctly adjusted for
|
||||
* share prices.
|
||||
*
|
||||
* Returns the running balance up to & including the indicated split.
|
||||
* Returns the running balance up to & including the indicated split.
|
||||
*/
|
||||
gnc_numeric xaccSplitGetBalance (const Split *split);
|
||||
|
||||
/**
|
||||
* The cleared-balance is the currency-denominated balance
|
||||
* The cleared-balance is the currency-denominated balance
|
||||
* of all transactions that have been marked as cleared or reconciled.
|
||||
* It is correctly adjusted for price fluctuations.
|
||||
*
|
||||
* Returns the running balance up to & including the indicated split.
|
||||
* Returns the running balance up to & including the indicated split.
|
||||
*/
|
||||
gnc_numeric xaccSplitGetClearedBalance (const Split *split);
|
||||
|
||||
@@ -304,13 +304,13 @@ gnc_numeric xaccSplitGetClearedBalance (const Split *split);
|
||||
* reconciled-balance is the currency-denominated balance of all
|
||||
* transactions that have been marked as reconciled.
|
||||
*
|
||||
* Returns the running balance up to & including the indicated split.
|
||||
* Returns the running balance up to & including the indicated split.
|
||||
*/
|
||||
gnc_numeric xaccSplitGetReconciledBalance (const Split *split);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @name Split utility functions
|
||||
/** @name Split utility functions
|
||||
@{
|
||||
*/
|
||||
|
||||
@@ -336,7 +336,7 @@ GList *xaccSplitListGetUniqueTransactions(const GList *splits);
|
||||
*/
|
||||
gboolean xaccSplitEqual(const Split *sa, const Split *sb,
|
||||
gboolean check_guids,
|
||||
gboolean check_balances,
|
||||
gboolean check_balances,
|
||||
gboolean check_txn_splits);
|
||||
|
||||
/** The xaccSplitLookup() subroutine will return the
|
||||
@@ -346,9 +346,9 @@ Split * xaccSplitLookup (const GUID *guid, QofBook *book);
|
||||
#define xaccSplitLookupDirect(g,b) xaccSplitLookup(&(g),b)
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* The xaccSplitGetOtherSplit() is a convenience routine that returns
|
||||
* the other of a pair of splits. If there are more than two
|
||||
* the other of a pair of splits. If there are more than two
|
||||
* splits, it returns NULL.
|
||||
*/
|
||||
Split * xaccSplitGetOtherSplit (const Split *split);
|
||||
@@ -372,8 +372,8 @@ void xaccSplitMakeStockSplit(Split *s);
|
||||
* if sa and sb have different transactions, return their xaccTransOrder
|
||||
* return a negative value if split sa has a smaller currency-value than sb,
|
||||
* return a positive value if split sa has a larger currency-value than sb,
|
||||
* return a negative value if split sa has a smaller share-price than sb,
|
||||
* return a positive value if split sa has a larger share-price than sb,
|
||||
* return a negative value if split sa has a smaller share-price than sb,
|
||||
* return a positive value if split sa has a larger share-price than sb,
|
||||
* then compares memo and action using the strcmp()
|
||||
* c-library routine, returning what strcmp would return.
|
||||
* Then it compares the reconciled flags, then the reconciled dates,
|
||||
@@ -384,9 +384,9 @@ gint xaccSplitOrderDateOnly (const Split *sa, const Split *sb);
|
||||
|
||||
|
||||
/*
|
||||
* These functions compare two splits by different criteria.
|
||||
* These functions compare two splits by different criteria.
|
||||
*
|
||||
* These functions were added because converting strings to guile
|
||||
* These functions were added because converting strings to guile
|
||||
* for comparisons in the transaction report is terribly inefficient.
|
||||
* More may be added here in future if it turns out that other types
|
||||
* of comparisons also induces guile slowdowns.
|
||||
@@ -411,11 +411,11 @@ int xaccSplitCompareOtherAccountCodes(const Split *sa, const Split *sb);
|
||||
/**
|
||||
* These functions take a split, get the corresponding split on the
|
||||
* "other side" of the transaction, and extract either the name or code
|
||||
* of that split, reverting to returning a constant "Split" if the
|
||||
* of that split, reverting to returning a constant "Split" if the
|
||||
* transaction has more than one split on the "other side". These
|
||||
* were added for the transaction report, and is in C because the code
|
||||
* was already written in C for the above functions and duplication
|
||||
* is silly.
|
||||
* was already written in C for the above functions and duplication
|
||||
* is silly.
|
||||
*/
|
||||
|
||||
char * xaccSplitGetCorrAccountFullName(const Split *sa);
|
||||
@@ -432,7 +432,7 @@ void xaccSplitDump (const Split *split, const char *tag);
|
||||
|
||||
|
||||
|
||||
/** @name Split deprecated functions
|
||||
/** @name Split deprecated functions
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
* SplitP.h
|
||||
*
|
||||
* FUNCTION:
|
||||
* The is the *private* split header file. Code outside of
|
||||
* The is the *private* split header file. Code outside of
|
||||
* engine should *not* include this file. This is because code
|
||||
* outside of the engine should *never* access any of the structure
|
||||
* members directly.
|
||||
@@ -70,66 +70,66 @@
|
||||
|
||||
struct split_s
|
||||
{
|
||||
QofInstance inst;
|
||||
QofInstance inst;
|
||||
|
||||
Account *acc; /* back-pointer to debited/credited account */
|
||||
Account *orig_acc;
|
||||
GNCLot *lot; /* back-pointer to debited/credited lot */
|
||||
Account *acc; /* back-pointer to debited/credited account */
|
||||
Account *orig_acc;
|
||||
GNCLot *lot; /* back-pointer to debited/credited lot */
|
||||
|
||||
Transaction *parent; /* parent of split */
|
||||
Transaction *orig_parent;
|
||||
Transaction *parent; /* parent of split */
|
||||
Transaction *orig_parent;
|
||||
|
||||
/* The memo field is an arbitrary user-assiged value.
|
||||
* It is intended to hold a short (zero to forty character) string
|
||||
* that is displayed by the GUI along with this split.
|
||||
*/
|
||||
char * memo;
|
||||
/* The memo field is an arbitrary user-assiged value.
|
||||
* It is intended to hold a short (zero to forty character) string
|
||||
* that is displayed by the GUI along with this split.
|
||||
*/
|
||||
char * memo;
|
||||
|
||||
/* The action field is an arbitrary user-assigned value.
|
||||
* It is meant to be a very short (one to ten character) string that
|
||||
* signifies the "type" of this split, such as e.g. Buy, Sell, Div,
|
||||
* Withdraw, Deposit, ATM, Check, etc. The idea is that this field
|
||||
* can be used to create custom reports or graphs of data.
|
||||
*/
|
||||
char * action; /* Buy, Sell, Div, etc. */
|
||||
/* The action field is an arbitrary user-assigned value.
|
||||
* It is meant to be a very short (one to ten character) string that
|
||||
* signifies the "type" of this split, such as e.g. Buy, Sell, Div,
|
||||
* Withdraw, Deposit, ATM, Check, etc. The idea is that this field
|
||||
* can be used to create custom reports or graphs of data.
|
||||
*/
|
||||
char * action; /* Buy, Sell, Div, etc. */
|
||||
|
||||
Timespec date_reconciled; /* date split was reconciled */
|
||||
char reconciled; /* The reconciled field */
|
||||
Timespec date_reconciled; /* date split was reconciled */
|
||||
char reconciled; /* The reconciled field */
|
||||
|
||||
/* gains is a flag used to track the relationship between
|
||||
* capital-gains splits. Depending on its value, this flag indicates
|
||||
* if this split is the source of gains, if this split is a record
|
||||
* of the gains, and if values are 'dirty' and need to be recomputed.
|
||||
*/
|
||||
unsigned char gains;
|
||||
/* gains is a flag used to track the relationship between
|
||||
* capital-gains splits. Depending on its value, this flag indicates
|
||||
* if this split is the source of gains, if this split is a record
|
||||
* of the gains, and if values are 'dirty' and need to be recomputed.
|
||||
*/
|
||||
unsigned char gains;
|
||||
|
||||
/* 'gains_split' is a convenience pointer used to track down the
|
||||
* other end of a cap-gains transaction pair. NULL if this split
|
||||
* doesn't involve cap gains.
|
||||
*/
|
||||
Split *gains_split;
|
||||
/* 'gains_split' is a convenience pointer used to track down the
|
||||
* other end of a cap-gains transaction pair. NULL if this split
|
||||
* doesn't involve cap gains.
|
||||
*/
|
||||
Split *gains_split;
|
||||
|
||||
/* 'value' is the quantity of the transaction balancing commodity
|
||||
* (i.e. currency) involved, 'amount' is the amount of the account's
|
||||
* commodity involved. */
|
||||
gnc_numeric value;
|
||||
gnc_numeric amount;
|
||||
/* 'value' is the quantity of the transaction balancing commodity
|
||||
* (i.e. currency) involved, 'amount' is the amount of the account's
|
||||
* commodity involved. */
|
||||
gnc_numeric value;
|
||||
gnc_numeric amount;
|
||||
|
||||
/* -------------------------------------------------------------- */
|
||||
/* Below follow some 'temporary' fields */
|
||||
/* -------------------------------------------------------------- */
|
||||
/* Below follow some 'temporary' fields */
|
||||
|
||||
/* The various "balances" are the sum of all of the values of
|
||||
* all the splits in the account, up to and including this split.
|
||||
* These balances apply to a sorting order by date posted
|
||||
* (not by date entered). */
|
||||
gnc_numeric balance;
|
||||
gnc_numeric cleared_balance;
|
||||
gnc_numeric reconciled_balance;
|
||||
/* The various "balances" are the sum of all of the values of
|
||||
* all the splits in the account, up to and including this split.
|
||||
* These balances apply to a sorting order by date posted
|
||||
* (not by date entered). */
|
||||
gnc_numeric balance;
|
||||
gnc_numeric cleared_balance;
|
||||
gnc_numeric reconciled_balance;
|
||||
};
|
||||
|
||||
struct _SplitClass
|
||||
{
|
||||
QofInstanceClass parent_class;
|
||||
QofInstanceClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
@@ -140,8 +140,8 @@ struct _SplitClass
|
||||
|
||||
/* The xaccFreeSplit() method simply frees all memory associated
|
||||
* with the split. It does not verify that the split isn't
|
||||
* referenced in some account. If the split is referenced by an
|
||||
* account, then calling this method will leave the system in an
|
||||
* referenced in some account. If the split is referenced by an
|
||||
* account, then calling this method will leave the system in an
|
||||
* inconsistent state. This *will* lead to crashes and hangs.
|
||||
*/
|
||||
void xaccFreeSplit (Split *split); /* frees memory */
|
||||
@@ -164,35 +164,35 @@ gnc_numeric xaccSplitsComputeValue (GList *splits, const Split * skip_me,
|
||||
/* Code to register Split type with the engine */
|
||||
gboolean xaccSplitRegister (void);
|
||||
|
||||
/* The xaccSplitDetermineGainStatus() routine will analyze the
|
||||
* the split, and try to set the internal status flags
|
||||
/* The xaccSplitDetermineGainStatus() routine will analyze the
|
||||
* the split, and try to set the internal status flags
|
||||
* appropriately for the split. These flags indicate if the split
|
||||
* represents cap gains, and if the gains value/amount needs to be
|
||||
* represents cap gains, and if the gains value/amount needs to be
|
||||
* recomputed.
|
||||
*/
|
||||
void xaccSplitDetermineGainStatus (Split *split);
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Deprecated routines */
|
||||
void DxaccSplitSetSharePriceAndAmount (Split *split,
|
||||
double price,
|
||||
double amount);
|
||||
void DxaccSplitSetSharePriceAndAmount (Split *split,
|
||||
double price,
|
||||
double amount);
|
||||
void DxaccSplitSetShareAmount (Split *split, double amount);
|
||||
|
||||
/********************************************************************\
|
||||
* sorting comparison function
|
||||
*
|
||||
* returns a negative value if transaction a is dated earlier than b,
|
||||
* returns a positive value if transaction a is dated later than b,
|
||||
* returns a negative value if transaction a is dated earlier than b,
|
||||
* 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 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
|
||||
* fields are compared. If these are identical, then the memo fields
|
||||
* are compared. Hopefully, there will not be any transactions that
|
||||
* occur on the same day that have all three of these values identical.
|
||||
*
|
||||
* Note that being able to establish this kind of absolute order is
|
||||
* Note that being able to establish this kind of absolute order is
|
||||
* important for some of the ledger display functions.
|
||||
*
|
||||
* Yes, this kind of code dependency is ugly, but the alternatives seem
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include "TransLog.h"
|
||||
#include "qof.h"
|
||||
|
||||
/*
|
||||
/*
|
||||
* Some design philosphy that I think would be good to keep in mind:
|
||||
* (0) Simplicity and foolproofness are the over-riding design points.
|
||||
* This is supposed to be a fail-safe safety net. We don't want
|
||||
@@ -47,31 +47,31 @@
|
||||
* (2.a) Keep the format, simple, flat, more or less unstructured,
|
||||
* record oriented. This will help parsing by perl scripts.
|
||||
* No, using a perl script to analyze a file that's supposed to
|
||||
* be human readable is not a contradication in terms -- that's
|
||||
* be human readable is not a contradication in terms -- that's
|
||||
* exactly the point.
|
||||
* (2.b) Use tabs as a human friendly field separator; its also a
|
||||
* character that does not (should not) appear naturally anywhere
|
||||
* in the data, as it serves no formatting purpose in the current
|
||||
* GUI design. (hack alert -- this is not currently tested for
|
||||
* or enforced, so this is a very unsafe assumption. Maybe
|
||||
* (2.b) Use tabs as a human friendly field separator; its also a
|
||||
* character that does not (should not) appear naturally anywhere
|
||||
* in the data, as it serves no formatting purpose in the current
|
||||
* GUI design. (hack alert -- this is not currently tested for
|
||||
* or enforced, so this is a very unsafe assumption. Maybe
|
||||
* urlencoding should be used.)
|
||||
* (2.c) Don't print redundant information in a single record. This
|
||||
* (2.c) Don't print redundant information in a single record. This
|
||||
* would just confuse any potential user of this file.
|
||||
* (2.d) Saving space, being compact is not a priority, I don't think.
|
||||
*
|
||||
*
|
||||
* (3) There are no compatibility requirements from release to release.
|
||||
* Sounds OK to me to change the format of the output when needed.
|
||||
*
|
||||
* (-) print transaction start and end delimiters
|
||||
* (-) print a unique transaction id as a handy label for anyone
|
||||
* who actually examines these logs.
|
||||
* The C address pointer to the transaction struct should be fine,
|
||||
* (-) print a unique transaction id as a handy label for anyone
|
||||
* who actually examines these logs.
|
||||
* The C address pointer to the transaction struct should be fine,
|
||||
* as it is simple and unique until the transaction is deleted ...
|
||||
* and we log deletions, so that's OK. Just note that the id
|
||||
* for a deleted transaction might be recycled.
|
||||
* (-) print the current timestamp, so that if it is known that a bug
|
||||
* occurred at a certain time, it can be located.
|
||||
* (-) hack alert -- something better than just the account name
|
||||
* (-) hack alert -- something better than just the account name
|
||||
* is needed for identifying the account.
|
||||
*/
|
||||
/* ------------------------------------------------------------------ */
|
||||
@@ -85,34 +85,42 @@ static char * log_base_name = NULL;
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
void xaccLogDisable (void) { gen_logs = 0; }
|
||||
void xaccLogEnable (void) { gen_logs = 1; }
|
||||
void xaccLogDisable (void)
|
||||
{
|
||||
gen_logs = 0;
|
||||
}
|
||||
void xaccLogEnable (void)
|
||||
{
|
||||
gen_logs = 1;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
void
|
||||
void
|
||||
xaccReopenLog (void)
|
||||
{
|
||||
if (trans_log) {
|
||||
xaccCloseLog();
|
||||
xaccOpenLog();
|
||||
}
|
||||
if (trans_log)
|
||||
{
|
||||
xaccCloseLog();
|
||||
xaccOpenLog();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
xaccLogSetBaseName (const char *basepath)
|
||||
{
|
||||
if (!basepath) return;
|
||||
if (!basepath) return;
|
||||
|
||||
g_free (log_base_name);
|
||||
log_base_name = g_strdup (basepath);
|
||||
g_free (log_base_name);
|
||||
log_base_name = g_strdup (basepath);
|
||||
|
||||
if (trans_log) {
|
||||
xaccCloseLog();
|
||||
xaccOpenLog();
|
||||
}
|
||||
if (trans_log)
|
||||
{
|
||||
xaccCloseLog();
|
||||
xaccOpenLog();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -125,16 +133,16 @@ xaccLogSetBaseName (const char *basepath)
|
||||
gboolean
|
||||
xaccFileIsCurrentLog (const gchar *name)
|
||||
{
|
||||
gchar *base;
|
||||
gint result;
|
||||
gchar *base;
|
||||
gint result;
|
||||
|
||||
if (!name || !trans_log_name)
|
||||
return FALSE;
|
||||
if (!name || !trans_log_name)
|
||||
return FALSE;
|
||||
|
||||
base = g_path_get_basename(name);
|
||||
result = (strcmp(base, trans_log_name) == 0);
|
||||
g_free(base);
|
||||
return result;
|
||||
base = g_path_get_basename(name);
|
||||
result = (strcmp(base, trans_log_name) == 0);
|
||||
g_free(base);
|
||||
return result;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
@@ -143,45 +151,46 @@ xaccFileIsCurrentLog (const gchar *name)
|
||||
void
|
||||
xaccOpenLog (void)
|
||||
{
|
||||
char * filename;
|
||||
char * timestamp;
|
||||
char * filename;
|
||||
char * timestamp;
|
||||
|
||||
if (!gen_logs) return;
|
||||
if (trans_log) return;
|
||||
if (!gen_logs) return;
|
||||
if (trans_log) return;
|
||||
|
||||
if (!log_base_name) log_base_name = g_strdup ("translog");
|
||||
if (!log_base_name) log_base_name = g_strdup ("translog");
|
||||
|
||||
/* tag each filename with a timestamp */
|
||||
timestamp = xaccDateUtilGetStampNow ();
|
||||
/* tag each filename with a timestamp */
|
||||
timestamp = xaccDateUtilGetStampNow ();
|
||||
|
||||
filename = g_strconcat (log_base_name, ".", timestamp, ".log", NULL);
|
||||
filename = g_strconcat (log_base_name, ".", timestamp, ".log", NULL);
|
||||
|
||||
trans_log = g_fopen (filename, "a");
|
||||
if (!trans_log) {
|
||||
int norr = errno;
|
||||
printf ("Error: xaccOpenLog(): cannot open journal \n"
|
||||
"\t %d %s\n", norr, strerror (norr));
|
||||
trans_log = g_fopen (filename, "a");
|
||||
if (!trans_log)
|
||||
{
|
||||
int norr = errno;
|
||||
printf ("Error: xaccOpenLog(): cannot open journal \n"
|
||||
"\t %d %s\n", norr, strerror (norr));
|
||||
|
||||
g_free (filename);
|
||||
g_free (timestamp);
|
||||
return;
|
||||
}
|
||||
g_free (filename);
|
||||
g_free (timestamp);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save the log file name */
|
||||
if (trans_log_name)
|
||||
g_free (trans_log_name);
|
||||
trans_log_name = g_path_get_basename(filename);
|
||||
/* Save the log file name */
|
||||
if (trans_log_name)
|
||||
g_free (trans_log_name);
|
||||
trans_log_name = g_path_get_basename(filename);
|
||||
|
||||
g_free (filename);
|
||||
g_free (timestamp);
|
||||
g_free (filename);
|
||||
g_free (timestamp);
|
||||
|
||||
/* Note: this must match src/import-export/log-replay/gnc-log-replay.c */
|
||||
fprintf (trans_log, "mod\ttrans_guid\tsplit_guid\ttime_now\t"
|
||||
"date_entered\tdate_posted\t"
|
||||
"acc_guid\tacc_name\tnum\tdescription\t"
|
||||
"notes\tmemo\taction\treconciled\t"
|
||||
"amount\tvalue\tdate_reconciled\n");
|
||||
fprintf (trans_log, "-----------------\n");
|
||||
/* Note: this must match src/import-export/log-replay/gnc-log-replay.c */
|
||||
fprintf (trans_log, "mod\ttrans_guid\tsplit_guid\ttime_now\t"
|
||||
"date_entered\tdate_posted\t"
|
||||
"acc_guid\tacc_name\tnum\tdescription\t"
|
||||
"notes\tmemo\taction\treconciled\t"
|
||||
"amount\tvalue\tdate_reconciled\n");
|
||||
fprintf (trans_log, "-----------------\n");
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
@@ -190,10 +199,10 @@ xaccOpenLog (void)
|
||||
void
|
||||
xaccCloseLog (void)
|
||||
{
|
||||
if (!trans_log) return;
|
||||
fflush (trans_log);
|
||||
fclose (trans_log);
|
||||
trans_log = NULL;
|
||||
if (!trans_log) return;
|
||||
fflush (trans_log);
|
||||
fclose (trans_log);
|
||||
trans_log = NULL;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
@@ -202,85 +211,85 @@ xaccCloseLog (void)
|
||||
void
|
||||
xaccTransWriteLog (Transaction *trans, char flag)
|
||||
{
|
||||
GList *node;
|
||||
char trans_guid_str[GUID_ENCODING_LENGTH+1];
|
||||
char split_guid_str[GUID_ENCODING_LENGTH+1];
|
||||
const char *trans_notes;
|
||||
char dnow[100], dent[100], dpost[100], drecn[100];
|
||||
Timespec ts;
|
||||
GList *node;
|
||||
char trans_guid_str[GUID_ENCODING_LENGTH+1];
|
||||
char split_guid_str[GUID_ENCODING_LENGTH+1];
|
||||
const char *trans_notes;
|
||||
char dnow[100], dent[100], dpost[100], drecn[100];
|
||||
Timespec ts;
|
||||
|
||||
if (!gen_logs) return;
|
||||
if (!trans_log) return;
|
||||
if (!gen_logs) return;
|
||||
if (!trans_log) return;
|
||||
|
||||
timespecFromTime_t(&ts,time(NULL));
|
||||
gnc_timespec_to_iso8601_buff (ts, dnow);
|
||||
timespecFromTime_t(&ts, time(NULL));
|
||||
gnc_timespec_to_iso8601_buff (ts, dnow);
|
||||
|
||||
timespecFromTime_t(&ts,trans->date_entered.tv_sec);
|
||||
gnc_timespec_to_iso8601_buff (ts, dent);
|
||||
timespecFromTime_t(&ts, trans->date_entered.tv_sec);
|
||||
gnc_timespec_to_iso8601_buff (ts, dent);
|
||||
|
||||
timespecFromTime_t(&ts,trans->date_posted.tv_sec);
|
||||
gnc_timespec_to_iso8601_buff (ts, dpost);
|
||||
timespecFromTime_t(&ts, trans->date_posted.tv_sec);
|
||||
gnc_timespec_to_iso8601_buff (ts, dpost);
|
||||
|
||||
guid_to_string_buff (xaccTransGetGUID(trans), trans_guid_str);
|
||||
trans_notes = xaccTransGetNotes(trans);
|
||||
fprintf (trans_log, "===== START\n");
|
||||
guid_to_string_buff (xaccTransGetGUID(trans), trans_guid_str);
|
||||
trans_notes = xaccTransGetNotes(trans);
|
||||
fprintf (trans_log, "===== START\n");
|
||||
|
||||
for (node = trans->splits; node; node = node->next)
|
||||
{
|
||||
Split *split = node->data;
|
||||
const char * accname = "";
|
||||
char acc_guid_str[GUID_ENCODING_LENGTH+1];
|
||||
gnc_numeric amt,val;
|
||||
for (node = trans->splits; node; node = node->next)
|
||||
{
|
||||
Split *split = node->data;
|
||||
const char * accname = "";
|
||||
char acc_guid_str[GUID_ENCODING_LENGTH+1];
|
||||
gnc_numeric amt, val;
|
||||
|
||||
if (xaccSplitGetAccount(split))
|
||||
{
|
||||
accname = xaccAccountGetName (xaccSplitGetAccount(split));
|
||||
guid_to_string_buff(xaccAccountGetGUID(xaccSplitGetAccount(split)),
|
||||
acc_guid_str);
|
||||
}
|
||||
else
|
||||
{
|
||||
acc_guid_str[0] = '\0';
|
||||
}
|
||||
|
||||
timespecFromTime_t(&ts,split->date_reconciled.tv_sec);
|
||||
gnc_timespec_to_iso8601_buff (ts, drecn);
|
||||
if (xaccSplitGetAccount(split))
|
||||
{
|
||||
accname = xaccAccountGetName (xaccSplitGetAccount(split));
|
||||
guid_to_string_buff(xaccAccountGetGUID(xaccSplitGetAccount(split)),
|
||||
acc_guid_str);
|
||||
}
|
||||
else
|
||||
{
|
||||
acc_guid_str[0] = '\0';
|
||||
}
|
||||
|
||||
guid_to_string_buff (xaccSplitGetGUID(split), split_guid_str);
|
||||
amt = xaccSplitGetAmount (split);
|
||||
val = xaccSplitGetValue (split);
|
||||
timespecFromTime_t(&ts, split->date_reconciled.tv_sec);
|
||||
gnc_timespec_to_iso8601_buff (ts, drecn);
|
||||
|
||||
/* use tab-separated fields */
|
||||
fprintf (trans_log,
|
||||
"%c\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t"
|
||||
"%s\t%s\t%s\t%s\t%c\t%" G_GINT64_FORMAT "/%" G_GINT64_FORMAT "\t%" G_GINT64_FORMAT "/%" G_GINT64_FORMAT "\t%s\n",
|
||||
flag,
|
||||
trans_guid_str, split_guid_str, /* trans+split make up unique id */
|
||||
/* Note that the next three strings always exist,
|
||||
* so we don't need to test them. */
|
||||
dnow,
|
||||
dent,
|
||||
dpost,
|
||||
acc_guid_str,
|
||||
accname ? accname : "",
|
||||
trans->num ? trans->num : "",
|
||||
trans->description ? trans->description : "",
|
||||
trans_notes ? trans_notes : "",
|
||||
split->memo ? split->memo : "",
|
||||
split->action ? split->action : "",
|
||||
split->reconciled,
|
||||
gnc_numeric_num(amt),
|
||||
gnc_numeric_denom(amt),
|
||||
gnc_numeric_num(val),
|
||||
gnc_numeric_denom(val),
|
||||
/* The next string always exists. No need to test it. */
|
||||
drecn);
|
||||
}
|
||||
guid_to_string_buff (xaccSplitGetGUID(split), split_guid_str);
|
||||
amt = xaccSplitGetAmount (split);
|
||||
val = xaccSplitGetValue (split);
|
||||
|
||||
fprintf (trans_log, "===== END\n");
|
||||
/* use tab-separated fields */
|
||||
fprintf (trans_log,
|
||||
"%c\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t"
|
||||
"%s\t%s\t%s\t%s\t%c\t%" G_GINT64_FORMAT "/%" G_GINT64_FORMAT "\t%" G_GINT64_FORMAT "/%" G_GINT64_FORMAT "\t%s\n",
|
||||
flag,
|
||||
trans_guid_str, split_guid_str, /* trans+split make up unique id */
|
||||
/* Note that the next three strings always exist,
|
||||
* so we don't need to test them. */
|
||||
dnow,
|
||||
dent,
|
||||
dpost,
|
||||
acc_guid_str,
|
||||
accname ? accname : "",
|
||||
trans->num ? trans->num : "",
|
||||
trans->description ? trans->description : "",
|
||||
trans_notes ? trans_notes : "",
|
||||
split->memo ? split->memo : "",
|
||||
split->action ? split->action : "",
|
||||
split->reconciled,
|
||||
gnc_numeric_num(amt),
|
||||
gnc_numeric_denom(amt),
|
||||
gnc_numeric_num(val),
|
||||
gnc_numeric_denom(val),
|
||||
/* The next string always exists. No need to test it. */
|
||||
drecn);
|
||||
}
|
||||
|
||||
/* get data out to the disk */
|
||||
fflush (trans_log);
|
||||
fprintf (trans_log, "===== END\n");
|
||||
|
||||
/* get data out to the disk */
|
||||
fflush (trans_log);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
@@ -294,109 +303,122 @@ xaccTransWriteLog (Transaction *trans, char flag)
|
||||
*/
|
||||
|
||||
char *
|
||||
xaccSplitAsString(Split *split, const char prefix[])
|
||||
xaccSplitAsString(Split *split, const char prefix[])
|
||||
{
|
||||
char *result = NULL;
|
||||
size_t result_size;
|
||||
FILE *stream = open_memstream(&result, &result_size);
|
||||
const char *split_memo = xaccSplitGetMemo(split);
|
||||
const double split_value = gnc_numeric_to_double(xaccSplitGetValue(split));
|
||||
Account *split_dest = xaccSplitGetAccount(split);
|
||||
const char *dest_name =
|
||||
split_dest ? xaccAccountGetName(split_dest) : NULL;
|
||||
char *result = NULL;
|
||||
size_t result_size;
|
||||
FILE *stream = open_memstream(&result, &result_size);
|
||||
const char *split_memo = xaccSplitGetMemo(split);
|
||||
const double split_value = gnc_numeric_to_double(xaccSplitGetValue(split));
|
||||
Account *split_dest = xaccSplitGetAccount(split);
|
||||
const char *dest_name =
|
||||
split_dest ? xaccAccountGetName(split_dest) : NULL;
|
||||
|
||||
g_return_val_if_fail (stream, NULL);
|
||||
g_return_val_if_fail (stream, NULL);
|
||||
|
||||
fputc('\n', stream);
|
||||
fputs(prefix, stream);
|
||||
fprintf(stream, " %10.2f | %15s | %s",
|
||||
split_value,
|
||||
dest_name ? dest_name : "<no-account-name>",
|
||||
split_memo ? split_memo : "<no-split-memo>");
|
||||
fclose(stream);
|
||||
return(result);
|
||||
fputc('\n', stream);
|
||||
fputs(prefix, stream);
|
||||
fprintf(stream, " %10.2f | %15s | %s",
|
||||
split_value,
|
||||
dest_name ? dest_name : "<no-account-name>",
|
||||
split_memo ? split_memo : "<no-split-memo>");
|
||||
fclose(stream);
|
||||
return(result);
|
||||
}
|
||||
|
||||
static char *
|
||||
xaccTransGetDateStr (Transaction *trans)
|
||||
{
|
||||
char buf [MAX_DATE_LENGTH];
|
||||
struct tm *date;
|
||||
time_t secs;
|
||||
char buf [MAX_DATE_LENGTH];
|
||||
struct tm *date;
|
||||
time_t secs;
|
||||
|
||||
secs = xaccTransGetDate (trans);
|
||||
secs = xaccTransGetDate (trans);
|
||||
|
||||
date = localtime (&secs);
|
||||
date = localtime (&secs);
|
||||
|
||||
qof_print_date_buff(buf, date->tm_mday, date->tm_mon+1, date->tm_year +1900);
|
||||
qof_print_date_buff(buf, date->tm_mday, date->tm_mon + 1, date->tm_year + 1900);
|
||||
|
||||
return g_strdup (buf);
|
||||
return g_strdup (buf);
|
||||
}
|
||||
|
||||
char *
|
||||
xaccTransAsString(Transaction *txn, const char prefix[])
|
||||
xaccTransAsString(Transaction *txn, const char prefix[])
|
||||
{
|
||||
char *result = NULL;
|
||||
size_t result_size;
|
||||
FILE *stream = open_memstream(&result, &result_size);
|
||||
time_t date = xaccTransGetDate(txn);
|
||||
const char *num = xaccTransGetNum(txn);
|
||||
const char *desc = xaccTransGetDescription(txn);
|
||||
const char *memo = xaccSplitGetMemo(xaccTransGetSplit(txn, 0));
|
||||
const double total = gnc_numeric_to_double(xaccSplitGetValue(xaccTransGetSplit(txn, 0)));
|
||||
|
||||
g_return_val_if_fail (stream, NULL);
|
||||
char *result = NULL;
|
||||
size_t result_size;
|
||||
FILE *stream = open_memstream(&result, &result_size);
|
||||
time_t date = xaccTransGetDate(txn);
|
||||
const char *num = xaccTransGetNum(txn);
|
||||
const char *desc = xaccTransGetDescription(txn);
|
||||
const char *memo = xaccSplitGetMemo(xaccTransGetSplit(txn, 0));
|
||||
const double total = gnc_numeric_to_double(xaccSplitGetValue(xaccTransGetSplit(txn, 0)));
|
||||
|
||||
fputs(prefix, stream);
|
||||
if(date) {
|
||||
char *datestr = xaccTransGetDateStr(txn);
|
||||
fprintf(stream, "%s", datestr);
|
||||
free(datestr);
|
||||
} else {
|
||||
fprintf(stream, "<no-date>");
|
||||
}
|
||||
fputc(' ', stream);
|
||||
if(num) {
|
||||
fputs(num, stream);
|
||||
} else {
|
||||
fprintf(stream, "<no-num>");
|
||||
}
|
||||
g_return_val_if_fail (stream, NULL);
|
||||
|
||||
fputc('\n', stream);
|
||||
fputs(prefix, stream);
|
||||
if(desc) {
|
||||
fputs(" ", stream);
|
||||
fputs(desc, stream);
|
||||
} else {
|
||||
fprintf(stream, "<no-description>");
|
||||
}
|
||||
|
||||
fputc('\n', stream);
|
||||
fputs(prefix, stream);
|
||||
if(memo) {
|
||||
fputs(" ", stream);
|
||||
fputs(memo, stream);
|
||||
} else {
|
||||
fprintf(stream, "<no-transaction-memo>");
|
||||
}
|
||||
|
||||
{
|
||||
int split_count = xaccTransCountSplits(txn);
|
||||
int i;
|
||||
for(i = 1; i < split_count; i++) {
|
||||
Split *split = xaccTransGetSplit(txn, i);
|
||||
char *split_text = xaccSplitAsString(split, prefix);
|
||||
fputs(split_text, stream);
|
||||
free(split_text);
|
||||
fputs(prefix, stream);
|
||||
if (date)
|
||||
{
|
||||
char *datestr = xaccTransGetDateStr(txn);
|
||||
fprintf(stream, "%s", datestr);
|
||||
free(datestr);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stream, "<no-date>");
|
||||
}
|
||||
fputc(' ', stream);
|
||||
if (num)
|
||||
{
|
||||
fputs(num, stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stream, "<no-num>");
|
||||
}
|
||||
}
|
||||
fputc('\n', stream);
|
||||
|
||||
fputs(prefix, stream);
|
||||
fprintf(stream, " %10.2f -- Transaction total\n", total);
|
||||
fclose(stream);
|
||||
fputc('\n', stream);
|
||||
fputs(prefix, stream);
|
||||
if (desc)
|
||||
{
|
||||
fputs(" ", stream);
|
||||
fputs(desc, stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stream, "<no-description>");
|
||||
}
|
||||
|
||||
return(result);
|
||||
fputc('\n', stream);
|
||||
fputs(prefix, stream);
|
||||
if (memo)
|
||||
{
|
||||
fputs(" ", stream);
|
||||
fputs(memo, stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stream, "<no-transaction-memo>");
|
||||
}
|
||||
|
||||
{
|
||||
int split_count = xaccTransCountSplits(txn);
|
||||
int i;
|
||||
for (i = 1; i < split_count; i++)
|
||||
{
|
||||
Split *split = xaccTransGetSplit(txn, i);
|
||||
char *split_text = xaccSplitAsString(split, prefix);
|
||||
fputs(split_text, stream);
|
||||
free(split_text);
|
||||
}
|
||||
}
|
||||
fputc('\n', stream);
|
||||
|
||||
fputs(prefix, stream);
|
||||
fprintf(stream, " %10.2f -- Transaction total\n", total);
|
||||
fclose(stream);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
/** @addtogroup Engine
|
||||
@{ */
|
||||
/** @addtogroup TransLog Transaction Logging
|
||||
The transaction logging mechanism provides a very simple,
|
||||
The transaction logging mechanism provides a very simple,
|
||||
low-level logging of user input to a file. The goal of
|
||||
the transaction logger is to provide mechanism of last resort
|
||||
for recovering lost user data in the event of a crash.
|
||||
@@ -33,7 +33,7 @@
|
||||
that can be used to recover user input.
|
||||
There are some simple command-line tools that will read a log
|
||||
and replay it.
|
||||
|
||||
|
||||
@{ */
|
||||
/** @file TransLog.h
|
||||
@brief API for the transaction logger
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
/** @addtogroup Engine
|
||||
@{ */
|
||||
/** @addtogroup Transaction Financial Transactions
|
||||
A good overview of transactions, splits and accounts can be
|
||||
A good overview of transactions, splits and accounts can be
|
||||
found in the texinfo documentation, together with an overview of
|
||||
how to use this API.
|
||||
|
||||
@@ -31,27 +31,27 @@ a (possibly) different currency than the amount, a Memo, a pointer to
|
||||
the parent Transaction, a pointer to the debited Account, a reconciled
|
||||
flag and timestamp, an "Action" field, and a key-value frame which can
|
||||
store arbitrary data.
|
||||
|
||||
Transactions embody the notion of "double entry" accounting.
|
||||
A Transaction consists of a date, a description, an ID number,
|
||||
|
||||
Transactions embody the notion of "double entry" accounting.
|
||||
A Transaction consists of a date, a description, an ID number,
|
||||
a list of one or more Splits, and a key-value frame. The transaction
|
||||
also specifies the currency with which all of the splits will be valued.
|
||||
When double-entry rules are enforced, the sum total value of the splits
|
||||
are zero. If there are only two splits, then the value of one must be
|
||||
positive, the other negative: this denotes that one account is debited,
|
||||
When double-entry rules are enforced, the sum total value of the splits
|
||||
are zero. If there are only two splits, then the value of one must be
|
||||
positive, the other negative: this denotes that one account is debited,
|
||||
and another is credited by an equal amount. By forcing the value of the
|
||||
splits to always 'add up' to zero, we can guarantee that the balances
|
||||
of the accounts are always correctly balanced.
|
||||
|
||||
The engine does not enforce double-entry accounting, but provides an API
|
||||
to enable user-code to find unbalanced transactions and 'repair' them so
|
||||
that they are in balance.
|
||||
that they are in balance.
|
||||
|
||||
Note the sum of the values of Splits in a Transaction is always computed
|
||||
with respect to a currency; thus splits can be balanced even when they
|
||||
are in different currencies, as long as they share a common currency.
|
||||
This feature allows currency-trading accounts to be established.
|
||||
|
||||
|
||||
Every Split must point to its parent Transaction, and that Transaction
|
||||
must in turn include that Split in the Transaction's list of Splits. A
|
||||
Split can belong to at most one Transaction. These relationships are
|
||||
@@ -67,9 +67,9 @@ A Split can belong to at most one Account. Besides merely containing a
|
||||
list of Splits, the Account structure also gives the Account a name, a
|
||||
code number, description and notes fields, a key-value frame, a pointer
|
||||
to the commodity that is used for all splits in this account. The
|
||||
commodity can be the name of anything traded and tradable: a stock
|
||||
commodity can be the name of anything traded and tradable: a stock
|
||||
(e.g. "IBM", "McDonald's"), a currency (e.g. "USD", "GBP"), or anything
|
||||
added to the commodity table.
|
||||
added to the commodity table.
|
||||
|
||||
Accounts can be arranged in a hierarchical tree. The nodes of the tree
|
||||
are called "Account Groups". By accounting
|
||||
@@ -77,7 +77,7 @@ convention, the value of an Account is equal to the value of all of its
|
||||
Splits plus the value of all of its sub-Accounts.
|
||||
|
||||
@{ */
|
||||
/** @file Transaction.h
|
||||
/** @file Transaction.h
|
||||
@brief API for Transactions and Splits (journal entries)
|
||||
@author Copyright (C) 1997 Robin D. Clark
|
||||
@author Copyright (C) 1997-2001 Linas Vepstas <linas@linas.org>
|
||||
@@ -127,11 +127,11 @@ GType gnc_transaction_get_type(void);
|
||||
/** @name Transaction creation and editing
|
||||
@{
|
||||
*/
|
||||
/**
|
||||
/**
|
||||
The xaccMallocTransaction() will malloc memory and initialize it.
|
||||
Once created, it is usually unsafe to merely "free" this memory;
|
||||
the xaccTransDestroy() method should be called. */
|
||||
Transaction * xaccMallocTransaction (QofBook *book);
|
||||
the xaccTransDestroy() method should be called. */
|
||||
Transaction * xaccMallocTransaction (QofBook *book);
|
||||
|
||||
/** Destroys a transaction.
|
||||
* Each split in transaction @a trans is removed from its
|
||||
@@ -141,8 +141,8 @@ Transaction * xaccMallocTransaction (QofBook *book);
|
||||
* ::xaccTransBeginEdit() then the changes are committed immediately.
|
||||
* Otherwise, the caller must follow up with either
|
||||
* ::xaccTransCommitEdit(), in which case the transaction and
|
||||
* split memory will be freed, or xaccTransRollbackEdit(), in which
|
||||
* case nothing at all is freed, and everything is put back into
|
||||
* split memory will be freed, or xaccTransRollbackEdit(), in which
|
||||
* case nothing at all is freed, and everything is put back into
|
||||
* original order.
|
||||
*
|
||||
* @param trans the transaction to destroy
|
||||
@@ -186,7 +186,7 @@ gboolean xaccTransEqual(const Transaction *ta,
|
||||
gboolean assume_ordered);
|
||||
|
||||
/** The xaccTransBeginEdit() method must be called before any changes
|
||||
are made to a transaction or any of its component splits. If
|
||||
are made to a transaction or any of its component splits. If
|
||||
this is not done, errors will result. */
|
||||
void xaccTransBeginEdit (Transaction *trans);
|
||||
|
||||
@@ -197,15 +197,15 @@ void xaccTransBeginEdit (Transaction *trans);
|
||||
of xaccTransDestroy() was called on the transaction. */
|
||||
void xaccTransCommitEdit (Transaction *trans);
|
||||
|
||||
/** The xaccTransRollbackEdit() routine rejects all edits made, and
|
||||
sets the transaction back to where it was before the editing
|
||||
/** The xaccTransRollbackEdit() routine rejects all edits made, and
|
||||
sets the transaction back to where it was before the editing
|
||||
started. This includes restoring any deleted splits, removing
|
||||
any added splits, and undoing the effects of xaccTransDestroy,
|
||||
as well as restoring share quantities, memos, descriptions, etc. */
|
||||
void xaccTransRollbackEdit (Transaction *trans);
|
||||
|
||||
/** The xaccTransIsOpen() method returns TRUE if the transaction
|
||||
is open for editing. Otherwise, it returns false.
|
||||
is open for editing. Otherwise, it returns false.
|
||||
XXX this routne should probably be deprecated. its, umm,
|
||||
hard to imagine legitimate uses (but it is used by
|
||||
the import/export code for reasons I can't understand.)
|
||||
@@ -215,24 +215,25 @@ gboolean xaccTransIsOpen (const Transaction *trans);
|
||||
/** The xaccTransLookup() subroutine will return the
|
||||
transaction associated with the given id, or NULL
|
||||
if there is no such transaction. */
|
||||
/*@ dependent @*//*@ null @*/ Transaction * xaccTransLookup (const GUID *guid, QofBook *book);
|
||||
/*@ dependent @*//*@ null @*/
|
||||
Transaction * xaccTransLookup (const GUID *guid, QofBook *book);
|
||||
#define xaccTransLookupDirect(g,b) xaccTransLookup(&(g),b)
|
||||
|
||||
Split * xaccTransFindSplitByAccount(const Transaction *trans,
|
||||
Split * xaccTransFindSplitByAccount(const Transaction *trans,
|
||||
const Account *acc);
|
||||
|
||||
/** The xaccTransScrubGains() routine performs a number of cleanup
|
||||
* functions on the indicated transaction, with the end-goal of
|
||||
* setting up a consistent set of gains/losses for all the splits
|
||||
* in the transaction. This includes making sure that the lot
|
||||
* assignments of all the splits are good, and that the lots
|
||||
* assignments of all the splits are good, and that the lots
|
||||
* balance appropriately.
|
||||
*/
|
||||
void xaccTransScrubGains (Transaction *trans, Account *gain_acc);
|
||||
|
||||
|
||||
/** \warning XXX FIXME
|
||||
* gnc_book_count_transactions is a utility function,
|
||||
/** \warning XXX FIXME
|
||||
* gnc_book_count_transactions is a utility function,
|
||||
* probably needs to be moved to a utility file somewhere.
|
||||
*/
|
||||
guint gnc_book_count_transactions(QofBook *book);
|
||||
@@ -283,18 +284,18 @@ const char * xaccTransGetNotes (const Transaction *trans);
|
||||
|
||||
|
||||
/** Add a split to the transaction
|
||||
*
|
||||
The xaccTransAppendSplit() method will append the indicated
|
||||
*
|
||||
The xaccTransAppendSplit() method will append the indicated
|
||||
split to the collection of splits in this transaction.
|
||||
@note If the split is already a part of another transaction,
|
||||
it will be removed from that transaction first.
|
||||
*/
|
||||
#define xaccTransAppendSplit(t, s) xaccSplitSetParent((s), (t))
|
||||
|
||||
/** The xaccTransGetSplit() method returns a pointer to each of the
|
||||
/** The xaccTransGetSplit() method returns a pointer to each of the
|
||||
splits in this transaction.
|
||||
@param trans The transaction
|
||||
@param i The split number. Valid values for i are zero to
|
||||
@param trans The transaction
|
||||
@param i The split number. Valid values for i are zero to
|
||||
(number_of__splits-1). An invalid value of i will cause NULL to
|
||||
be returned. A convenient way of cycling through all splits is
|
||||
to start at zero, and keep incrementing until a null value is returned. */
|
||||
@@ -304,10 +305,11 @@ Split * xaccTransGetSplit (const Transaction *trans, int i);
|
||||
int xaccTransGetSplitIndex(const Transaction *trans, const Split *split);
|
||||
|
||||
/** The xaccTransGetSplitList() method returns a GList of the splits
|
||||
in a transaction.
|
||||
in a transaction.
|
||||
@return The list of splits. This list must NOT be modified. Do *NOT* free
|
||||
this list when you are done with it. */
|
||||
/*@ dependent @*/ SplitList * xaccTransGetSplitList (const Transaction *trans);
|
||||
/*@ dependent @*/
|
||||
SplitList * xaccTransGetSplitList (const Transaction *trans);
|
||||
gboolean xaccTransStillHasSplit(const Transaction *trans, const Split *s);
|
||||
|
||||
|
||||
@@ -324,24 +326,25 @@ int xaccTransCountSplits (const Transaction *trans);
|
||||
gboolean xaccTransHasReconciledSplits (const Transaction *trans);
|
||||
/** FIXME: document me */
|
||||
gboolean xaccTransHasReconciledSplitsByAccount (const Transaction *trans,
|
||||
const Account *account);
|
||||
const Account *account);
|
||||
|
||||
/** FIXME: document me */
|
||||
gboolean xaccTransHasSplitsInState (const Transaction *trans, const char state);
|
||||
/** FIXME: document me */
|
||||
gboolean xaccTransHasSplitsInStateByAccount (const Transaction *trans,
|
||||
const char state,
|
||||
const Account *account);
|
||||
const char state,
|
||||
const Account *account);
|
||||
|
||||
|
||||
/** Returns the valuation commodity of this transaction.
|
||||
*
|
||||
* Each transaction's valuation commodity, or 'currency' is, by definition,
|
||||
* the common currency in which all splits in the transaction can be valued.
|
||||
* The total value of the transaction must be zero when all splits
|
||||
* The total value of the transaction must be zero when all splits
|
||||
* are valued in this currency.
|
||||
* @note What happens if the Currency isn't set? Ans: bad things. */
|
||||
/*@ dependent @*/ gnc_commodity * xaccTransGetCurrency (const Transaction *trans);
|
||||
/*@ dependent @*/
|
||||
gnc_commodity * xaccTransGetCurrency (const Transaction *trans);
|
||||
|
||||
/** Set the commodity of this transaction. */
|
||||
void xaccTransSetCurrency (Transaction *trans, gnc_commodity *curr);
|
||||
@@ -353,9 +356,9 @@ void xaccTransSetCurrency (Transaction *trans, gnc_commodity *curr);
|
||||
* transactions can sneak in, and this routine can be used to find
|
||||
* out how much things are off by. The value returned is denominated
|
||||
* in the currency that is returned by the xaccTransFindCommonCurrency()
|
||||
* method.
|
||||
* method.
|
||||
*
|
||||
* If the use of currency exchange accounts is enabled then the a
|
||||
* If the use of currency exchange accounts is enabled then the a
|
||||
* a transaction must be balanced in each currency it uses to be considered
|
||||
* to be balanced. The method xaccTransGetImbalance is used by most
|
||||
* code to take this into consideration. This method is only used in a few
|
||||
@@ -363,8 +366,8 @@ void xaccTransSetCurrency (Transaction *trans, gnc_commodity *curr);
|
||||
* are enabled. */
|
||||
gnc_numeric xaccTransGetImbalanceValue (const Transaction * trans);
|
||||
|
||||
/** The xaccTransGetImbalance method returns a list giving the value of
|
||||
* the transaction in each currency for which the balance is not zero.
|
||||
/** The xaccTransGetImbalance method returns a list giving the value of
|
||||
* the transaction in each currency for which the balance is not zero.
|
||||
* If the use of currency accounts is disabled, then this will be only
|
||||
* the common currency for the transaction and xaccTransGetImbalance
|
||||
* becomes equivalent to xaccTransGetImbalanceValue. Otherwise it will
|
||||
@@ -381,8 +384,8 @@ gboolean xaccTransIsBalanced(const Transaction * trans);
|
||||
* trying to balance Lots) -- this function is just a convienience to
|
||||
* view everything at once.
|
||||
*/
|
||||
gnc_numeric xaccTransGetAccountValue (const Transaction *trans,
|
||||
const Account *account);
|
||||
gnc_numeric xaccTransGetAccountValue (const Transaction *trans,
|
||||
const Account *account);
|
||||
|
||||
/** Same as xaccTransGetAccountValue, but uses the Account's commodity. */
|
||||
gnc_numeric xaccTransGetAccountAmount (const Transaction *trans,
|
||||
@@ -426,7 +429,7 @@ int xaccTransOrder (const Transaction *ta, const Transaction *tb);
|
||||
/** @name Transaction date setters/getters
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
/** The xaccTransSetDate() method does the same thing as
|
||||
xaccTransSetDate[Posted]Secs(), but takes a convenient
|
||||
day-month-year format.
|
||||
@@ -457,7 +460,7 @@ void xaccTransSetDateEnteredSecs (Transaction *trans, time_t time);
|
||||
/** Modify the date of when the transaction was entered. The entered
|
||||
* date is the date when the register entry was made. */
|
||||
void xaccTransSetDateEnteredTS (Transaction *trans,
|
||||
const Timespec *ts);
|
||||
const Timespec *ts);
|
||||
|
||||
/** Dates and txn-type for A/R and A/P "invoice" postings */
|
||||
void xaccTransSetDateDueTS (Transaction *trans, const Timespec *ts);
|
||||
@@ -510,8 +513,8 @@ void xaccTransGetDateDueTS (const Transaction *trans, Timespec *ts);
|
||||
* @param reason The textual reason why this transaction is being
|
||||
* voided.
|
||||
*/
|
||||
void xaccTransVoid(Transaction *transaction,
|
||||
const char *reason);
|
||||
void xaccTransVoid(Transaction *transaction,
|
||||
const char *reason);
|
||||
|
||||
/** xaccTransUnvoid restores a voided transaction to its original
|
||||
* state. At some point when gnucash is enhanced to support an audit
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
* TransactionP.h
|
||||
*
|
||||
* FUNCTION:
|
||||
* The is the *private* transaction header file. Code outside of
|
||||
* The is the *private* transaction header file. Code outside of
|
||||
* engine should *not* include this file. This is because code
|
||||
* outside of the engine should *never* access any of the structure
|
||||
* members directly.
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
|
||||
/** STRUCTS *********************************************************/
|
||||
/*
|
||||
/*
|
||||
* Double-entry is forced by having at least two splits in every
|
||||
* transaction. By convention, (and only by convention, not by
|
||||
* any innate requirement), the first split is considered to be
|
||||
@@ -73,48 +73,48 @@
|
||||
|
||||
struct transaction_s
|
||||
{
|
||||
QofInstance inst; /* glbally unique id */
|
||||
QofInstance inst; /* glbally unique id */
|
||||
|
||||
Timespec date_entered; /* date register entry was made */
|
||||
Timespec date_posted; /* date transaction was posted at bank */
|
||||
Timespec date_entered; /* date register entry was made */
|
||||
Timespec date_posted; /* date transaction was posted at bank */
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
char * num;
|
||||
/* 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.
|
||||
*/
|
||||
char * num;
|
||||
|
||||
/* The description field is an arbitrary user-assigned value.
|
||||
* It is meant to be a short descriptive phrase.
|
||||
*/
|
||||
char * description;
|
||||
/* The description field is an arbitrary user-assigned value.
|
||||
* It is meant to be a short descriptive phrase.
|
||||
*/
|
||||
char * description;
|
||||
|
||||
/* The common_currency field is the balancing common currency for
|
||||
* all the splits in the transaction. Alternate, better(?) name:
|
||||
* "valuation currency": it is the currency in which all of the
|
||||
* splits can be valued. */
|
||||
gnc_commodity *common_currency;
|
||||
/* The common_currency field is the balancing common currency for
|
||||
* all the splits in the transaction. Alternate, better(?) name:
|
||||
* "valuation currency": it is the currency in which all of the
|
||||
* splits can be valued. */
|
||||
gnc_commodity *common_currency;
|
||||
|
||||
GList * splits; /* list of splits */
|
||||
GList * splits; /* list of splits */
|
||||
|
||||
/* 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
|
||||
* corresponding to the current traversal. */
|
||||
unsigned char marker;
|
||||
/* 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
|
||||
* corresponding to the current traversal. */
|
||||
unsigned char marker;
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
Transaction *orig;
|
||||
/* 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.
|
||||
*/
|
||||
Transaction *orig;
|
||||
};
|
||||
|
||||
struct _TransactionClass
|
||||
{
|
||||
QofInstanceClass parent_class;
|
||||
QofInstanceClass parent_class;
|
||||
};
|
||||
|
||||
/* Set the transaction's GUID. This should only be done when reading
|
||||
@@ -126,10 +126,10 @@ struct _TransactionClass
|
||||
* This routine cannot be exposed publically since the duplicate
|
||||
* is wrong in many ways: it is not issued a unique guid, and thus
|
||||
* not a properly registered Entity. The splits are copied, but
|
||||
* these are also funny: they aren't inserted into the accounts
|
||||
* these are also funny: they aren't inserted into the accounts
|
||||
* they claim to be in. The splits also have bogus GUID's.
|
||||
* Another 'feature': the splits point at the old transaction
|
||||
* as the parent, not the new transaction.
|
||||
* as the parent, not the new transaction.
|
||||
*/
|
||||
Transaction * xaccDupeTransaction (const Transaction *t);
|
||||
|
||||
@@ -145,14 +145,14 @@ gint32 xaccTransGetVersion (const Transaction*);
|
||||
gboolean xaccTransRegister (void);
|
||||
|
||||
/* The xaccTransactionGetBackend() subroutine will find the
|
||||
* persistent-data storage backend associated with this
|
||||
* persistent-data storage backend associated with this
|
||||
* transaction.
|
||||
*/
|
||||
QofBackend * xaccTransactionGetBackend (Transaction *trans);
|
||||
|
||||
/* The xaccEnable/DisableDataScrubbing() routines affect what
|
||||
* happens during transaction commit. When scrubbing is enabled,
|
||||
* then transactions are fixed up during transaction commit,
|
||||
* then transactions are fixed up during transaction commit,
|
||||
* so that only consistent transactions are commited to the engine.
|
||||
* However, when data is being loaded from a backend (in particular,
|
||||
* from the file backend), the data might not be consistent until
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifdef ENABLE_BINRELOC
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#ifdef MAC_INTEGRATION
|
||||
#include <igemacintegration/ige-mac-bundle.h>
|
||||
#endif
|
||||
@@ -43,172 +43,185 @@ static char *
|
||||
_br_find_exe (GbrInitError *error)
|
||||
{
|
||||
#ifndef ENABLE_BINRELOC
|
||||
if (error)
|
||||
*error = GBR_INIT_ERROR_DISABLED;
|
||||
return NULL;
|
||||
if (error)
|
||||
*error = GBR_INIT_ERROR_DISABLED;
|
||||
return NULL;
|
||||
#else
|
||||
#ifdef G_OS_WIN32
|
||||
/* I *thought* this program code already included the
|
||||
relocation code for windows. Unfortunately this is not
|
||||
the case and we have to add this manually. This is only
|
||||
one possibility; other ways of looking up the full path
|
||||
of gnucash-bin.exe probably exist.*/
|
||||
gchar *prefix;
|
||||
gchar *result;
|
||||
/* I *thought* this program code already included the
|
||||
relocation code for windows. Unfortunately this is not
|
||||
the case and we have to add this manually. This is only
|
||||
one possibility; other ways of looking up the full path
|
||||
of gnucash-bin.exe probably exist.*/
|
||||
gchar *prefix;
|
||||
gchar *result;
|
||||
|
||||
/* From the glib docs: When passed NULL, this function looks
|
||||
up installation the directory of the main executable of
|
||||
the current process */
|
||||
prefix = g_win32_get_package_installation_directory_of_module (NULL);
|
||||
result = g_build_filename (prefix,
|
||||
"bin", "gnucash-bin.exe",
|
||||
(char*)NULL);
|
||||
g_free (prefix);
|
||||
return result;
|
||||
/* From the glib docs: When passed NULL, this function looks
|
||||
up installation the directory of the main executable of
|
||||
the current process */
|
||||
prefix = g_win32_get_package_installation_directory_of_module (NULL);
|
||||
result = g_build_filename (prefix,
|
||||
"bin", "gnucash-bin.exe",
|
||||
(char*)NULL);
|
||||
g_free (prefix);
|
||||
return result;
|
||||
#elif MAC_INTEGRATION
|
||||
gchar *prefix = NULL, *result = NULL;
|
||||
g_type_init();
|
||||
bundle = ige_mac_bundle_new();
|
||||
if (!bundle) {
|
||||
*error = GBR_INIT_ERROR_MAC_NOT_BUNDLE;
|
||||
return NULL;
|
||||
}
|
||||
if (!ige_mac_bundle_get_is_app_bundle (bundle)) {
|
||||
g_object_unref(bundle);
|
||||
bundle = NULL;
|
||||
*error = GBR_INIT_ERROR_MAC_NOT_APP_BUNDLE;
|
||||
return NULL;
|
||||
}
|
||||
ige_mac_bundle_setup_environment(bundle);
|
||||
prefix = g_strdup(ige_mac_bundle_get_path(bundle));
|
||||
result = g_build_filename(prefix, "Contents/MacOS",
|
||||
"gnucash-bin", NULL);
|
||||
g_free(prefix);
|
||||
return result;
|
||||
gchar *prefix = NULL, *result = NULL;
|
||||
g_type_init();
|
||||
bundle = ige_mac_bundle_new();
|
||||
if (!bundle)
|
||||
{
|
||||
*error = GBR_INIT_ERROR_MAC_NOT_BUNDLE;
|
||||
return NULL;
|
||||
}
|
||||
if (!ige_mac_bundle_get_is_app_bundle (bundle))
|
||||
{
|
||||
g_object_unref(bundle);
|
||||
bundle = NULL;
|
||||
*error = GBR_INIT_ERROR_MAC_NOT_APP_BUNDLE;
|
||||
return NULL;
|
||||
}
|
||||
ige_mac_bundle_setup_environment(bundle);
|
||||
prefix = g_strdup(ige_mac_bundle_get_path(bundle));
|
||||
result = g_build_filename(prefix, "Contents/MacOS",
|
||||
"gnucash-bin", NULL);
|
||||
g_free(prefix);
|
||||
return result;
|
||||
#else
|
||||
char *path, *path2, *line, *result;
|
||||
size_t buf_size;
|
||||
ssize_t size;
|
||||
struct stat stat_buf;
|
||||
FILE *f;
|
||||
char *path, *path2, *line, *result;
|
||||
size_t buf_size;
|
||||
ssize_t size;
|
||||
struct stat stat_buf;
|
||||
FILE *f;
|
||||
|
||||
/* Read from /proc/self/exe (symlink) */
|
||||
if (sizeof (path) > SSIZE_MAX)
|
||||
buf_size = SSIZE_MAX - 1;
|
||||
else
|
||||
buf_size = PATH_MAX - 1;
|
||||
path = (char *) g_try_malloc (buf_size);
|
||||
if (path == NULL) {
|
||||
/* Cannot allocate memory. */
|
||||
if (error)
|
||||
*error = GBR_INIT_ERROR_NOMEM;
|
||||
return NULL;
|
||||
}
|
||||
path2 = (char *) g_try_malloc (buf_size);
|
||||
if (path2 == NULL) {
|
||||
/* Cannot allocate memory. */
|
||||
if (error)
|
||||
*error = GBR_INIT_ERROR_NOMEM;
|
||||
g_free (path);
|
||||
return NULL;
|
||||
}
|
||||
/* Read from /proc/self/exe (symlink) */
|
||||
if (sizeof (path) > SSIZE_MAX)
|
||||
buf_size = SSIZE_MAX - 1;
|
||||
else
|
||||
buf_size = PATH_MAX - 1;
|
||||
path = (char *) g_try_malloc (buf_size);
|
||||
if (path == NULL)
|
||||
{
|
||||
/* Cannot allocate memory. */
|
||||
if (error)
|
||||
*error = GBR_INIT_ERROR_NOMEM;
|
||||
return NULL;
|
||||
}
|
||||
path2 = (char *) g_try_malloc (buf_size);
|
||||
if (path2 == NULL)
|
||||
{
|
||||
/* Cannot allocate memory. */
|
||||
if (error)
|
||||
*error = GBR_INIT_ERROR_NOMEM;
|
||||
g_free (path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strncpy (path2, "/proc/self/exe", buf_size - 1);
|
||||
strncpy (path2, "/proc/self/exe", buf_size - 1);
|
||||
|
||||
while (1) {
|
||||
int i;
|
||||
while (1)
|
||||
{
|
||||
int i;
|
||||
|
||||
size = readlink (path2, path, buf_size - 1);
|
||||
if (size == -1) {
|
||||
/* Error. */
|
||||
g_free (path2);
|
||||
break;
|
||||
}
|
||||
size = readlink (path2, path, buf_size - 1);
|
||||
if (size == -1)
|
||||
{
|
||||
/* Error. */
|
||||
g_free (path2);
|
||||
break;
|
||||
}
|
||||
|
||||
/* readlink() success. */
|
||||
path[size] = '\0';
|
||||
/* readlink() success. */
|
||||
path[size] = '\0';
|
||||
|
||||
/* Check whether the symlink's target is also a symlink.
|
||||
* We want to get the final target. */
|
||||
i = stat (path, &stat_buf);
|
||||
if (i == -1) {
|
||||
/* Error. */
|
||||
g_free (path2);
|
||||
break;
|
||||
}
|
||||
/* Check whether the symlink's target is also a symlink.
|
||||
* We want to get the final target. */
|
||||
i = stat (path, &stat_buf);
|
||||
if (i == -1)
|
||||
{
|
||||
/* Error. */
|
||||
g_free (path2);
|
||||
break;
|
||||
}
|
||||
|
||||
/* stat() success. */
|
||||
if (!S_ISLNK (stat_buf.st_mode)) {
|
||||
/* path is not a symlink. Done. */
|
||||
g_free (path2);
|
||||
return path;
|
||||
}
|
||||
/* stat() success. */
|
||||
if (!S_ISLNK (stat_buf.st_mode))
|
||||
{
|
||||
/* path is not a symlink. Done. */
|
||||
g_free (path2);
|
||||
return path;
|
||||
}
|
||||
|
||||
/* path is a symlink. Continue loop and resolve this. */
|
||||
strncpy (path, path2, buf_size - 1);
|
||||
}
|
||||
/* path is a symlink. Continue loop and resolve this. */
|
||||
strncpy (path, path2, buf_size - 1);
|
||||
}
|
||||
|
||||
|
||||
/* readlink() or stat() failed; this can happen when the program is
|
||||
* running in Valgrind 2.2. Read from /proc/self/maps as fallback. */
|
||||
/* readlink() or stat() failed; this can happen when the program is
|
||||
* running in Valgrind 2.2. Read from /proc/self/maps as fallback. */
|
||||
|
||||
buf_size = PATH_MAX + 128;
|
||||
line = (char *) g_try_realloc (path, buf_size);
|
||||
if (line == NULL) {
|
||||
/* Cannot allocate memory. */
|
||||
g_free (path);
|
||||
if (error)
|
||||
*error = GBR_INIT_ERROR_NOMEM;
|
||||
return NULL;
|
||||
}
|
||||
buf_size = PATH_MAX + 128;
|
||||
line = (char *) g_try_realloc (path, buf_size);
|
||||
if (line == NULL)
|
||||
{
|
||||
/* Cannot allocate memory. */
|
||||
g_free (path);
|
||||
if (error)
|
||||
*error = GBR_INIT_ERROR_NOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
f = fopen ("/proc/self/maps", "r");
|
||||
if (f == NULL) {
|
||||
g_free (line);
|
||||
if (error)
|
||||
*error = GBR_INIT_ERROR_OPEN_MAPS;
|
||||
return NULL;
|
||||
}
|
||||
f = fopen ("/proc/self/maps", "r");
|
||||
if (f == NULL)
|
||||
{
|
||||
g_free (line);
|
||||
if (error)
|
||||
*error = GBR_INIT_ERROR_OPEN_MAPS;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The first entry should be the executable name. */
|
||||
result = fgets (line, (int) buf_size, f);
|
||||
if (result == NULL) {
|
||||
fclose (f);
|
||||
g_free (line);
|
||||
if (error)
|
||||
*error = GBR_INIT_ERROR_READ_MAPS;
|
||||
return NULL;
|
||||
}
|
||||
/* The first entry should be the executable name. */
|
||||
result = fgets (line, (int) buf_size, f);
|
||||
if (result == NULL)
|
||||
{
|
||||
fclose (f);
|
||||
g_free (line);
|
||||
if (error)
|
||||
*error = GBR_INIT_ERROR_READ_MAPS;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get rid of newline character. */
|
||||
buf_size = strlen (line);
|
||||
if (buf_size <= 0) {
|
||||
/* Huh? An empty string? */
|
||||
fclose (f);
|
||||
g_free (line);
|
||||
if (error)
|
||||
*error = GBR_INIT_ERROR_INVALID_MAPS;
|
||||
return NULL;
|
||||
}
|
||||
if (line[buf_size - 1] == 10)
|
||||
line[buf_size - 1] = 0;
|
||||
/* Get rid of newline character. */
|
||||
buf_size = strlen (line);
|
||||
if (buf_size <= 0)
|
||||
{
|
||||
/* Huh? An empty string? */
|
||||
fclose (f);
|
||||
g_free (line);
|
||||
if (error)
|
||||
*error = GBR_INIT_ERROR_INVALID_MAPS;
|
||||
return NULL;
|
||||
}
|
||||
if (line[buf_size - 1] == 10)
|
||||
line[buf_size - 1] = 0;
|
||||
|
||||
/* Extract the filename; it is always an absolute path. */
|
||||
path = strchr (line, '/');
|
||||
/* Extract the filename; it is always an absolute path. */
|
||||
path = strchr (line, '/');
|
||||
|
||||
/* Sanity check. */
|
||||
if (strstr (line, " r-xp ") == NULL || path == NULL) {
|
||||
fclose (f);
|
||||
g_free (line);
|
||||
if (error)
|
||||
*error = GBR_INIT_ERROR_INVALID_MAPS;
|
||||
return NULL;
|
||||
}
|
||||
/* Sanity check. */
|
||||
if (strstr (line, " r-xp ") == NULL || path == NULL)
|
||||
{
|
||||
fclose (f);
|
||||
g_free (line);
|
||||
if (error)
|
||||
*error = GBR_INIT_ERROR_INVALID_MAPS;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
path = g_strdup (path);
|
||||
g_free (line);
|
||||
fclose (f);
|
||||
return path;
|
||||
path = g_strdup (path);
|
||||
g_free (line);
|
||||
fclose (f);
|
||||
return path;
|
||||
#endif /* G_OS_WINDOWS */
|
||||
#endif /* ENABLE_BINRELOC */
|
||||
}
|
||||
@@ -222,108 +235,111 @@ static char *
|
||||
_br_find_exe_for_symbol (const void *symbol, GbrInitError *error)
|
||||
{
|
||||
#ifndef ENABLE_BINRELOC
|
||||
if (error)
|
||||
*error = GBR_INIT_ERROR_DISABLED;
|
||||
return (char *) NULL;
|
||||
if (error)
|
||||
*error = GBR_INIT_ERROR_DISABLED;
|
||||
return (char *) NULL;
|
||||
#else
|
||||
#if defined G_OS_WIN32
|
||||
g_warning ("_br_find_exe_for_symbol not implemented on win32.");
|
||||
if (error)
|
||||
*error = GBR_INIT_ERROR_DISABLED;
|
||||
return (char *) NULL;
|
||||
#if defined G_OS_WIN32
|
||||
g_warning ("_br_find_exe_for_symbol not implemented on win32.");
|
||||
if (error)
|
||||
*error = GBR_INIT_ERROR_DISABLED;
|
||||
return (char *) NULL;
|
||||
#else
|
||||
#define SIZE PATH_MAX + 100
|
||||
FILE *f;
|
||||
size_t address_string_len;
|
||||
char *address_string, line[SIZE], *found;
|
||||
#define SIZE PATH_MAX + 100
|
||||
FILE *f;
|
||||
size_t address_string_len;
|
||||
char *address_string, line[SIZE], *found;
|
||||
|
||||
if (symbol == NULL)
|
||||
return (char *) NULL;
|
||||
if (symbol == NULL)
|
||||
return (char *) NULL;
|
||||
|
||||
f = fopen ("/proc/self/maps", "r");
|
||||
if (f == NULL)
|
||||
return (char *) NULL;
|
||||
f = fopen ("/proc/self/maps", "r");
|
||||
if (f == NULL)
|
||||
return (char *) NULL;
|
||||
|
||||
address_string_len = 4;
|
||||
address_string = (char *) g_try_malloc (address_string_len);
|
||||
found = (char *) NULL;
|
||||
address_string_len = 4;
|
||||
address_string = (char *) g_try_malloc (address_string_len);
|
||||
found = (char *) NULL;
|
||||
|
||||
while (!feof (f)) {
|
||||
char *start_addr, *end_addr, *end_addr_end, *file;
|
||||
void *start_addr_p, *end_addr_p;
|
||||
size_t len;
|
||||
while (!feof (f))
|
||||
{
|
||||
char *start_addr, *end_addr, *end_addr_end, *file;
|
||||
void *start_addr_p, *end_addr_p;
|
||||
size_t len;
|
||||
|
||||
if (fgets (line, SIZE, f) == NULL)
|
||||
break;
|
||||
if (fgets (line, SIZE, f) == NULL)
|
||||
break;
|
||||
|
||||
/* Sanity check. */
|
||||
if (strstr (line, " r-xp ") == NULL || strchr (line, '/') == NULL)
|
||||
continue;
|
||||
/* Sanity check. */
|
||||
if (strstr (line, " r-xp ") == NULL || strchr (line, '/') == NULL)
|
||||
continue;
|
||||
|
||||
/* Parse line. */
|
||||
start_addr = line;
|
||||
end_addr = strchr (line, '-');
|
||||
file = strchr (line, '/');
|
||||
/* Parse line. */
|
||||
start_addr = line;
|
||||
end_addr = strchr (line, '-');
|
||||
file = strchr (line, '/');
|
||||
|
||||
/* More sanity check. */
|
||||
if (!(file > end_addr && end_addr != NULL && end_addr[0] == '-'))
|
||||
continue;
|
||||
/* More sanity check. */
|
||||
if (!(file > end_addr && end_addr != NULL && end_addr[0] == '-'))
|
||||
continue;
|
||||
|
||||
end_addr[0] = '\0';
|
||||
end_addr++;
|
||||
end_addr_end = strchr (end_addr, ' ');
|
||||
if (end_addr_end == NULL)
|
||||
continue;
|
||||
end_addr[0] = '\0';
|
||||
end_addr++;
|
||||
end_addr_end = strchr (end_addr, ' ');
|
||||
if (end_addr_end == NULL)
|
||||
continue;
|
||||
|
||||
end_addr_end[0] = '\0';
|
||||
len = strlen (file);
|
||||
if (len == 0)
|
||||
continue;
|
||||
if (file[len - 1] == '\n')
|
||||
file[len - 1] = '\0';
|
||||
end_addr_end[0] = '\0';
|
||||
len = strlen (file);
|
||||
if (len == 0)
|
||||
continue;
|
||||
if (file[len - 1] == '\n')
|
||||
file[len - 1] = '\0';
|
||||
|
||||
/* Get rid of "(deleted)" from the filename. */
|
||||
len = strlen (file);
|
||||
if (len > 10 && strcmp (file + len - 10, " (deleted)") == 0)
|
||||
file[len - 10] = '\0';
|
||||
/* Get rid of "(deleted)" from the filename. */
|
||||
len = strlen (file);
|
||||
if (len > 10 && strcmp (file + len - 10, " (deleted)") == 0)
|
||||
file[len - 10] = '\0';
|
||||
|
||||
/* I don't know whether this can happen but better safe than sorry. */
|
||||
len = strlen (start_addr);
|
||||
if (len != strlen (end_addr))
|
||||
continue;
|
||||
/* I don't know whether this can happen but better safe than sorry. */
|
||||
len = strlen (start_addr);
|
||||
if (len != strlen (end_addr))
|
||||
continue;
|
||||
|
||||
|
||||
/* Transform the addresses into a string in the form of 0xdeadbeef,
|
||||
* then transform that into a pointer. */
|
||||
if (address_string_len < len + 3) {
|
||||
address_string_len = len + 3;
|
||||
address_string = (char *) g_try_realloc (address_string, address_string_len);
|
||||
}
|
||||
/* Transform the addresses into a string in the form of 0xdeadbeef,
|
||||
* then transform that into a pointer. */
|
||||
if (address_string_len < len + 3)
|
||||
{
|
||||
address_string_len = len + 3;
|
||||
address_string = (char *) g_try_realloc (address_string, address_string_len);
|
||||
}
|
||||
|
||||
memcpy (address_string, "0x", 2);
|
||||
memcpy (address_string + 2, start_addr, len);
|
||||
address_string[2 + len] = '\0';
|
||||
sscanf (address_string, "%p", &start_addr_p);
|
||||
memcpy (address_string, "0x", 2);
|
||||
memcpy (address_string + 2, start_addr, len);
|
||||
address_string[2 + len] = '\0';
|
||||
sscanf (address_string, "%p", &start_addr_p);
|
||||
|
||||
memcpy (address_string, "0x", 2);
|
||||
memcpy (address_string + 2, end_addr, len);
|
||||
address_string[2 + len] = '\0';
|
||||
sscanf (address_string, "%p", &end_addr_p);
|
||||
memcpy (address_string, "0x", 2);
|
||||
memcpy (address_string + 2, end_addr, len);
|
||||
address_string[2 + len] = '\0';
|
||||
sscanf (address_string, "%p", &end_addr_p);
|
||||
|
||||
|
||||
if (symbol >= start_addr_p && symbol < end_addr_p) {
|
||||
found = file;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (symbol >= start_addr_p && symbol < end_addr_p)
|
||||
{
|
||||
found = file;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_free (address_string);
|
||||
fclose (f);
|
||||
g_free (address_string);
|
||||
fclose (f);
|
||||
|
||||
if (found == NULL)
|
||||
return (char *) NULL;
|
||||
else
|
||||
return g_strdup (found);
|
||||
if (found == NULL)
|
||||
return (char *) NULL;
|
||||
else
|
||||
return g_strdup (found);
|
||||
#endif /* G_OS_WIN32 */
|
||||
#endif /* ENABLE_BINRELOC */
|
||||
}
|
||||
@@ -352,18 +368,19 @@ static void set_gerror (GError **error, GbrInitError errcode);
|
||||
gboolean
|
||||
gbr_init (GError **error)
|
||||
{
|
||||
GbrInitError errcode = 0;
|
||||
GbrInitError errcode = 0;
|
||||
|
||||
/* Locate the application's filename. */
|
||||
exe = _br_find_exe (&errcode);
|
||||
if (exe != NULL)
|
||||
/* Success! */
|
||||
return TRUE;
|
||||
else {
|
||||
/* Failed :-( */
|
||||
set_gerror (error, errcode);
|
||||
return FALSE;
|
||||
}
|
||||
/* Locate the application's filename. */
|
||||
exe = _br_find_exe (&errcode);
|
||||
if (exe != NULL)
|
||||
/* Success! */
|
||||
return TRUE;
|
||||
else
|
||||
{
|
||||
/* Failed :-( */
|
||||
set_gerror (error, errcode);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -380,56 +397,58 @@ gbr_init (GError **error)
|
||||
gboolean
|
||||
gbr_init_lib (GError **error)
|
||||
{
|
||||
GbrInitError errcode = 0;
|
||||
GbrInitError errcode = 0;
|
||||
|
||||
exe = _br_find_exe_for_symbol ((const void *) "", &errcode);
|
||||
if (exe != NULL)
|
||||
/* Success! */
|
||||
return TRUE;
|
||||
else {
|
||||
/* Failed :-( */
|
||||
set_gerror (error, errcode);
|
||||
return exe != NULL;
|
||||
}
|
||||
exe = _br_find_exe_for_symbol ((const void *) "", &errcode);
|
||||
if (exe != NULL)
|
||||
/* Success! */
|
||||
return TRUE;
|
||||
else
|
||||
{
|
||||
/* Failed :-( */
|
||||
set_gerror (error, errcode);
|
||||
return exe != NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_gerror (GError **error, GbrInitError errcode)
|
||||
{
|
||||
gchar *error_message;
|
||||
gchar *error_message;
|
||||
|
||||
if (error == NULL)
|
||||
return;
|
||||
if (error == NULL)
|
||||
return;
|
||||
|
||||
switch (errcode) {
|
||||
case GBR_INIT_ERROR_NOMEM:
|
||||
error_message = "Cannot allocate memory.";
|
||||
break;
|
||||
case GBR_INIT_ERROR_OPEN_MAPS:
|
||||
error_message = "Unable to open /proc/self/maps for reading.";
|
||||
break;
|
||||
case GBR_INIT_ERROR_READ_MAPS:
|
||||
error_message = "Unable to read from /proc/self/maps.";
|
||||
break;
|
||||
case GBR_INIT_ERROR_INVALID_MAPS:
|
||||
error_message = "The file format of /proc/self/maps is invalid.";
|
||||
break;
|
||||
case GBR_INIT_ERROR_MAC_NOT_BUNDLE:
|
||||
error_message = "Binreloc did not find a bundle";
|
||||
break;
|
||||
case GBR_INIT_ERROR_MAC_NOT_APP_BUNDLE:
|
||||
error_message = "Binreloc found that the bundle is not an app bundle";
|
||||
break;
|
||||
case GBR_INIT_ERROR_DISABLED:
|
||||
error_message = "Binary relocation support is disabled.";
|
||||
break;
|
||||
default:
|
||||
error_message = "Unknown error.";
|
||||
break;
|
||||
};
|
||||
g_set_error (error, g_quark_from_static_string ("GBinReloc"),
|
||||
errcode, "%s", error_message);
|
||||
switch (errcode)
|
||||
{
|
||||
case GBR_INIT_ERROR_NOMEM:
|
||||
error_message = "Cannot allocate memory.";
|
||||
break;
|
||||
case GBR_INIT_ERROR_OPEN_MAPS:
|
||||
error_message = "Unable to open /proc/self/maps for reading.";
|
||||
break;
|
||||
case GBR_INIT_ERROR_READ_MAPS:
|
||||
error_message = "Unable to read from /proc/self/maps.";
|
||||
break;
|
||||
case GBR_INIT_ERROR_INVALID_MAPS:
|
||||
error_message = "The file format of /proc/self/maps is invalid.";
|
||||
break;
|
||||
case GBR_INIT_ERROR_MAC_NOT_BUNDLE:
|
||||
error_message = "Binreloc did not find a bundle";
|
||||
break;
|
||||
case GBR_INIT_ERROR_MAC_NOT_APP_BUNDLE:
|
||||
error_message = "Binreloc found that the bundle is not an app bundle";
|
||||
break;
|
||||
case GBR_INIT_ERROR_DISABLED:
|
||||
error_message = "Binary relocation support is disabled.";
|
||||
break;
|
||||
default:
|
||||
error_message = "Unknown error.";
|
||||
break;
|
||||
};
|
||||
g_set_error (error, g_quark_from_static_string ("GBinReloc"),
|
||||
errcode, "%s", error_message);
|
||||
}
|
||||
|
||||
|
||||
@@ -445,14 +464,15 @@ set_gerror (GError **error, GbrInitError errcode)
|
||||
gchar *
|
||||
gbr_find_exe (const gchar *default_exe)
|
||||
{
|
||||
if (exe == NULL) {
|
||||
/* BinReloc is not initialized. */
|
||||
if (default_exe != NULL)
|
||||
return g_strdup (default_exe);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
return g_strdup (exe);
|
||||
if (exe == NULL)
|
||||
{
|
||||
/* BinReloc is not initialized. */
|
||||
if (default_exe != NULL)
|
||||
return g_strdup (default_exe);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
return g_strdup (exe);
|
||||
}
|
||||
|
||||
|
||||
@@ -473,15 +493,16 @@ gbr_find_exe (const gchar *default_exe)
|
||||
gchar *
|
||||
gbr_find_exe_dir (const gchar *default_dir)
|
||||
{
|
||||
if (exe == NULL) {
|
||||
/* BinReloc not initialized. */
|
||||
if (default_dir != NULL)
|
||||
return g_strdup (default_dir);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
if (exe == NULL)
|
||||
{
|
||||
/* BinReloc not initialized. */
|
||||
if (default_dir != NULL)
|
||||
return g_strdup (default_dir);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return g_path_get_dirname (exe);
|
||||
return g_path_get_dirname (exe);
|
||||
}
|
||||
|
||||
|
||||
@@ -502,34 +523,36 @@ gbr_find_exe_dir (const gchar *default_dir)
|
||||
gchar *
|
||||
gbr_find_prefix (const gchar *default_prefix)
|
||||
{
|
||||
gchar *dir1, *dir2;
|
||||
gchar *dir1, *dir2;
|
||||
|
||||
#if defined ENABLE_BINRELOC && defined MAC_INTEGRATION
|
||||
gchar *prefix = NULL, *result = NULL;
|
||||
if (bundle == NULL) {
|
||||
/* BinReloc not initialized. */
|
||||
if (default_prefix != NULL)
|
||||
return g_strdup (default_prefix);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
prefix = g_strdup(ige_mac_bundle_get_path(bundle));
|
||||
result = g_build_filename(prefix, "Contents/Resources", NULL);
|
||||
g_free(prefix);
|
||||
return result;
|
||||
gchar *prefix = NULL, *result = NULL;
|
||||
if (bundle == NULL)
|
||||
{
|
||||
/* BinReloc not initialized. */
|
||||
if (default_prefix != NULL)
|
||||
return g_strdup (default_prefix);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
prefix = g_strdup(ige_mac_bundle_get_path(bundle));
|
||||
result = g_build_filename(prefix, "Contents/Resources", NULL);
|
||||
g_free(prefix);
|
||||
return result;
|
||||
#else
|
||||
|
||||
if (exe == NULL) {
|
||||
/* BinReloc not initialized. */
|
||||
if (default_prefix != NULL)
|
||||
return g_strdup (default_prefix);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
dir1 = g_path_get_dirname (exe);
|
||||
dir2 = g_path_get_dirname (dir1);
|
||||
g_free (dir1);
|
||||
return dir2;
|
||||
if (exe == NULL)
|
||||
{
|
||||
/* BinReloc not initialized. */
|
||||
if (default_prefix != NULL)
|
||||
return g_strdup (default_prefix);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
dir1 = g_path_get_dirname (exe);
|
||||
dir2 = g_path_get_dirname (dir1);
|
||||
g_free (dir1);
|
||||
return dir2;
|
||||
#endif //ENABLE_BINRELOC && MAC_INTEGRATION
|
||||
}
|
||||
|
||||
@@ -550,33 +573,35 @@ gbr_find_prefix (const gchar *default_prefix)
|
||||
gchar *
|
||||
gbr_find_bin_dir (const gchar *default_bin_dir)
|
||||
{
|
||||
gchar *prefix, *dir;
|
||||
gchar *prefix, *dir;
|
||||
#if defined ENABLE_BINRELOC && defined MAC_INTEGRATION
|
||||
if (bundle == NULL) {
|
||||
/* BinReloc not initialized. */
|
||||
if (default_bin_dir != NULL)
|
||||
return g_strdup (default_bin_dir);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
prefix = g_strdup(ige_mac_bundle_get_path(bundle));
|
||||
dir = g_build_filename(prefix, "Contents/MacOS", NULL);
|
||||
g_free(prefix);
|
||||
return dir;
|
||||
if (bundle == NULL)
|
||||
{
|
||||
/* BinReloc not initialized. */
|
||||
if (default_bin_dir != NULL)
|
||||
return g_strdup (default_bin_dir);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
prefix = g_strdup(ige_mac_bundle_get_path(bundle));
|
||||
dir = g_build_filename(prefix, "Contents/MacOS", NULL);
|
||||
g_free(prefix);
|
||||
return dir;
|
||||
#else
|
||||
|
||||
prefix = gbr_find_prefix (NULL);
|
||||
if (prefix == NULL) {
|
||||
/* BinReloc not initialized. */
|
||||
if (default_bin_dir != NULL)
|
||||
return g_strdup (default_bin_dir);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
prefix = gbr_find_prefix (NULL);
|
||||
if (prefix == NULL)
|
||||
{
|
||||
/* BinReloc not initialized. */
|
||||
if (default_bin_dir != NULL)
|
||||
return g_strdup (default_bin_dir);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dir = g_build_filename (prefix, "bin", NULL);
|
||||
g_free (prefix);
|
||||
return dir;
|
||||
dir = g_build_filename (prefix, "bin", NULL);
|
||||
g_free (prefix);
|
||||
return dir;
|
||||
#endif //ENABLE_BINRELOC && MAC_INTEGRATION
|
||||
}
|
||||
|
||||
@@ -597,20 +622,21 @@ gbr_find_bin_dir (const gchar *default_bin_dir)
|
||||
gchar *
|
||||
gbr_find_sbin_dir (const gchar *default_sbin_dir)
|
||||
{
|
||||
gchar *prefix, *dir;
|
||||
gchar *prefix, *dir;
|
||||
|
||||
prefix = gbr_find_prefix (NULL);
|
||||
if (prefix == NULL) {
|
||||
/* BinReloc not initialized. */
|
||||
if (default_sbin_dir != NULL)
|
||||
return g_strdup (default_sbin_dir);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
prefix = gbr_find_prefix (NULL);
|
||||
if (prefix == NULL)
|
||||
{
|
||||
/* BinReloc not initialized. */
|
||||
if (default_sbin_dir != NULL)
|
||||
return g_strdup (default_sbin_dir);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dir = g_build_filename (prefix, "sbin", NULL);
|
||||
g_free (prefix);
|
||||
return dir;
|
||||
dir = g_build_filename (prefix, "sbin", NULL);
|
||||
g_free (prefix);
|
||||
return dir;
|
||||
}
|
||||
|
||||
|
||||
@@ -631,20 +657,21 @@ gbr_find_sbin_dir (const gchar *default_sbin_dir)
|
||||
gchar *
|
||||
gbr_find_data_dir (const gchar *default_data_dir)
|
||||
{
|
||||
gchar *prefix, *dir;
|
||||
gchar *prefix, *dir;
|
||||
|
||||
prefix = gbr_find_prefix (NULL);
|
||||
if (prefix == NULL) {
|
||||
/* BinReloc not initialized. */
|
||||
if (default_data_dir != NULL)
|
||||
return g_strdup (default_data_dir);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
prefix = gbr_find_prefix (NULL);
|
||||
if (prefix == NULL)
|
||||
{
|
||||
/* BinReloc not initialized. */
|
||||
if (default_data_dir != NULL)
|
||||
return g_strdup (default_data_dir);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dir = g_build_filename (prefix, "share", NULL);
|
||||
g_free (prefix);
|
||||
return dir;
|
||||
dir = g_build_filename (prefix, "share", NULL);
|
||||
g_free (prefix);
|
||||
return dir;
|
||||
}
|
||||
|
||||
|
||||
@@ -664,20 +691,21 @@ gbr_find_data_dir (const gchar *default_data_dir)
|
||||
gchar *
|
||||
gbr_find_lib_dir (const gchar *default_lib_dir)
|
||||
{
|
||||
gchar *prefix, *dir;
|
||||
gchar *prefix, *dir;
|
||||
|
||||
prefix = gbr_find_prefix (NULL);
|
||||
if (prefix == NULL) {
|
||||
/* BinReloc not initialized. */
|
||||
if (default_lib_dir != NULL)
|
||||
return g_strdup (default_lib_dir);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
prefix = gbr_find_prefix (NULL);
|
||||
if (prefix == NULL)
|
||||
{
|
||||
/* BinReloc not initialized. */
|
||||
if (default_lib_dir != NULL)
|
||||
return g_strdup (default_lib_dir);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dir = g_build_filename (prefix, "lib", NULL);
|
||||
g_free (prefix);
|
||||
return dir;
|
||||
dir = g_build_filename (prefix, "lib", NULL);
|
||||
g_free (prefix);
|
||||
return dir;
|
||||
}
|
||||
|
||||
|
||||
@@ -697,20 +725,21 @@ gbr_find_lib_dir (const gchar *default_lib_dir)
|
||||
gchar *
|
||||
gbr_find_libexec_dir (const gchar *default_libexec_dir)
|
||||
{
|
||||
gchar *prefix, *dir;
|
||||
gchar *prefix, *dir;
|
||||
|
||||
prefix = gbr_find_prefix (NULL);
|
||||
if (prefix == NULL) {
|
||||
/* BinReloc not initialized. */
|
||||
if (default_libexec_dir != NULL)
|
||||
return g_strdup (default_libexec_dir);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
prefix = gbr_find_prefix (NULL);
|
||||
if (prefix == NULL)
|
||||
{
|
||||
/* BinReloc not initialized. */
|
||||
if (default_libexec_dir != NULL)
|
||||
return g_strdup (default_libexec_dir);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dir = g_build_filename (prefix, "libexec", NULL);
|
||||
g_free (prefix);
|
||||
return dir;
|
||||
dir = g_build_filename (prefix, "libexec", NULL);
|
||||
g_free (prefix);
|
||||
return dir;
|
||||
}
|
||||
|
||||
|
||||
@@ -730,20 +759,21 @@ gbr_find_libexec_dir (const gchar *default_libexec_dir)
|
||||
gchar *
|
||||
gbr_find_etc_dir (const gchar *default_etc_dir)
|
||||
{
|
||||
gchar *prefix, *dir;
|
||||
gchar *prefix, *dir;
|
||||
|
||||
prefix = gbr_find_prefix (NULL);
|
||||
if (prefix == NULL) {
|
||||
/* BinReloc not initialized. */
|
||||
if (default_etc_dir != NULL)
|
||||
return g_strdup (default_etc_dir);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
prefix = gbr_find_prefix (NULL);
|
||||
if (prefix == NULL)
|
||||
{
|
||||
/* BinReloc not initialized. */
|
||||
if (default_etc_dir != NULL)
|
||||
return g_strdup (default_etc_dir);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dir = g_build_filename (prefix, "etc", NULL);
|
||||
g_free (prefix);
|
||||
return dir;
|
||||
dir = g_build_filename (prefix, "etc", NULL);
|
||||
g_free (prefix);
|
||||
return dir;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -19,35 +19,36 @@ G_BEGIN_DECLS
|
||||
|
||||
|
||||
/** These error codes can be returned by br_init(), br_init_lib(), gbr_init() or gbr_init_lib(). */
|
||||
typedef enum {
|
||||
/** Cannot allocate memory. */
|
||||
GBR_INIT_ERROR_NOMEM,
|
||||
/** Unable to open /proc/self/maps; see errno for details. */
|
||||
GBR_INIT_ERROR_OPEN_MAPS,
|
||||
/** Unable to read from /proc/self/maps; see errno for details. */
|
||||
GBR_INIT_ERROR_READ_MAPS,
|
||||
/** The file format of /proc/self/maps is invalid; kernel bug? */
|
||||
GBR_INIT_ERROR_INVALID_MAPS,
|
||||
/** BinReloc determined that gnucash is not running from a bundle */
|
||||
GBR_INIT_ERROR_MAC_NOT_BUNDLE,
|
||||
/** Binreloc determined that the bundle is not an app bundle */
|
||||
GBR_INIT_ERROR_MAC_NOT_APP_BUNDLE,
|
||||
/** BinReloc is disabled (the ENABLE_BINRELOC macro is not defined). */
|
||||
GBR_INIT_ERROR_DISABLED
|
||||
typedef enum
|
||||
{
|
||||
/** Cannot allocate memory. */
|
||||
GBR_INIT_ERROR_NOMEM,
|
||||
/** Unable to open /proc/self/maps; see errno for details. */
|
||||
GBR_INIT_ERROR_OPEN_MAPS,
|
||||
/** Unable to read from /proc/self/maps; see errno for details. */
|
||||
GBR_INIT_ERROR_READ_MAPS,
|
||||
/** The file format of /proc/self/maps is invalid; kernel bug? */
|
||||
GBR_INIT_ERROR_INVALID_MAPS,
|
||||
/** BinReloc determined that gnucash is not running from a bundle */
|
||||
GBR_INIT_ERROR_MAC_NOT_BUNDLE,
|
||||
/** Binreloc determined that the bundle is not an app bundle */
|
||||
GBR_INIT_ERROR_MAC_NOT_APP_BUNDLE,
|
||||
/** BinReloc is disabled (the ENABLE_BINRELOC macro is not defined). */
|
||||
GBR_INIT_ERROR_DISABLED
|
||||
} GbrInitError;
|
||||
|
||||
|
||||
#ifndef BINRELOC_RUNNING_DOXYGEN
|
||||
/* Mangle symbol names to avoid symbol collisions with other ELF objects. */
|
||||
#define gbr_find_exe ffEt66859784967989_gbr_find_exe
|
||||
#define gbr_find_exe_dir ffEt66859784967989_gbr_find_exe_dir
|
||||
#define gbr_find_prefix ffEt66859784967989_gbr_find_prefix
|
||||
#define gbr_find_bin_dir ffEt66859784967989_gbr_find_bin_dir
|
||||
#define gbr_find_sbin_dir ffEt66859784967989_gbr_find_sbin_dir
|
||||
#define gbr_find_data_dir ffEt66859784967989_gbr_find_data_dir
|
||||
#define gbr_find_lib_dir ffEt66859784967989_gbr_find_lib_dir
|
||||
#define gbr_find_libexec_dir ffEt66859784967989_gbr_find_libexec_dir
|
||||
#define gbr_find_etc_dir ffEt66859784967989_gbr_find_etc_dir
|
||||
#define gbr_find_exe ffEt66859784967989_gbr_find_exe
|
||||
#define gbr_find_exe_dir ffEt66859784967989_gbr_find_exe_dir
|
||||
#define gbr_find_prefix ffEt66859784967989_gbr_find_prefix
|
||||
#define gbr_find_bin_dir ffEt66859784967989_gbr_find_bin_dir
|
||||
#define gbr_find_sbin_dir ffEt66859784967989_gbr_find_sbin_dir
|
||||
#define gbr_find_data_dir ffEt66859784967989_gbr_find_data_dir
|
||||
#define gbr_find_lib_dir ffEt66859784967989_gbr_find_lib_dir
|
||||
#define gbr_find_libexec_dir ffEt66859784967989_gbr_find_libexec_dir
|
||||
#define gbr_find_etc_dir ffEt66859784967989_gbr_find_etc_dir
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,19 +24,19 @@
|
||||
|
||||
/** @addtogroup CapGains Cap Gains
|
||||
* This file implements the various routines to automatically
|
||||
* compute and handle Cap Gains/Losses resulting from trading
|
||||
* activities. Some of these routines might have broader
|
||||
* applicability, for handling depreciation & etc.
|
||||
* compute and handle Cap Gains/Losses resulting from trading
|
||||
* activities. Some of these routines might have broader
|
||||
* applicability, for handling depreciation & etc.
|
||||
*
|
||||
* This code is under development, and is 'beta': we think we're
|
||||
* mostly done, and we've tested and "things work for us", but there
|
||||
* may still be something missing, and there might still be some
|
||||
* may still be something missing, and there might still be some
|
||||
* bugs.
|
||||
*
|
||||
* This code does not currently handle tax distinctions, e.g
|
||||
* the different tax treatment that short-term and long-term
|
||||
* cap gains have.
|
||||
*
|
||||
* the different tax treatment that short-term and long-term
|
||||
* cap gains have.
|
||||
*
|
||||
* The computation of (Realized) Gains/Losses is performed automatically by
|
||||
* the lot "scrub" routines, using a "double-balance" algorithm. Every
|
||||
* split has two numbers associated with it: an "amount", which is the
|
||||
@@ -46,8 +46,8 @@
|
||||
* sold; thus the amount-balance is zero. But since the purchase/sale of
|
||||
* the items in the lot typically happen at different prices, there will
|
||||
* typically be a gain/loss. This gain/loss is the grand-total value of all
|
||||
* the items in the lot (total costs minus total income).
|
||||
*
|
||||
* the items in the lot (total costs minus total income).
|
||||
*
|
||||
* In order to properly account for the gains/losses, an "adjusting split"
|
||||
* is added that brings the total gains/losses back to exactly zero (this
|
||||
* is the second "balance" of "double balance"). This adjusting split will
|
||||
@@ -58,17 +58,17 @@
|
||||
* and then the sale of some item, the "gains transaction" will record $300
|
||||
* in income in an income account. Thus, the change in the bank balance is
|
||||
* always reflected by an equal change in income, assuring that the books
|
||||
* are balanced.
|
||||
* are balanced.
|
||||
*
|
||||
* Notes about auto-recompute: If the amount in a split is changed,
|
||||
* Notes about auto-recompute: If the amount in a split is changed,
|
||||
* then the lot has to be recomputed.
|
||||
* This has a potential trickle-through effect on all later lots.
|
||||
* Ideally, later lots are dissolved, and recomputed. However, some
|
||||
* This has a potential trickle-through effect on all later lots.
|
||||
* Ideally, later lots are dissolved, and recomputed. However, some
|
||||
* lots may have been user-hand-built. These should be left alone.
|
||||
*
|
||||
ToDo:
|
||||
o XXX Need to create a data-integrity scrubber, tht makes sure that
|
||||
the various flags, and pointers & etc. match.
|
||||
the various flags, and pointers & etc. match.
|
||||
* @{ */
|
||||
|
||||
/** @file cap-gains.h
|
||||
@@ -82,9 +82,9 @@ ToDo:
|
||||
|
||||
#include "gnc-engine.h"
|
||||
|
||||
/** The xaccSplitGetCapGains() method returns the value of
|
||||
* capital gains (if any) associated with the indicated
|
||||
* split. In order for there to be any capital gains,
|
||||
/** The xaccSplitGetCapGains() method returns the value of
|
||||
* capital gains (if any) associated with the indicated
|
||||
* split. In order for there to be any capital gains,
|
||||
* several things must hold true about this split:
|
||||
* (1) It must have been involved in trading (for aexample,
|
||||
* by belonging to a stock or trading account)
|
||||
@@ -95,9 +95,9 @@ ToDo:
|
||||
*/
|
||||
gnc_numeric xaccSplitGetCapGains(Split *);
|
||||
|
||||
/** The xaccAccountHasTrades() method checks to see if the
|
||||
/** The xaccAccountHasTrades() method checks to see if the
|
||||
* indicated account is used in the trading of commodities.
|
||||
* A 'trading' account will contain transactions whose
|
||||
* A 'trading' account will contain transactions whose
|
||||
* transaction currency is not the same as the account
|
||||
* commodity. The existance of such transactions is
|
||||
* the very definition of a 'trade'. This routine returns
|
||||
@@ -108,24 +108,24 @@ gboolean xaccAccountHasTrades (const Account *);
|
||||
|
||||
/** The xaccAccountFindEarliestOpenLot() method is a handy
|
||||
* utility routine for finding the earliest open lot in
|
||||
* an account whose lot balance is *opposite* to the
|
||||
* an account whose lot balance is *opposite* to the
|
||||
* passed argument 'sign'. By 'earliest lot', we mean
|
||||
* the lot that has a split with the earliest 'date_posted'.
|
||||
* The sign comparison helps identify a lot that can be
|
||||
* The sign comparison helps identify a lot that can be
|
||||
* added to: usually, one wants to add splits to a lot so
|
||||
* that the balance only decreases.
|
||||
* If 'currency' is non-null, then this attempts to find
|
||||
* a lot whose opening transaction has the same currency.
|
||||
*/
|
||||
GNCLot * xaccAccountFindEarliestOpenLot (Account *acc,
|
||||
gnc_numeric sign,
|
||||
gnc_commodity *currency);
|
||||
GNCLot * xaccAccountFindLatestOpenLot (Account *acc,
|
||||
GNCLot * xaccAccountFindEarliestOpenLot (Account *acc,
|
||||
gnc_numeric sign,
|
||||
gnc_commodity *currency);
|
||||
GNCLot * xaccAccountFindLatestOpenLot (Account *acc,
|
||||
gnc_numeric sign,
|
||||
gnc_commodity *currency);
|
||||
|
||||
/** The xaccAccountGetDefaultGainAccount() routine will return
|
||||
* the account to which realized gains/losses may be posted.
|
||||
* the account to which realized gains/losses may be posted.
|
||||
* Because gains may be in different currencies, one must
|
||||
* specify the currency type in which the gains will be posted.
|
||||
* This routine does nothing more than return the value of
|
||||
@@ -135,10 +135,10 @@ GNCLot * xaccAccountFindLatestOpenLot (Account *acc,
|
||||
*/
|
||||
Account * xaccAccountGetDefaultGainAccount (const Account *acc, const gnc_commodity * currency);
|
||||
|
||||
/** The xaccAccountSetDefaultGainAccount() routine can be used
|
||||
* to set the account to which realized gains/losses will be
|
||||
* posted by default. This routine does nothing more than set
|
||||
* value of the "/lot-mgmt/gains-act/XXX" key, where XXX is the
|
||||
/** The xaccAccountSetDefaultGainAccount() routine can be used
|
||||
* to set the account to which realized gains/losses will be
|
||||
* posted by default. This routine does nothing more than set
|
||||
* value of the "/lot-mgmt/gains-act/XXX" key, where XXX is the
|
||||
* unique currency name of the currency of gains account.
|
||||
*/
|
||||
void xaccAccountSetDefaultGainAccount (Account *acc, const Account *gains_acct);
|
||||
@@ -147,25 +147,25 @@ void xaccAccountSetDefaultGainAccount (Account *acc, const Account *gains_acct);
|
||||
* that records the cap gains for this split. It returns NULL
|
||||
* if not found. This routine does nothing more than search for
|
||||
* the split recorded in the KVP key "/gains-split"
|
||||
*/
|
||||
*/
|
||||
Split * xaccSplitGetCapGainsSplit (const Split *);
|
||||
|
||||
/** The xaccSplitGetGainsSourceSplit() routine returns the split
|
||||
* that is the source of the cap gains in this split. It returns
|
||||
* NULL if not found. This routine does nothing more than search
|
||||
* NULL if not found. This routine does nothing more than search
|
||||
* for the split recorded in the KVP key "/gains-source"
|
||||
*/
|
||||
*/
|
||||
Split * xaccSplitGetGainsSourceSplit (const Split *);
|
||||
|
||||
/** The`xaccSplitAssign() routine will take the indicated
|
||||
* split and, if it doesn't already belong to a lot, it will attempt
|
||||
* split and, if it doesn't already belong to a lot, it will attempt
|
||||
* to assign it to an appropriate lot.
|
||||
* If the split already belongs to a Lot, this routine does nothing.
|
||||
* If there are no open Lots, this routine will create a new lot
|
||||
* and place the split into it. If there's an open lot, and its
|
||||
* big enough to accept the split in it's entirety, then the split
|
||||
* will be placed into that lot. If the split is too big to fit
|
||||
* into the currently open lot, it will be busted up into two
|
||||
* into the currently open lot, it will be busted up into two
|
||||
* (or more) pieces, and each placed into a lot accordingly.
|
||||
* If the split needed to be broken up into several pieces, this
|
||||
* routine will return TRUE, else it returns FALSE.
|
||||
@@ -174,7 +174,7 @@ Split * xaccSplitGetGainsSourceSplit (const Split *);
|
||||
* directory is used to identify the peers. 'gemini'-style kvp's
|
||||
* are used.
|
||||
*
|
||||
* This routine uses the "FIFOPolicy" callback, and thus
|
||||
* This routine uses the "FIFOPolicy" callback, and thus
|
||||
* implements a "FIFO" First-In First-Out accounting policy.
|
||||
* This is currently the only implemented policy; adding new
|
||||
* policies should be 'easy'; read the source luke.
|
||||
@@ -208,7 +208,7 @@ Split * xaccSplitAssignToLot (Split *split, GNCLot *lot);
|
||||
* default account is used (and created, if needed).
|
||||
*
|
||||
* To compute the gains, the split must belong to a lot. If the
|
||||
* split is the 'opening split', i.e. the earliest split in the
|
||||
* split is the 'opening split', i.e. the earliest split in the
|
||||
* lot, then nothing is done, as there are no gains/losses (something
|
||||
* must be bought *and* sold for there to be a gain/loss).
|
||||
*
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include "cashobjects.h"
|
||||
#include "gnc-engine.h"
|
||||
@@ -37,15 +37,15 @@
|
||||
gboolean
|
||||
cashobjects_register(void)
|
||||
{
|
||||
g_return_val_if_fail(gnc_commodity_table_register(), FALSE);
|
||||
g_return_val_if_fail(xaccAccountRegister(), FALSE);
|
||||
g_return_val_if_fail ( xaccTransRegister(), FALSE);
|
||||
g_return_val_if_fail ( xaccSplitRegister(), FALSE);
|
||||
g_return_val_if_fail ( SXRegister (), FALSE);
|
||||
g_return_val_if_fail ( gnc_sxtt_register(), FALSE);
|
||||
g_return_val_if_fail(gnc_pricedb_register(),FALSE);
|
||||
g_return_val_if_fail (gnc_budget_register(),FALSE);
|
||||
g_return_val_if_fail ( gnc_lot_register (), FALSE);
|
||||
return TRUE;
|
||||
g_return_val_if_fail(gnc_commodity_table_register(), FALSE);
|
||||
g_return_val_if_fail(xaccAccountRegister(), FALSE);
|
||||
g_return_val_if_fail ( xaccTransRegister(), FALSE);
|
||||
g_return_val_if_fail ( xaccSplitRegister(), FALSE);
|
||||
g_return_val_if_fail ( SXRegister (), FALSE);
|
||||
g_return_val_if_fail ( gnc_sxtt_register(), FALSE);
|
||||
g_return_val_if_fail(gnc_pricedb_register(), FALSE);
|
||||
g_return_val_if_fail (gnc_budget_register(), FALSE);
|
||||
g_return_val_if_fail ( gnc_lot_register (), FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/* a convenience header for anyone working with the libcashobjects.la library. */
|
||||
|
||||
|
||||
/* a convenience header for anyone working with the libcashobjects.la library. */
|
||||
|
||||
#ifndef _CASHOBJECTS_H
|
||||
#define _CASHOBJECTS_H
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/********************************************************************\
|
||||
* glib-helpers.h -- gnucash glib helper functions *
|
||||
* Copyright (C) 2000 Linas Vepstas *
|
||||
* Copyright (C) 2006 Chris Shoemaker <c.shoemaker@cox.net> *
|
||||
* Copyright (C) 2006 Chris Shoemaker <c.shoemaker@cox.net> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
* gnc-associate-account.h : api for associating income and *
|
||||
* expense accounts with stock/mutual fund accounts, for tracking *
|
||||
* dividends, brokerage, and other stock-related expenses and *
|
||||
* income so that they can be reported *
|
||||
* income so that they can be reported *
|
||||
* Copyright 2000 Gnumatic Incorporated *
|
||||
* Written by Robert Merkel <rgmerk@mira.net> *
|
||||
*
|
||||
*
|
||||
* WARNING WARNING WARNING: THIS CODE IS TOTALLY UNTESTED. *
|
||||
* THE ONLY REASON IT'S IN CVS IS FOR SAFEKEEPING *
|
||||
* *
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <Account.h>
|
||||
#include <glib.h>
|
||||
|
||||
/*
|
||||
/*
|
||||
* account_list is a list of account *'s, all of which much be expense
|
||||
* accounts
|
||||
*/
|
||||
@@ -40,50 +40,52 @@ typedef enum {GNC_TR_INC_MISC,
|
||||
GNC_TR_INC__DIVIDEND,
|
||||
GNC_TR_INC_LT_CG,
|
||||
GNC_TR_INC_ST_CG,
|
||||
GNC_TR_INC_N_CATEGORIES} GNCTrackingIncomeCategory;
|
||||
GNC_TR_INC_N_CATEGORIES
|
||||
} GNCTrackingIncomeCategory;
|
||||
|
||||
typedef enum {GNC_TR_EXP_MISC,
|
||||
GNC_TR_EXP_COMMISSION,
|
||||
GNC_TR_EXP_N_CATEGORIES} GNCTrackingExpenseCategory;
|
||||
|
||||
GNC_TR_EXP_N_CATEGORIES
|
||||
} GNCTrackingExpenseCategory;
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
* account_list is a list of account *'s, all of which much be expense
|
||||
* accounts. You can clear associations by setting account_list to NULL
|
||||
*/
|
||||
|
||||
void gnc_tracking_associate_income_accounts(Account *stock_account,
|
||||
GNCTrackingIncomeCategory category,
|
||||
AccountList *account_list);
|
||||
*/
|
||||
|
||||
void gnc_tracking_associate_income_accounts(Account *stock_account,
|
||||
GNCTrackingIncomeCategory category,
|
||||
AccountList *account_list);
|
||||
|
||||
|
||||
void gnc_tracking_asssociate_expense_account(Account *stock_account,
|
||||
GNCTrackingExpenseCategory category,
|
||||
AccountList *account_list);
|
||||
GNCTrackingExpenseCategory category,
|
||||
AccountList *account_list);
|
||||
|
||||
/*
|
||||
* returns a list of account *'s,
|
||||
* returns null if no association specified
|
||||
/*
|
||||
* returns a list of account *'s,
|
||||
* returns null if no association specified
|
||||
*/
|
||||
|
||||
AccountList *gnc_tracking_find_expense_accounts(Account *stock_account,
|
||||
GNCTrackingExpenseCategory category);
|
||||
AccountList *gnc_tracking_find_expense_accounts(Account *stock_account,
|
||||
GNCTrackingExpenseCategory category);
|
||||
|
||||
AccountList *gnc_tracking_find_income_accounts(Account *stock_account,
|
||||
GNCTrackingIncomeCategory category);
|
||||
AccountList *gnc_tracking_find_income_accounts(Account *stock_account,
|
||||
GNCTrackingIncomeCategory category);
|
||||
|
||||
/* for ROI purposes we don't care about categories, these are "grab
|
||||
all" for that purpose */
|
||||
|
||||
|
||||
AccountList *gnc_tracking_find_all_expense_accounts(Account *stock_account);
|
||||
|
||||
AccountList *gnc_tracking_find_all_income_accounts(Account *stock_account);
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
* reverse lookup - obviously returns a stock account (or NULL if none
|
||||
* associated), and argument must be an income or expense account
|
||||
*/
|
||||
*/
|
||||
Account *gnc_tracking_find_stock_account(Account *inc_or_expense_acc);
|
||||
|
||||
void gnc_tracking_dissociate_account(Account *inc_or_expense_account);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
/** @addtogroup budget
|
||||
/** @addtogroup budget
|
||||
@{
|
||||
*/
|
||||
/** @file gnc-budget.h
|
||||
@@ -95,7 +95,8 @@ gboolean gnc_budget_register(void);
|
||||
/**
|
||||
* Creates and initializes a Budget.
|
||||
**/
|
||||
/*@ dependent @*/ GncBudget *gnc_budget_new(QofBook *book);
|
||||
/*@ dependent @*/
|
||||
GncBudget *gnc_budget_new(QofBook *book);
|
||||
|
||||
/** Deletes the given budget object.*/
|
||||
void gnc_budget_destroy(GncBudget* budget);
|
||||
@@ -103,24 +104,28 @@ void gnc_budget_destroy(GncBudget* budget);
|
||||
void gnc_budget_begin_edit(GncBudget *bgt);
|
||||
void gnc_budget_commit_edit(GncBudget *bgt);
|
||||
|
||||
/*@ dependent @*/ const GUID* gnc_budget_get_guid(GncBudget* budget);
|
||||
/*@ dependent @*/
|
||||
const GUID* gnc_budget_get_guid(GncBudget* budget);
|
||||
#define gnc_budget_return_guid(X) \
|
||||
(X ? *(qof_entity_get_guid(QOF_INSTANCE(X))) : *(guid_null()))
|
||||
|
||||
/** Set/Get the name of the Budget */
|
||||
void gnc_budget_set_name(GncBudget* budget, const gchar* name);
|
||||
/*@ dependent @*/ const gchar* gnc_budget_get_name(GncBudget* budget);
|
||||
/*@ dependent @*/
|
||||
const gchar* gnc_budget_get_name(GncBudget* budget);
|
||||
|
||||
/** Set/Get the description of the Budget */
|
||||
void gnc_budget_set_description(GncBudget* budget, const gchar* description);
|
||||
/*@ dependent @*/ const gchar* gnc_budget_get_description(GncBudget* budget);
|
||||
/*@ dependent @*/
|
||||
const gchar* gnc_budget_get_description(GncBudget* budget);
|
||||
|
||||
/** Set/Get the number of periods in the Budget */
|
||||
void gnc_budget_set_num_periods(GncBudget* budget, guint num_periods);
|
||||
guint gnc_budget_get_num_periods(GncBudget* budget);
|
||||
|
||||
void gnc_budget_set_recurrence(GncBudget *budget, const Recurrence *r);
|
||||
/*@ dependent @*/ const Recurrence * gnc_budget_get_recurrence(GncBudget *budget);
|
||||
/*@ dependent @*/
|
||||
const Recurrence * gnc_budget_get_recurrence(GncBudget *budget);
|
||||
|
||||
/** Get the starting date of the Budget period*/
|
||||
Timespec gnc_budget_get_period_start_date(GncBudget* budget, guint period_num);
|
||||
@@ -149,7 +154,8 @@ QofBook* gnc_budget_get_book(GncBudget* budget);
|
||||
GncBudget* gnc_budget_get_default(QofBook *book);
|
||||
|
||||
/* Get the budget associated with the given GUID from the given book. */
|
||||
/*@ dependent @*/ GncBudget* gnc_budget_lookup (const GUID *guid, QofBook *book);
|
||||
/*@ dependent @*/
|
||||
GncBudget* gnc_budget_lookup (const GUID *guid, QofBook *book);
|
||||
#define gnc_budget_lookup_direct(g,b) gnc_budget_lookup(&(g),(b))
|
||||
|
||||
#endif // __BUDGET_H__
|
||||
|
||||
@@ -26,19 +26,19 @@
|
||||
A commodity is something of value that is easily tradeable or
|
||||
sellable; for example, currencies, stocks, bonds, grain,
|
||||
copper, and oil are all commodities. This file provides
|
||||
an API for defining a commodities, and for working with
|
||||
an API for defining a commodities, and for working with
|
||||
collections of commodities. All GnuCash financial transactions
|
||||
must identify the commodity that is being traded.
|
||||
|
||||
@warning The system used here does not follow the object
|
||||
handling and identification system (GUID's, Entities, etc.)
|
||||
that the other parts of GnuCash use. The API really should be
|
||||
ported over. This would allow us to get rid of the
|
||||
commodity table routines defined below.
|
||||
ported over. This would allow us to get rid of the
|
||||
commodity table routines defined below.
|
||||
|
||||
@{ */
|
||||
/** @file gnc-commodity.h
|
||||
* @brief Commodity handling public routines
|
||||
* @brief Commodity handling public routines
|
||||
* @author Copyright (C) 2000 Bill Gribble
|
||||
* @author Copyright (C) 2001 Linas Vepstas <linas@linas.org>
|
||||
*/
|
||||
@@ -85,7 +85,7 @@ GType gnc_commodity_namespace_get_type(void);
|
||||
|
||||
/** The commodity namespace definitions are used to tag a commodity by
|
||||
* its type, or a stocks by the exchange where it is traded.
|
||||
*
|
||||
*
|
||||
* The LEGACY name is only used by the file i/o routines, and is
|
||||
* converted to another commodity namespace before it is seen by the
|
||||
* rest of the system. The ISO namespace represents currencies.
|
||||
@@ -107,7 +107,7 @@ GType gnc_commodity_namespace_get_type(void);
|
||||
|
||||
typedef GList CommodityList;
|
||||
|
||||
/** @name Commodity Quote Source functions
|
||||
/** @name Commodity Quote Source functions
|
||||
@{
|
||||
*/
|
||||
|
||||
@@ -117,19 +117,19 @@ typedef GList CommodityList;
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
SOURCE_SINGLE = 0, /**< This quote source pulls from a single
|
||||
SOURCE_SINGLE = 0, /**< This quote source pulls from a single
|
||||
* specific web site. For example, the
|
||||
* yahoo_australia source only pulls from
|
||||
* the yahoo web site. */
|
||||
SOURCE_MULTI, /**< This quote source may pull from multiple
|
||||
SOURCE_MULTI, /**< This quote source may pull from multiple
|
||||
* web sites. For example, the australia
|
||||
* source may pull from ASX, yahoo, etc. */
|
||||
SOURCE_UNKNOWN, /**< This is a locally installed quote source
|
||||
SOURCE_UNKNOWN, /**< This is a locally installed quote source
|
||||
* that gnucash knows nothing about. May
|
||||
* pull from single or multiple
|
||||
* locations. */
|
||||
SOURCE_MAX,
|
||||
SOURCE_CURRENCY = SOURCE_MAX, /**< The special currency quote source. */
|
||||
SOURCE_MAX,
|
||||
SOURCE_CURRENCY = SOURCE_MAX, /**< The special currency quote source. */
|
||||
} QuoteSourceType;
|
||||
|
||||
/** This function indicates whether or not the Finance::Quote module
|
||||
@@ -180,7 +180,8 @@ gnc_quote_source *gnc_quote_source_add_new(const char * name, gboolean supported
|
||||
* @return A pointer to the price quote source that has the specified
|
||||
* internal name.
|
||||
*/
|
||||
/*@ dependent @*/ gnc_quote_source *gnc_quote_source_lookup_by_internal(const char * internal_name);
|
||||
/*@ dependent @*/
|
||||
gnc_quote_source *gnc_quote_source_lookup_by_internal(const char * internal_name);
|
||||
|
||||
/** Given the type/index of a quote source, find the data structure
|
||||
* identified by this pair.
|
||||
@@ -230,7 +231,8 @@ gint gnc_quote_source_get_index (const gnc_quote_source *source);
|
||||
*
|
||||
* @return The user friendly name.
|
||||
*/
|
||||
/*@ dependent @*/ const char *gnc_quote_source_get_user_name (const gnc_quote_source *source);
|
||||
/*@ dependent @*/
|
||||
const char *gnc_quote_source_get_user_name (const gnc_quote_source *source);
|
||||
|
||||
/** Given a gnc_quote_source data structure, return the internal name
|
||||
* of this quote source. This is the name used by both gnucash and
|
||||
@@ -240,7 +242,8 @@ gint gnc_quote_source_get_index (const gnc_quote_source *source);
|
||||
*
|
||||
* @return The internal name.
|
||||
*/
|
||||
/*@ dependent @*/ const char *gnc_quote_source_get_internal_name (const gnc_quote_source *source);
|
||||
/*@ dependent @*/
|
||||
const char *gnc_quote_source_get_internal_name (const gnc_quote_source *source);
|
||||
|
||||
/** Given a gnc_quote_source data structure, return the internal name
|
||||
* of this quote source. This is the name used by both gnucash and
|
||||
@@ -258,8 +261,8 @@ const char *gnc_quote_source_get_old_internal_name (const gnc_quote_source *sour
|
||||
/** @} */
|
||||
|
||||
|
||||
/** @name Commodity Creation
|
||||
@{
|
||||
/** @name Commodity Creation
|
||||
@{
|
||||
*/
|
||||
|
||||
/** Create a new commodity. This function allocates a new commodity
|
||||
@@ -294,8 +297,9 @@ const char *gnc_quote_source_get_old_internal_name (const gnc_quote_source *sour
|
||||
*
|
||||
* @return A pointer to the new commodity.
|
||||
*/
|
||||
/*@ dependent @*/ gnc_commodity * gnc_commodity_new(QofBook *book,
|
||||
/*@ null @*/ const char * fullname,
|
||||
/*@ dependent @*/
|
||||
gnc_commodity * gnc_commodity_new(QofBook *book,
|
||||
/*@ null @*/ const char * fullname,
|
||||
/*@ null @*/ const char * namespace,
|
||||
/*@ null @*/ const char * mnemonic,
|
||||
/*@ null @*/ const char * cusip,
|
||||
@@ -451,8 +455,10 @@ gboolean gnc_commodity_get_quote_flag(const gnc_commodity *cm);
|
||||
*
|
||||
* @return A pointer to the price quote source for this commodity.
|
||||
*/
|
||||
/*@ dependent @*/ gnc_quote_source* gnc_commodity_get_quote_source(const gnc_commodity *cm);
|
||||
/*@ dependent @*/ gnc_quote_source* gnc_commodity_get_default_quote_source(const gnc_commodity *cm);
|
||||
/*@ dependent @*/
|
||||
gnc_quote_source* gnc_commodity_get_quote_source(const gnc_commodity *cm);
|
||||
/*@ dependent @*/
|
||||
gnc_quote_source* gnc_commodity_get_default_quote_source(const gnc_commodity *cm);
|
||||
|
||||
/** Retrieve the automatic price quote timezone for the specified
|
||||
* commodity. This will be a pointer to a null terminated string of
|
||||
@@ -615,7 +621,7 @@ gnc_commodity_decrement_usage_count(gnc_commodity *cm);
|
||||
/** @} */
|
||||
|
||||
|
||||
/** @name Commodity Comparison
|
||||
/** @name Commodity Comparison
|
||||
@{
|
||||
*/
|
||||
|
||||
@@ -650,7 +656,7 @@ int gnc_commodity_compare_void(const void * a, const void * b);
|
||||
/** @} */
|
||||
|
||||
|
||||
/** @name Currency Checks
|
||||
/** @name Currency Checks
|
||||
@{
|
||||
*/
|
||||
|
||||
@@ -681,13 +687,14 @@ gboolean gnc_commodity_is_currency(const gnc_commodity *cm);
|
||||
|
||||
|
||||
/* =============================================================== */
|
||||
/** @name Commodity Table
|
||||
/** @name Commodity Table
|
||||
@{
|
||||
*/
|
||||
|
||||
/** Returns the commodity table assoicated with a book.
|
||||
*/
|
||||
/*@ dependent @*/ gnc_commodity_table * gnc_commodity_table_get_table(QofBook *book);
|
||||
/*@ dependent @*/
|
||||
gnc_commodity_table * gnc_commodity_table_get_table(QofBook *book);
|
||||
|
||||
/* XXX backwards compat function; remove me someday */
|
||||
#define gnc_book_get_commodity_table gnc_commodity_table_get_table
|
||||
@@ -705,17 +712,18 @@ void gnc_commodity_table_copy(gnc_commodity_table *dest,
|
||||
/** @name Commodity Table Lookup functions
|
||||
@{
|
||||
*/
|
||||
gnc_commodity * gnc_commodity_table_lookup(const gnc_commodity_table * table,
|
||||
const char * namespace,
|
||||
const char * mnemonic);
|
||||
gnc_commodity * gnc_commodity_table_lookup(const gnc_commodity_table * table,
|
||||
const char * namespace,
|
||||
const char * mnemonic);
|
||||
gnc_commodity *
|
||||
gnc_commodity_table_lookup_unique(const gnc_commodity_table *table,
|
||||
const char * unique_name);
|
||||
gnc_commodity * gnc_commodity_table_find_full(const gnc_commodity_table * t,
|
||||
const char * namespace,
|
||||
const char * fullname);
|
||||
const char * namespace,
|
||||
const char * fullname);
|
||||
|
||||
/*@ dependent @*/ gnc_commodity * gnc_commodity_find_commodity_by_guid(const GUID *guid, QofBook *book);
|
||||
/*@ dependent @*/
|
||||
gnc_commodity * gnc_commodity_find_commodity_by_guid(const GUID *guid, QofBook *book);
|
||||
gnc_commodity_namespace * gnc_commodity_find_namespace_by_guid(const GUID *guid, QofBook *book);
|
||||
|
||||
/** @} */
|
||||
@@ -730,7 +738,7 @@ gnc_commodity_namespace * gnc_commodity_find_namespace_by_guid(const GUID *guid,
|
||||
* nothing), or another entries has the same namespace and mnemonic
|
||||
* (updates the existing entry).
|
||||
*
|
||||
* @param table A pointer to the commodity table
|
||||
* @param table A pointer to the commodity table
|
||||
*
|
||||
* @param comm A pointer to the commodity to add.
|
||||
*
|
||||
@@ -739,17 +747,18 @@ gnc_commodity_namespace * gnc_commodity_find_namespace_by_guid(const GUID *guid,
|
||||
* @note The commodity pointer passed to this function should not be
|
||||
* used after its return, as it may have been destroyed. Use the
|
||||
* return value which is guaranteed to be valid. */
|
||||
/*@ dependent @*/ gnc_commodity * gnc_commodity_table_insert(gnc_commodity_table * table,
|
||||
gnc_commodity * comm);
|
||||
/*@ dependent @*/
|
||||
gnc_commodity * gnc_commodity_table_insert(gnc_commodity_table * table,
|
||||
gnc_commodity * comm);
|
||||
|
||||
/** Remove a commodity from the commodity table. If the commodity to
|
||||
* remove doesn't exist, nothing happens.
|
||||
*
|
||||
* @param table A pointer to the commodity table
|
||||
* @param table A pointer to the commodity table
|
||||
*
|
||||
* @param comm A pointer to the commodity to remove. */
|
||||
void gnc_commodity_table_remove(gnc_commodity_table * table,
|
||||
gnc_commodity * comm);
|
||||
gnc_commodity * comm);
|
||||
|
||||
/** Add all the standard namespaces and currencies to the commodity
|
||||
* table. This routine creates the namespaces for the NYSE, NASDAQ,
|
||||
@@ -794,14 +803,14 @@ guint gnc_commodity_table_get_number_of_namespaces(const gnc_commodity_table* tb
|
||||
|
||||
/** Test to see if the indicated namespace exits in the commodity table.
|
||||
*
|
||||
* @param table A pointer to the commodity table
|
||||
* @param table A pointer to the commodity table
|
||||
*
|
||||
* @param namespace The new namespace to check.
|
||||
*
|
||||
* @return 1 if the namespace exists. 0 if it doesn't exist, or the
|
||||
* routine was passed a bad argument. */
|
||||
int gnc_commodity_table_has_namespace(const gnc_commodity_table * table,
|
||||
const char * namespace);
|
||||
const char * namespace);
|
||||
|
||||
/** Return a list of all namespaces in the commodity table. This
|
||||
* returns both system and user defined namespaces.
|
||||
@@ -824,7 +833,7 @@ GList * gnc_commodity_table_get_namespaces_list(const gnc_commodity_table * t);
|
||||
/** This function adds a new string to the list of commodity namespaces.
|
||||
* If the new namespace already exists, nothing happens.
|
||||
*
|
||||
* @param table A pointer to the commodity table
|
||||
* @param table A pointer to the commodity table
|
||||
*
|
||||
* @param namespace The new namespace to be added.
|
||||
*
|
||||
@@ -832,31 +841,31 @@ GList * gnc_commodity_table_get_namespaces_list(const gnc_commodity_table * t);
|
||||
*
|
||||
* @return A pointer to the newly created namespace. */
|
||||
gnc_commodity_namespace * gnc_commodity_table_add_namespace(gnc_commodity_table * table,
|
||||
const char * namespace,
|
||||
QofBook *book);
|
||||
const char * namespace,
|
||||
QofBook *book);
|
||||
|
||||
/** This function finds a commodity namespace in the set of existing commodity namespaces.
|
||||
*
|
||||
* @param table A pointer to the commodity table
|
||||
* @param table A pointer to the commodity table
|
||||
*
|
||||
* @param namespace The new namespace to be added.
|
||||
*
|
||||
* @return The a pointer to the namespace found, or NULL if the
|
||||
* namespace doesn't exist. */
|
||||
gnc_commodity_namespace * gnc_commodity_table_find_namespace(const gnc_commodity_table * table,
|
||||
const char * namespace);
|
||||
const char * namespace);
|
||||
|
||||
/** This function deletes a string from the list of commodity namespaces.
|
||||
* If the namespace does not exist, nothing happens.
|
||||
*
|
||||
* @param table A pointer to the commodity table
|
||||
* @param table A pointer to the commodity table
|
||||
*
|
||||
* @param namespace The namespace to be deleted.
|
||||
*
|
||||
* @note This routine will destroy any commodities that exist as part
|
||||
* of this namespace. Use it carefully. */
|
||||
void gnc_commodity_table_delete_namespace(gnc_commodity_table * table,
|
||||
const char * namespace);
|
||||
const char * namespace);
|
||||
/** @} */
|
||||
/* ---------------------------------------------------------- */
|
||||
/** @name Commodity Table Accessor functions
|
||||
@@ -865,7 +874,7 @@ void gnc_commodity_table_delete_namespace(gnc_commodity_table * table,
|
||||
|
||||
/** Returns the number of commodities in the commodity table.
|
||||
*
|
||||
* @param tbl A pointer to the commodity table
|
||||
* @param tbl A pointer to the commodity table
|
||||
*
|
||||
* @return The number of commodities in the table. 0 if there are no
|
||||
* commodities, or the routine was passed a bad argument. */
|
||||
@@ -874,7 +883,7 @@ guint gnc_commodity_table_get_size(const gnc_commodity_table* tbl);
|
||||
/** Return a list of all commodities in the commodity table that are
|
||||
* in the given namespace.
|
||||
*
|
||||
* @param table A pointer to the commodity table
|
||||
* @param table A pointer to the commodity table
|
||||
*
|
||||
* @param namespace A string indicating which commodities should be
|
||||
* returned. It is a required argument.
|
||||
@@ -896,7 +905,7 @@ CommodityList * gnc_commodity_table_get_commodities(
|
||||
* regular expression are checked. If none was given, all
|
||||
* commodities are checked.
|
||||
*
|
||||
* @param table A pointer to the commodity table
|
||||
* @param table A pointer to the commodity table
|
||||
*
|
||||
* @return A pointer to a list of commodities. NULL if invalid
|
||||
* arguments were supplied or if there no commodities are flagged for
|
||||
@@ -910,16 +919,16 @@ CommodityList * gnc_commodity_table_get_quotable_commodities(
|
||||
* This table walk returns whenever the end of the table is reached,
|
||||
* or the function returns FALSE.
|
||||
*
|
||||
* @param table A pointer to the commodity table
|
||||
* @param table A pointer to the commodity table
|
||||
*
|
||||
* @param f The function to call for each commodity.
|
||||
*
|
||||
* @param user_data A pointer that is passed into the function
|
||||
* unchanged by the table walk routine. */
|
||||
gboolean gnc_commodity_table_foreach_commodity(const gnc_commodity_table * table,
|
||||
gboolean (*f)(gnc_commodity *cm,
|
||||
gpointer user_data),
|
||||
gpointer user_data);
|
||||
gboolean (*f)(gnc_commodity *cm,
|
||||
gpointer user_data),
|
||||
gpointer user_data);
|
||||
/** @} */
|
||||
|
||||
|
||||
@@ -936,7 +945,7 @@ gnc_commodity_table * gnc_commodity_table_new(void);
|
||||
void gnc_commodity_table_destroy(gnc_commodity_table * table);
|
||||
|
||||
/** Given the commodity 'from', this routine will find and return the
|
||||
* equivalent commodity (commodity with the same 'unique name') in
|
||||
* equivalent commodity (commodity with the same 'unique name') in
|
||||
* the indicated book. This routine is primarily useful for setting
|
||||
* up clones of things across multiple books.
|
||||
*/
|
||||
@@ -950,7 +959,7 @@ gboolean gnc_commodity_table_register (void);
|
||||
|
||||
void gnc_commodity_begin_edit (gnc_commodity *cm);
|
||||
void gnc_commodity_commit_edit (gnc_commodity *cm);
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @name Monetary value, commodity identity and numeric value
|
||||
@@ -958,55 +967,62 @@ void gnc_commodity_commit_edit (gnc_commodity *cm);
|
||||
*/
|
||||
struct _gnc_monetary
|
||||
{
|
||||
gnc_commodity *commodity;
|
||||
gnc_numeric value;
|
||||
gnc_commodity *commodity;
|
||||
gnc_numeric value;
|
||||
};
|
||||
|
||||
typedef struct _gnc_monetary gnc_monetary;
|
||||
|
||||
/* A list of monetary values. This could be a hash table, but as currently
|
||||
* used it rarely contains more than one or two different commodities so
|
||||
* it doesn't seem worth the trouble.
|
||||
* used it rarely contains more than one or two different commodities so
|
||||
* it doesn't seem worth the trouble.
|
||||
*/
|
||||
typedef GList MonetaryList;
|
||||
|
||||
/** @name Constructors
|
||||
@{
|
||||
Make a gnc_monetary from a gnc_commodity and gnc_numeric */
|
||||
static inline
|
||||
gnc_monetary gnc_monetary_create(gnc_commodity *commod, gnc_numeric val) {
|
||||
static inline
|
||||
gnc_monetary gnc_monetary_create(gnc_commodity *commod, gnc_numeric val)
|
||||
{
|
||||
gnc_monetary out;
|
||||
out.commodity = commod;
|
||||
out.value = val;
|
||||
return out;
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** @name Accessors
|
||||
@{
|
||||
*/
|
||||
static inline
|
||||
gnc_commodity * gnc_monetary_commodity(gnc_monetary a) { return a.commodity; }
|
||||
|
||||
static inline
|
||||
gnc_numeric gnc_monetary_value(gnc_monetary a) { return a.value; }
|
||||
/** @} */
|
||||
|
||||
/** @name Manipulate MonetaryList lists
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** @name Accessors
|
||||
@{
|
||||
*/
|
||||
static inline
|
||||
gnc_commodity * gnc_monetary_commodity(gnc_monetary a)
|
||||
{
|
||||
return a.commodity;
|
||||
}
|
||||
|
||||
static inline
|
||||
gnc_numeric gnc_monetary_value(gnc_monetary a)
|
||||
{
|
||||
return a.value;
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** @name Manipulate MonetaryList lists
|
||||
@{
|
||||
*/
|
||||
|
||||
/** Add a gnc_monetary to the list */
|
||||
MonetaryList *gnc_monetary_list_add_monetary(MonetaryList *list, gnc_monetary mon);
|
||||
|
||||
/** Add something to the list given a commodity and value */
|
||||
static inline
|
||||
MonetaryList *gnc_monetary_list_add_value(MonetaryList *list,
|
||||
gnc_commodity *commod,
|
||||
gnc_numeric value)
|
||||
MonetaryList *gnc_monetary_list_add_value(MonetaryList *list,
|
||||
gnc_commodity *commod,
|
||||
gnc_numeric value)
|
||||
{
|
||||
return gnc_monetary_list_add_monetary(list,
|
||||
gnc_monetary_create(commod, value));
|
||||
return gnc_monetary_list_add_monetary(list,
|
||||
gnc_monetary_create(commod, value));
|
||||
}
|
||||
|
||||
/** Delete all the zero-value entries from a list */
|
||||
|
||||
@@ -22,10 +22,10 @@
|
||||
/** @addtogroup Engine GnuCash Engine: Core, Non-GUI Accounting Functions
|
||||
The GnuCash Engine provides a set of objects and classes that
|
||||
encapsulate typical financial accounting concepts. The GnuCash
|
||||
GUI is expected to manipulate these objects through the provided
|
||||
GUI is expected to manipulate these objects through the provided
|
||||
engine API.
|
||||
@{ */
|
||||
/** @file gnc-engine.h
|
||||
/** @file gnc-engine.h
|
||||
@brief All type declarations for the whole Gnucash engine
|
||||
@author Copyright (C) 1997 Robin D. Clark
|
||||
@author Copyright (C) 2000 Bill Gribble <grib@billgribble.com>
|
||||
@@ -68,7 +68,7 @@
|
||||
//@}
|
||||
|
||||
/** @brief IDENTIFIERS
|
||||
* GUID Identifiers can be used to reference Accounts, Transactions,
|
||||
* GUID Identifiers can be used to reference Accounts, Transactions,
|
||||
* Splits and other objects. These Gnucash types are referred to as Gnucash
|
||||
* entities. GUID Identifiers are globally-unique and permanent, i.e., once
|
||||
* an entity has been assigned an identifier, it retains that same
|
||||
@@ -81,7 +81,7 @@
|
||||
* to any entity. An identifier with any other type 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.
|
||||
* identifier.
|
||||
*/
|
||||
|
||||
#define GNC_ID_NONE QOF_ID_NONE
|
||||
@@ -124,14 +124,14 @@
|
||||
*/
|
||||
|
||||
|
||||
/** @brief Account in Gnucash.
|
||||
/** @brief Account in Gnucash.
|
||||
* This is the typename for an account. The actual structure is
|
||||
* defined in the private header AccountP.h, but no one outside the
|
||||
* engine should include that file. Instead, access that data only
|
||||
* through the functions in Account.h .*/
|
||||
typedef struct account_s Account;
|
||||
|
||||
/** @brief Split in Gnucash.
|
||||
/** @brief Split in Gnucash.
|
||||
* A "split" is more commonly refered to as a "entry" in a
|
||||
* "transaction". Each split belongs to one Account and one
|
||||
* Transaction. The split is one out of several parts a Transaction is
|
||||
@@ -143,7 +143,7 @@ typedef struct account_s Account;
|
||||
* the functions in Transaction.h .*/
|
||||
typedef struct split_s Split;
|
||||
|
||||
/** @brief Transaction in Gnucash.
|
||||
/** @brief Transaction in Gnucash.
|
||||
* A Transaction is a piece of business done; the transfer of money
|
||||
* from one account to one or more other accounts. Each Transaction is
|
||||
* divided into one or more Splits (usually two).
|
||||
@@ -154,7 +154,7 @@ typedef struct split_s Split;
|
||||
* through the functions in Transaction.h .*/
|
||||
typedef struct transaction_s Transaction;
|
||||
|
||||
/** @brief An article that is bought and sold.
|
||||
/** @brief An article that is bought and sold.
|
||||
* A Commodity is the most general term of what an account keeps track
|
||||
* of. Usually this is a monetary currency, but it can also be a stock
|
||||
* share or even a precious metal. Every account keeps track of
|
||||
@@ -177,8 +177,8 @@ typedef struct gnc_commodity_namespace_s gnc_commodity_namespace;
|
||||
typedef struct gnc_commodity_table_s gnc_commodity_table;
|
||||
|
||||
/** @brief Identifies that something sold at one time was bought at another.
|
||||
* A GNCLot provides a way of tracking physical items as they are
|
||||
* bought and sold in different transactions. By identifying
|
||||
* A GNCLot provides a way of tracking physical items as they are
|
||||
* bought and sold in different transactions. By identifying
|
||||
* the individual, underlying physical objects, it provides the
|
||||
* needed framework for implementing depreciation, capital gains,
|
||||
* inventory control and invoices.
|
||||
@@ -189,7 +189,7 @@ typedef struct gnc_lot_struct GNCLot;
|
||||
|
||||
/** @brief Price of commodity on a given date.
|
||||
* A GNCPrice encapsulates price information: the cost of a commodity
|
||||
* expressed as a currency, on a given date. It also holds info about
|
||||
* expressed as a currency, on a given date. It also holds info about
|
||||
* the provenance of the price: where it came from, its general validity.
|
||||
*/
|
||||
typedef struct gnc_price_s GNCPrice;
|
||||
@@ -241,7 +241,7 @@ gboolean gnc_engine_is_initialized(void);
|
||||
/** enable default log modules */
|
||||
void gnc_log_default(void);
|
||||
|
||||
/** Pass a function pointer to gnc_engine_add_init_hook and
|
||||
/** Pass a function pointer to gnc_engine_add_init_hook and
|
||||
* it will be called during the evaluation of gnc_engine_init */
|
||||
void gnc_engine_add_init_hook(gnc_engine_init_hook_t hook);
|
||||
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
#include <glib.h>
|
||||
#include <qof.h>
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
gpointer node;
|
||||
gint idx;
|
||||
} GncEventData;
|
||||
|
||||
@@ -42,27 +42,27 @@
|
||||
|
||||
struct gnc_lot_struct
|
||||
{
|
||||
QofInstance inst;
|
||||
QofInstance inst;
|
||||
|
||||
/* Account to which this lot applies. All splits in the lot must
|
||||
* belong to this account.
|
||||
*/
|
||||
Account * account;
|
||||
/* Account to which this lot applies. All splits in the lot must
|
||||
* belong to this account.
|
||||
*/
|
||||
Account * account;
|
||||
|
||||
/* List of splits that belong to this lot. */
|
||||
SplitList *splits;
|
||||
/* List of splits that belong to this lot. */
|
||||
SplitList *splits;
|
||||
|
||||
/* Handy cached value to indicate if lot is closed. */
|
||||
/* If value is negative, then the cache is invalid. */
|
||||
signed char is_closed;
|
||||
/* Handy cached value to indicate if lot is closed. */
|
||||
/* If value is negative, then the cache is invalid. */
|
||||
signed char is_closed;
|
||||
|
||||
/* traversal marker, handy for preventing recursion */
|
||||
unsigned char marker;
|
||||
/* traversal marker, handy for preventing recursion */
|
||||
unsigned char marker;
|
||||
};
|
||||
|
||||
struct _GncLotClass
|
||||
{
|
||||
QofInstanceClass parent_class;
|
||||
QofInstanceClass parent_class;
|
||||
};
|
||||
|
||||
#define gnc_lot_set_guid(L,G) qof_instance_set_guid(QOF_INSTANCE(L),&(G))
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
* is the same one as the item 'sold' in a different transaction.
|
||||
* Lots are used to make this association. One Lot holds all of the
|
||||
* splits that involve the same item. A lot is typically formed when
|
||||
* the item is bought, and is closed when the item is sold out.
|
||||
* A lot need not be a single item, it can be a quantity of the same
|
||||
* the item is bought, and is closed when the item is sold out.
|
||||
* A lot need not be a single item, it can be a quantity of the same
|
||||
* thing e.g. 500 gallons of paint (sold off a few gallons at a time).
|
||||
*
|
||||
* Lots are required to correctly implement invoices, inventory,
|
||||
@@ -36,9 +36,9 @@
|
||||
* A lot is "closed" when the number of items in the lot has gone to zero.
|
||||
* It is very easy to compute the gains/losses for a closed lot: it is the
|
||||
* sum-total of the values of the items put into/taken out of the lot.
|
||||
* (Realized) Gains on still-open lots can be computed by pro-rating the
|
||||
* purchase prices.
|
||||
*
|
||||
* (Realized) Gains on still-open lots can be computed by pro-rating the
|
||||
* purchase prices.
|
||||
*
|
||||
* Lots are nothing more than a collection or grouping of splits in an
|
||||
* account. All of the splits in a lot must belong to the same account;
|
||||
* there's no mix-n-match. Thus, in this sense, a lot belongs to an
|
||||
@@ -46,12 +46,12 @@
|
||||
*
|
||||
* Lots have an implicit "opening date": the date of the earliest split in
|
||||
* the lot. The "close date" is the date of the split that brought the lot
|
||||
* item balance down to zero.
|
||||
* item balance down to zero.
|
||||
*
|
||||
@{ */
|
||||
|
||||
/** @file gnc-lot.h
|
||||
*
|
||||
*
|
||||
* @author Created by Linas Vepstas May 2002
|
||||
* @author Copyright (c) 2002,2003 Linas Vepstas <linas@linas.org>
|
||||
*/
|
||||
@@ -79,11 +79,13 @@ typedef struct _GncLotClass GNCLotClass;
|
||||
GType gnc_lot_get_type(void);
|
||||
|
||||
|
||||
/*@ dependent @*/ GNCLot * gnc_lot_new (QofBook *);
|
||||
/*@ dependent @*/
|
||||
GNCLot * gnc_lot_new (QofBook *);
|
||||
void gnc_lot_destroy (GNCLot *);
|
||||
|
||||
/*@ dependent @*/ GNCLot * gnc_lot_lookup (const GUID *guid, QofBook *book);
|
||||
QofBook * gnc_lot_get_book (GNCLot *);
|
||||
/*@ dependent @*/
|
||||
GNCLot * gnc_lot_lookup (const GUID *guid, QofBook *book);
|
||||
QofBook * gnc_lot_get_book (GNCLot *);
|
||||
|
||||
void gnc_lot_begin_edit (GNCLot *lot);
|
||||
void gnc_lot_commit_edit (GNCLot *lot);
|
||||
@@ -92,7 +94,7 @@ void gnc_lot_commit_edit (GNCLot *lot);
|
||||
* that *all* splits in a lot must also be in the same account.
|
||||
* Note that this routine adds the split unconditionally, with
|
||||
* no regard for the accounting policy. To enforce a particular
|
||||
* accounting policy, use the xaccSplitAssignToLot() routine
|
||||
* accounting policy, use the xaccSplitAssignToLot() routine
|
||||
* instead.
|
||||
*/
|
||||
void gnc_lot_add_split (GNCLot *, Split *);
|
||||
@@ -108,12 +110,13 @@ void gnc_lot_remove_split (GNCLot *, Split *);
|
||||
SplitList * gnc_lot_get_split_list (const GNCLot *);
|
||||
gint gnc_lot_count_splits (const GNCLot *);
|
||||
|
||||
/** The gnc_lot_get_account() routine returns the account with which
|
||||
/** The gnc_lot_get_account() routine returns the account with which
|
||||
* this lot is associated. */
|
||||
/*@ dependent @*/ Account * gnc_lot_get_account (const GNCLot *);
|
||||
/*@ dependent @*/
|
||||
Account * gnc_lot_get_account (const GNCLot *);
|
||||
|
||||
/** The gnc_lot_get_balance() routine returns the balance of the lot.
|
||||
* The commodity in which this balance is expressed is the commodity
|
||||
/** The gnc_lot_get_balance() routine returns the balance of the lot.
|
||||
* The commodity in which this balance is expressed is the commodity
|
||||
* of the account. */
|
||||
gnc_numeric gnc_lot_get_balance (GNCLot *);
|
||||
|
||||
@@ -124,10 +127,10 @@ gnc_numeric gnc_lot_get_balance (GNCLot *);
|
||||
void gnc_lot_get_balance_before (const GNCLot *, const Split *,
|
||||
gnc_numeric *, gnc_numeric *);
|
||||
|
||||
/** The gnc_lot_is_closed() routine returns a boolean flag: is this
|
||||
* lot closed? A lot is closed if its balance is zero. This
|
||||
/** The gnc_lot_is_closed() routine returns a boolean flag: is this
|
||||
* lot closed? A lot is closed if its balance is zero. This
|
||||
* routine is faster than using gnc_lot_get_balance() because
|
||||
* once the balance goes to zero, this fact is cached.
|
||||
* once the balance goes to zero, this fact is cached.
|
||||
*/
|
||||
gboolean gnc_lot_is_closed (GNCLot *);
|
||||
|
||||
@@ -152,7 +155,7 @@ void gnc_lot_set_title (GNCLot *, const char *);
|
||||
void gnc_lot_set_notes (GNCLot *, const char *);
|
||||
|
||||
/** Every lot has a place to hang kvp data. This routine returns that
|
||||
* place.
|
||||
* place.
|
||||
* */
|
||||
KvpFrame * gnc_lot_get_slots (const GNCLot *);
|
||||
|
||||
|
||||
@@ -32,72 +32,73 @@
|
||||
|
||||
struct gnc_price_s
|
||||
{
|
||||
/* 'public' data fields */
|
||||
QofInstance inst; /* globally unique object identifier */
|
||||
/* 'public' data fields */
|
||||
QofInstance inst; /* globally unique object identifier */
|
||||
|
||||
GNCPriceDB *db;
|
||||
gnc_commodity *commodity;
|
||||
gnc_commodity *currency;
|
||||
Timespec tmspec;
|
||||
char *source;
|
||||
char *type;
|
||||
gnc_numeric value;
|
||||
GNCPriceDB *db;
|
||||
gnc_commodity *commodity;
|
||||
gnc_commodity *currency;
|
||||
Timespec tmspec;
|
||||
char *source;
|
||||
char *type;
|
||||
gnc_numeric value;
|
||||
|
||||
/* 'private' object management fields */
|
||||
guint32 refcount; /* garbage collection reference count */
|
||||
/* 'private' object management fields */
|
||||
guint32 refcount; /* garbage collection reference count */
|
||||
};
|
||||
|
||||
struct _GncPriceClass
|
||||
{
|
||||
QofInstanceClass parent_class;
|
||||
QofInstanceClass parent_class;
|
||||
};
|
||||
|
||||
struct gnc_price_db_s
|
||||
{
|
||||
QofInstance inst; /* globally unique object identifier */
|
||||
GHashTable *commodity_hash;
|
||||
gboolean bulk_update; /* TRUE while reading XML file, etc. */
|
||||
QofInstance inst; /* globally unique object identifier */
|
||||
GHashTable *commodity_hash;
|
||||
gboolean bulk_update; /* TRUE while reading XML file, etc. */
|
||||
};
|
||||
|
||||
struct _GncPriceDBClass
|
||||
{
|
||||
QofInstanceClass parent_class;
|
||||
QofInstanceClass parent_class;
|
||||
};
|
||||
|
||||
/* These structs define the kind of price lookup being done
|
||||
* so that it can be passed to the backend. This is a rather
|
||||
* cheesy, low-brow interface. It could stand improvement.
|
||||
*/
|
||||
typedef enum {
|
||||
LOOKUP_LATEST = 1,
|
||||
LOOKUP_ALL,
|
||||
LOOKUP_AT_TIME,
|
||||
LOOKUP_NEAREST_IN_TIME,
|
||||
LOOKUP_LATEST_BEFORE,
|
||||
LOOKUP_EARLIEST_AFTER
|
||||
typedef enum
|
||||
{
|
||||
LOOKUP_LATEST = 1,
|
||||
LOOKUP_ALL,
|
||||
LOOKUP_AT_TIME,
|
||||
LOOKUP_NEAREST_IN_TIME,
|
||||
LOOKUP_LATEST_BEFORE,
|
||||
LOOKUP_EARLIEST_AFTER
|
||||
} PriceLookupType;
|
||||
|
||||
|
||||
struct gnc_price_lookup_s
|
||||
{
|
||||
PriceLookupType type;
|
||||
GNCPriceDB *prdb;
|
||||
const gnc_commodity *commodity;
|
||||
const gnc_commodity *currency;
|
||||
Timespec date;
|
||||
PriceLookupType type;
|
||||
GNCPriceDB *prdb;
|
||||
const gnc_commodity *commodity;
|
||||
const gnc_commodity *currency;
|
||||
Timespec date;
|
||||
};
|
||||
|
||||
|
||||
typedef struct gnc_price_lookup_helper_s
|
||||
{
|
||||
GList **return_list;
|
||||
Timespec time;
|
||||
GList **return_list;
|
||||
Timespec time;
|
||||
} GNCPriceLookupHelper;
|
||||
|
||||
#define gnc_price_set_guid(P,G) qof_instance_set_guid(QOF_INSTANCE(P),(G))
|
||||
void gnc_pricedb_substitute_commodity(GNCPriceDB *db,
|
||||
gnc_commodity *old_c,
|
||||
gnc_commodity *new_c);
|
||||
gnc_commodity *old_c,
|
||||
gnc_commodity *new_c);
|
||||
|
||||
/** register the pricedb object with the gncObject system */
|
||||
gboolean gnc_pricedb_register (void);
|
||||
|
||||
@@ -100,7 +100,7 @@ GType gnc_pricedb_get_type(void);
|
||||
2001-02-03.
|
||||
|
||||
\par Fields:
|
||||
|
||||
|
||||
- commodity: the item being priced.
|
||||
- currency: the denomination of the value of the item being priced.
|
||||
- value: the value of the item being priced.
|
||||
@@ -162,7 +162,8 @@ typedef GList PriceList;
|
||||
|
||||
/** gnc_price_create - returns a newly allocated and initialized price
|
||||
with a reference count of 1. */
|
||||
/*@ dependent @*/ GNCPrice *gnc_price_create(QofBook *book);
|
||||
/*@ dependent @*/
|
||||
GNCPrice *gnc_price_create(QofBook *book);
|
||||
|
||||
/** gnc_price_clone - returns a newly allocated price that's a
|
||||
content-wise duplicate of the given price, p. The returned clone
|
||||
@@ -188,11 +189,11 @@ void gnc_price_unref(GNCPrice *p);
|
||||
* All of the setters store copies of the data
|
||||
* given, with the exception of the commodity field which just stores
|
||||
* the pointer given. It is assumed that commodities are a global
|
||||
* resource and are pointer unique.
|
||||
* resource and are pointer unique.
|
||||
*
|
||||
* Invocations of the setters should be wrapped with calls to
|
||||
* gnc_price_begin_edit() and commit_edit(). The begin/commit
|
||||
* calls help ensure that the local price db is synchronized with
|
||||
* calls help ensure that the local price db is synchronized with
|
||||
* the backend.
|
||||
@{ */
|
||||
void gnc_price_begin_edit (GNCPrice *p);
|
||||
@@ -213,8 +214,10 @@ void gnc_price_set_value(GNCPrice *p, gnc_numeric value);
|
||||
@{ */
|
||||
|
||||
GNCPrice * gnc_price_lookup (const GUID *guid, QofBook *book);
|
||||
/*@ dependent @*/ gnc_commodity * gnc_price_get_commodity(const GNCPrice *p);
|
||||
/*@ dependent @*/ gnc_commodity * gnc_price_get_currency(const GNCPrice *p);
|
||||
/*@ dependent @*/
|
||||
gnc_commodity * gnc_price_get_commodity(const GNCPrice *p);
|
||||
/*@ dependent @*/
|
||||
gnc_commodity * gnc_price_get_currency(const GNCPrice *p);
|
||||
Timespec gnc_price_get_time(const GNCPrice *p);
|
||||
const char * gnc_price_get_source(const GNCPrice *p);
|
||||
const char * gnc_price_get_typestr(const GNCPrice *p);
|
||||
@@ -308,7 +311,7 @@ gboolean gnc_pricedb_add_price(GNCPriceDB *db, GNCPrice *p);
|
||||
gboolean gnc_pricedb_remove_price(GNCPriceDB *db, GNCPrice *p);
|
||||
|
||||
gboolean gnc_pricedb_remove_old_prices(GNCPriceDB *db, Timespec cutoff,
|
||||
const gboolean delete_user, gboolean delete_last);
|
||||
const gboolean delete_user, gboolean delete_last);
|
||||
|
||||
/** gnc_pricedb_lookup_latest - find the most recent price for the
|
||||
given commodity in the given currency. Returns NULL on
|
||||
@@ -321,7 +324,7 @@ GNCPrice * gnc_pricedb_lookup_latest(GNCPriceDB *db,
|
||||
for the given commodity in any available currency. Prices will be
|
||||
returned as a GNCPrice list (see above). */
|
||||
PriceList * gnc_pricedb_lookup_latest_any_currency(GNCPriceDB *db,
|
||||
const gnc_commodity *commodity);
|
||||
const gnc_commodity *commodity);
|
||||
|
||||
/** gnc_pricedb_has_prices - return an indication of whether or not
|
||||
there are any prices for a given commodity in the given currency.
|
||||
@@ -334,92 +337,92 @@ gboolean gnc_pricedb_has_prices(GNCPriceDB *db,
|
||||
commodity in the given currency. Returns NULL on failure. The
|
||||
result is a GNCPrice list (see above). */
|
||||
PriceList * gnc_pricedb_get_prices(GNCPriceDB *db,
|
||||
const gnc_commodity *commodity,
|
||||
const gnc_commodity *currency);
|
||||
const gnc_commodity *commodity,
|
||||
const gnc_commodity *currency);
|
||||
|
||||
/** gnc_pricedb_lookup_at_time - return all prices that match the given
|
||||
commodity, currency, and timespec. Prices will be returned as a
|
||||
GNCPrice list (see above). */
|
||||
PriceList * gnc_pricedb_lookup_at_time(GNCPriceDB *db,
|
||||
const gnc_commodity *commodity,
|
||||
const gnc_commodity *currency,
|
||||
Timespec t);
|
||||
const gnc_commodity *commodity,
|
||||
const gnc_commodity *currency,
|
||||
Timespec t);
|
||||
|
||||
/** gnc_pricedb_lookup_at_time_any_currency - return all prices that match the
|
||||
given commodity and timespec in any available currency. Prices will be
|
||||
returned as a GNCPrice list (see above). */
|
||||
PriceList * gnc_pricedb_lookup_at_time_any_currency(GNCPriceDB *db,
|
||||
const gnc_commodity *c,
|
||||
Timespec t);
|
||||
const gnc_commodity *c,
|
||||
Timespec t);
|
||||
|
||||
/** gnc_pricedb_lookup_day - return all prices that match the given
|
||||
commodity, currency, and timespec. Prices will be returned as a
|
||||
GNCPrice list (see above). */
|
||||
PriceList * gnc_pricedb_lookup_day(GNCPriceDB *db,
|
||||
const gnc_commodity *commodity,
|
||||
const gnc_commodity *currency,
|
||||
Timespec t);
|
||||
const gnc_commodity *commodity,
|
||||
const gnc_commodity *currency,
|
||||
Timespec t);
|
||||
|
||||
/** gnc_pricedb_lookup_day_any_currency - return all prices that match the
|
||||
given commodity and timespec in any available currency. Prices will be
|
||||
returned as a GNCPrice list (see above). */
|
||||
PriceList * gnc_pricedb_lookup_day_any_currency(GNCPriceDB *db,
|
||||
const gnc_commodity *c,
|
||||
Timespec t);
|
||||
const gnc_commodity *c,
|
||||
Timespec t);
|
||||
|
||||
/** gnc_pricedb_lookup_nearest_in_time - return the price for the given
|
||||
commodity in the given currency nearest to the given time t. */
|
||||
GNCPrice * gnc_pricedb_lookup_nearest_in_time(GNCPriceDB *db,
|
||||
const gnc_commodity *c,
|
||||
const gnc_commodity *currency,
|
||||
Timespec t);
|
||||
const gnc_commodity *c,
|
||||
const gnc_commodity *currency,
|
||||
Timespec t);
|
||||
|
||||
/** gnc_pricedb_lookup_nearest_in_time_any_currency - return all prices that
|
||||
match the given commodity and timespec in any available currency. Prices
|
||||
will be returned as a GNCPrice list (see above). */
|
||||
PriceList * gnc_pricedb_lookup_nearest_in_time_any_currency(GNCPriceDB *db,
|
||||
const gnc_commodity *c,
|
||||
Timespec t);
|
||||
const gnc_commodity *c,
|
||||
Timespec t);
|
||||
/** gnc_pricedb_lookup_latest_before - return the latest price for the given commodity
|
||||
in the given currency up to and including time t. */
|
||||
GNCPrice * gnc_pricedb_lookup_latest_before(GNCPriceDB *db,
|
||||
gnc_commodity *c,
|
||||
gnc_commodity *currency,
|
||||
Timespec t);
|
||||
gnc_commodity *c,
|
||||
gnc_commodity *currency,
|
||||
Timespec t);
|
||||
|
||||
/** gnc_pricedb_lookup_latest_before_any_currency - return recent prices that
|
||||
match the given commodity up to and including time t in any available currency. Prices
|
||||
will be returned as a GNCPrice list (see above). */
|
||||
PriceList * gnc_pricedb_lookup_latest_before_any_currency(GNCPriceDB *db,
|
||||
gnc_commodity *c,
|
||||
Timespec t);
|
||||
gnc_commodity *c,
|
||||
Timespec t);
|
||||
|
||||
|
||||
/** gnc_pricedb_convert_balance_latest_price - Convert a balance
|
||||
from one currency to another. */
|
||||
gnc_numeric
|
||||
gnc_pricedb_convert_balance_latest_price(GNCPriceDB *pdb,
|
||||
gnc_numeric balance,
|
||||
const gnc_commodity *balance_currency,
|
||||
const gnc_commodity *new_currency);
|
||||
gnc_numeric balance,
|
||||
const gnc_commodity *balance_currency,
|
||||
const gnc_commodity *new_currency);
|
||||
|
||||
/** gnc_pricedb_convert_balance_nearest_price - Convert a balance
|
||||
from one currency to another. */
|
||||
gnc_numeric
|
||||
gnc_pricedb_convert_balance_nearest_price(GNCPriceDB *pdb,
|
||||
gnc_numeric balance,
|
||||
const gnc_commodity *balance_currency,
|
||||
const gnc_commodity *new_currency,
|
||||
Timespec t);
|
||||
gnc_numeric balance,
|
||||
const gnc_commodity *balance_currency,
|
||||
const gnc_commodity *new_currency,
|
||||
Timespec t);
|
||||
|
||||
/** gnc_pricedb_convert_balance_latest_before - Convert a balance from one currency
|
||||
to another using the lastest price prior to Timespec t. */
|
||||
gnc_numeric
|
||||
gnc_pricedb_convert_balance_latest_before(GNCPriceDB *pdb,
|
||||
gnc_numeric balance,
|
||||
gnc_commodity *balance_currency,
|
||||
gnc_commodity *new_currency,
|
||||
Timespec t);
|
||||
gnc_numeric balance,
|
||||
gnc_commodity *balance_currency,
|
||||
gnc_commodity *new_currency,
|
||||
Timespec t);
|
||||
|
||||
|
||||
/** gnc_pricedb_foreach_price - call f once for each price in db, until
|
||||
@@ -429,7 +432,7 @@ gnc_pricedb_convert_balance_latest_before(GNCPriceDB *pdb,
|
||||
less efficient). */
|
||||
gboolean gnc_pricedb_foreach_price(GNCPriceDB *db,
|
||||
gboolean (*f)(GNCPrice *p,
|
||||
gpointer user_data),
|
||||
gpointer user_data),
|
||||
gpointer user_data,
|
||||
gboolean stable_order);
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
* FUNCTION:
|
||||
* Encapsulates a connection to a GnuCash backend. That is, it
|
||||
* manages the connection to a persistant data store; whereas
|
||||
* the backend is the thing that performs the actual datastore
|
||||
* the backend is the thing that performs the actual datastore
|
||||
* access.
|
||||
*
|
||||
* HISTORY:
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
#include "qof.h"
|
||||
|
||||
|
||||
#define GncObject_t QofObject
|
||||
#define gncObjectLookup qof_object_lookup
|
||||
#define gncObjectRegister qof_object_register
|
||||
#define gncObjectGetTypeLabel qof_object_get_type_label
|
||||
#define gncObjectRegisterBackend qof_object_register_backend
|
||||
#define gncObjectLookupBackend qof_object_lookup_backend
|
||||
#define gncObjectForeachBackend qof_object_foreach_backend
|
||||
#define GncObject_t QofObject
|
||||
#define gncObjectLookup qof_object_lookup
|
||||
#define gncObjectRegister qof_object_register
|
||||
#define gncObjectGetTypeLabel qof_object_get_type_label
|
||||
#define gncObjectRegisterBackend qof_object_register_backend
|
||||
#define gncObjectLookupBackend qof_object_lookup_backend
|
||||
#define gncObjectForeachBackend qof_object_foreach_backend
|
||||
|
||||
#define gncObjectInitialize qof_object_initialize
|
||||
#define gncObjectShutdown qof_object_shutdown
|
||||
#define gncObjectBookBegin qof_object_book_begin
|
||||
#define gncObjectBookEnd qof_object_book_end
|
||||
#define gncObjectIsDirty qof_object_is_dirty
|
||||
#define gncObjectMarkClean qof_object_mark_clean
|
||||
#define gncObjectInitialize qof_object_initialize
|
||||
#define gncObjectShutdown qof_object_shutdown
|
||||
#define gncObjectBookBegin qof_object_book_begin
|
||||
#define gncObjectBookEnd qof_object_book_end
|
||||
#define gncObjectIsDirty qof_object_is_dirty
|
||||
#define gncObjectMarkClean qof_object_mark_clean
|
||||
|
||||
#define gncObjectForeachType qof_object_foreach_type
|
||||
#define gncObjectForeach qof_object_foreach
|
||||
#define gncObjectPrintable qof_object_printable
|
||||
#define gncObjectForeachType qof_object_foreach_type
|
||||
#define gncObjectForeach qof_object_foreach
|
||||
#define gncObjectPrintable qof_object_printable
|
||||
|
||||
@@ -26,13 +26,13 @@ int libgncmod_engine_gnc_module_age = 0;
|
||||
char *
|
||||
libgncmod_engine_gnc_module_path(void)
|
||||
{
|
||||
return g_strdup("gnucash/engine");
|
||||
return g_strdup("gnucash/engine");
|
||||
}
|
||||
|
||||
char *
|
||||
libgncmod_engine_gnc_module_description(void)
|
||||
{
|
||||
return g_strdup("The GnuCash accounting engine");
|
||||
return g_strdup("The GnuCash accounting engine");
|
||||
}
|
||||
|
||||
extern SCM scm_init_sw_engine_module(void);
|
||||
@@ -40,20 +40,21 @@ extern SCM scm_init_sw_engine_module(void);
|
||||
int
|
||||
libgncmod_engine_gnc_module_init(int refcount)
|
||||
{
|
||||
if(refcount == 0)
|
||||
{
|
||||
/* initialize the engine on the first load */
|
||||
gnc_engine_init(0, NULL);
|
||||
}
|
||||
if (refcount == 0)
|
||||
{
|
||||
/* initialize the engine on the first load */
|
||||
gnc_engine_init(0, NULL);
|
||||
}
|
||||
|
||||
scm_init_sw_engine_module();
|
||||
scm_c_eval_string("(use-modules (sw_engine))");
|
||||
scm_c_eval_string("(use-modules (gnucash engine))");
|
||||
scm_init_sw_engine_module();
|
||||
scm_c_eval_string("(use-modules (sw_engine))");
|
||||
scm_c_eval_string("(use-modules (gnucash engine))");
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
libgncmod_engine_gnc_module_end(int refcount) {
|
||||
return TRUE;
|
||||
libgncmod_engine_gnc_module_end(int refcount)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -24,14 +24,14 @@
|
||||
* @author Created by Linas Vepstas August 2003
|
||||
* @author Copyright (c) 2003 Linas Vepstas <linas@linas.org>
|
||||
*
|
||||
* This file implements Accounting Policy. The Accounting Policy
|
||||
* This file implements Accounting Policy. The Accounting Policy
|
||||
* determines how splits are assigned to lots. The default policy
|
||||
* is the FIFO policy: the first thing bought is also the first
|
||||
* thing sold.
|
||||
* is the FIFO policy: the first thing bought is also the first
|
||||
* thing sold.
|
||||
*/
|
||||
|
||||
#ifndef XACC_POLICY_P_H
|
||||
#define XACC_POLICY_P_H
|
||||
#ifndef XACC_POLICY_P_H
|
||||
#define XACC_POLICY_P_H
|
||||
|
||||
#include "gnc-engine.h"
|
||||
#include "policy.h"
|
||||
@@ -39,39 +39,39 @@
|
||||
/* ============================================================== */
|
||||
/** The Policy routines try to encapsulate the FIFO/LIFO-specific
|
||||
* parts of the cap-gains routine, and can be replaced by something
|
||||
* else for other policies.
|
||||
*
|
||||
* The PolicyGetLot() routine returns a lot into which the
|
||||
* else for other policies.
|
||||
*
|
||||
* The PolicyGetLot() routine returns a lot into which the
|
||||
* indicated split should be placed.
|
||||
*
|
||||
* The PolicyGetSplit() routine returns an unassinged split
|
||||
* from the account that is appropriate for placing into the
|
||||
* indicated lot. For the FIFO policy, that would be the
|
||||
* indicated lot. For the FIFO policy, that would be the
|
||||
* earliest split that is not in any account, and is of the
|
||||
* appropriate sign. For a LIFO, it would be the latest.
|
||||
*
|
||||
* The PolicyIsOpeningSplit() predicate returns a true/false
|
||||
* value, indicating if the indicated split was used to 'open'
|
||||
* or 'grow' the lot.
|
||||
* or 'grow' the lot.
|
||||
*
|
||||
* The PolicyGetLotOpening() routine returns information about
|
||||
* the opening balances for the lot. The 'opening balances'
|
||||
* the opening balances for the lot. The 'opening balances'
|
||||
* are the sum of all the splits used to grow (increase the size
|
||||
* of) the lot. For a LIFO or FIFO policy, there is only one
|
||||
* of) the lot. For a LIFO or FIFO policy, there is only one
|
||||
* split that opens a lot.
|
||||
*/
|
||||
|
||||
struct gncpolicy_s
|
||||
{
|
||||
GNCLot * (*PolicyGetLot) (GNCPolicy *, Split *split);
|
||||
Split * (*PolicyGetSplit) (GNCPolicy *, GNCLot *lot);
|
||||
void (*PolicyGetLotOpening) (GNCPolicy *, GNCLot *lot,
|
||||
gnc_numeric *ret_amount,
|
||||
gnc_numeric *ret_value,
|
||||
gnc_commodity **ret_currency);
|
||||
GNCLot * (*PolicyGetLot) (GNCPolicy *, Split *split);
|
||||
Split * (*PolicyGetSplit) (GNCPolicy *, GNCLot *lot);
|
||||
void (*PolicyGetLotOpening) (GNCPolicy *, GNCLot *lot,
|
||||
gnc_numeric *ret_amount,
|
||||
gnc_numeric *ret_value,
|
||||
gnc_commodity **ret_currency);
|
||||
|
||||
gboolean (*PolicyIsOpeningSplit) (GNCPolicy *, GNCLot *lot,
|
||||
Split *split);
|
||||
gboolean (*PolicyIsOpeningSplit) (GNCPolicy *, GNCLot *lot,
|
||||
Split *split);
|
||||
};
|
||||
|
||||
#endif /* XACC_POLICY_P_H */
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
/** @addtogroup Engine
|
||||
@{ */
|
||||
/** @addtogroup Policy Accounting Policy (FIFO/LIFO)
|
||||
* This file implements Accounting Policy. The Accounting Policy
|
||||
* This file implements Accounting Policy. The Accounting Policy
|
||||
* determines how Splits are assigned to Lots. The contents
|
||||
* of a Lot determines the Gains on that Lot. The default policy
|
||||
* is the FIFO policy: the first thing bought is also the first
|
||||
* thing sold.
|
||||
* is the FIFO policy: the first thing bought is also the first
|
||||
* thing sold.
|
||||
@{ */
|
||||
|
||||
/** @file policy.h
|
||||
@@ -34,12 +34,12 @@
|
||||
* @author Copyright (c) 2003,2004 Linas Vepstas <linas@linas.org>
|
||||
*/
|
||||
|
||||
#ifndef XACC_POLICY_H
|
||||
#define XACC_POLICY_H
|
||||
#ifndef XACC_POLICY_H
|
||||
#define XACC_POLICY_H
|
||||
|
||||
typedef struct gncpolicy_s GNCPolicy;
|
||||
|
||||
/** First-in, First-out Policy
|
||||
/** First-in, First-out Policy
|
||||
* This policy will create FIFO Lots. FIFO Lots have the following
|
||||
* properties:
|
||||
* -- The lot is started with the earliest posted split that isn't
|
||||
@@ -49,7 +49,7 @@ typedef struct gncpolicy_s GNCPolicy;
|
||||
* -- All splits in the lot share the same transaction currency as
|
||||
* the split that opened the lot.
|
||||
*/
|
||||
GNCPolicy *xaccGetFIFOPolicy (void);
|
||||
GNCPolicy *xaccGetFIFOPolicy (void);
|
||||
|
||||
/** Last-in, First-out Policy
|
||||
* This policy will create LIFO Lots. LIFO Lots have the following
|
||||
@@ -58,7 +58,7 @@ GNCPolicy *xaccGetFIFOPolicy (void);
|
||||
* -- All splits in the lot share the same transaction currency as
|
||||
* the split that opened the lot.
|
||||
*/
|
||||
GNCPolicy *xaccGetLIFOPolicy (void);
|
||||
GNCPolicy *xaccGetLIFOPolicy (void);
|
||||
|
||||
#endif /* XACC_POLICY_H */
|
||||
/** @} */
|
||||
|
||||
@@ -23,21 +23,25 @@ int libgncmod_test_engine_gnc_module_age = 0;
|
||||
|
||||
|
||||
char *
|
||||
libgncmod_test_engine_gnc_module_path(void) {
|
||||
return g_strdup("gnucash/engine/test");
|
||||
libgncmod_test_engine_gnc_module_path(void)
|
||||
{
|
||||
return g_strdup("gnucash/engine/test");
|
||||
}
|
||||
|
||||
char *
|
||||
libgncmod_test_engine_gnc_module_description(void) {
|
||||
return g_strdup("GnuCash Engine test infrastructure.");
|
||||
libgncmod_test_engine_gnc_module_description(void)
|
||||
{
|
||||
return g_strdup("GnuCash Engine test infrastructure.");
|
||||
}
|
||||
|
||||
int
|
||||
libgncmod_test_engine_gnc_module_init(int refcount) {
|
||||
return TRUE;
|
||||
libgncmod_test_engine_gnc_module_init(int refcount)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
libgncmod_test_engine_gnc_module_end(int refcount) {
|
||||
return TRUE;
|
||||
libgncmod_test_engine_gnc_module_end(int refcount)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1,152 +1,155 @@
|
||||
|
||||
static const gchar* sane_account_names[] = {
|
||||
"Bank CD",
|
||||
"Brokerage Account",
|
||||
"Bond",
|
||||
"Stock",
|
||||
"Market Index",
|
||||
"Mutual Fund",
|
||||
"Checking Account",
|
||||
"Money Market",
|
||||
"Retirement",
|
||||
"Bond",
|
||||
"Stock",
|
||||
"Market Index",
|
||||
"Mutual Fund",
|
||||
"Savings Account",
|
||||
"Spouse Retirement",
|
||||
"Bond",
|
||||
"Stock",
|
||||
"Market Index",
|
||||
"Mutual Fund",
|
||||
"Currency Trading",
|
||||
"Cash in Wallet",
|
||||
"House",
|
||||
"Other Asset",
|
||||
"Vehicle",
|
||||
"Credit Card",
|
||||
"Line of Credit",
|
||||
"Education Loan",
|
||||
"Mortgage Loan",
|
||||
"Other Loan",
|
||||
"Vehicle Loan",
|
||||
"Bonus",
|
||||
"Dividend Income",
|
||||
"Gifts Received",
|
||||
"Interest Income",
|
||||
"Bond Interest",
|
||||
"CD Interest",
|
||||
"Checking Interest",
|
||||
"Money Market Interest",
|
||||
"Other Interest",
|
||||
"Savings Interest",
|
||||
"Other Income",
|
||||
"Salary",
|
||||
"Salary (Spouse)",
|
||||
"Adjustment",
|
||||
"Auto",
|
||||
"Fees",
|
||||
"Gas",
|
||||
"Parking",
|
||||
"Repair and Maintenance",
|
||||
"Bank Service Charge",
|
||||
"Books",
|
||||
"Cable",
|
||||
"Charity",
|
||||
"Childcare",
|
||||
"Clothes",
|
||||
"Commissions",
|
||||
"Computer",
|
||||
"Dining",
|
||||
"Education",
|
||||
"Entertainment",
|
||||
"Music/Movies",
|
||||
"Recreation",
|
||||
"Travel",
|
||||
"Gifts",
|
||||
"Groceries",
|
||||
"Hobbies",
|
||||
"Home Repair",
|
||||
"Insurance",
|
||||
"Auto Insurance",
|
||||
"Health Insurance",
|
||||
"Home Insurance",
|
||||
"Life Insurance",
|
||||
"Rental Insurance",
|
||||
"Interest",
|
||||
"Education Loan Interest",
|
||||
"Mortgage Interest",
|
||||
"Other Interest",
|
||||
"Vehicle Loan Interest",
|
||||
"Laundry/Dry Cleaning",
|
||||
"Medical Expenses",
|
||||
"Miscellaneous",
|
||||
"Online Services",
|
||||
"Phone",
|
||||
"Public Transportation",
|
||||
"Rent",
|
||||
"Subscriptions",
|
||||
"Supplies",
|
||||
"Taxes",
|
||||
"Federal",
|
||||
"Medicare",
|
||||
"Other Tax",
|
||||
"Property Tax",
|
||||
"Social Security",
|
||||
"State/Province",
|
||||
"Taxes (Spouse)",
|
||||
"Federal",
|
||||
"Medicare",
|
||||
"Other Tax",
|
||||
"Social Security",
|
||||
"State/Province",
|
||||
"Utilities",
|
||||
"Electric",
|
||||
"Garbage collection",
|
||||
"Gas",
|
||||
"Water",
|
||||
"Opening Balances",
|
||||
NULL,
|
||||
static const gchar* sane_account_names[] =
|
||||
{
|
||||
"Bank CD",
|
||||
"Brokerage Account",
|
||||
"Bond",
|
||||
"Stock",
|
||||
"Market Index",
|
||||
"Mutual Fund",
|
||||
"Checking Account",
|
||||
"Money Market",
|
||||
"Retirement",
|
||||
"Bond",
|
||||
"Stock",
|
||||
"Market Index",
|
||||
"Mutual Fund",
|
||||
"Savings Account",
|
||||
"Spouse Retirement",
|
||||
"Bond",
|
||||
"Stock",
|
||||
"Market Index",
|
||||
"Mutual Fund",
|
||||
"Currency Trading",
|
||||
"Cash in Wallet",
|
||||
"House",
|
||||
"Other Asset",
|
||||
"Vehicle",
|
||||
"Credit Card",
|
||||
"Line of Credit",
|
||||
"Education Loan",
|
||||
"Mortgage Loan",
|
||||
"Other Loan",
|
||||
"Vehicle Loan",
|
||||
"Bonus",
|
||||
"Dividend Income",
|
||||
"Gifts Received",
|
||||
"Interest Income",
|
||||
"Bond Interest",
|
||||
"CD Interest",
|
||||
"Checking Interest",
|
||||
"Money Market Interest",
|
||||
"Other Interest",
|
||||
"Savings Interest",
|
||||
"Other Income",
|
||||
"Salary",
|
||||
"Salary (Spouse)",
|
||||
"Adjustment",
|
||||
"Auto",
|
||||
"Fees",
|
||||
"Gas",
|
||||
"Parking",
|
||||
"Repair and Maintenance",
|
||||
"Bank Service Charge",
|
||||
"Books",
|
||||
"Cable",
|
||||
"Charity",
|
||||
"Childcare",
|
||||
"Clothes",
|
||||
"Commissions",
|
||||
"Computer",
|
||||
"Dining",
|
||||
"Education",
|
||||
"Entertainment",
|
||||
"Music/Movies",
|
||||
"Recreation",
|
||||
"Travel",
|
||||
"Gifts",
|
||||
"Groceries",
|
||||
"Hobbies",
|
||||
"Home Repair",
|
||||
"Insurance",
|
||||
"Auto Insurance",
|
||||
"Health Insurance",
|
||||
"Home Insurance",
|
||||
"Life Insurance",
|
||||
"Rental Insurance",
|
||||
"Interest",
|
||||
"Education Loan Interest",
|
||||
"Mortgage Interest",
|
||||
"Other Interest",
|
||||
"Vehicle Loan Interest",
|
||||
"Laundry/Dry Cleaning",
|
||||
"Medical Expenses",
|
||||
"Miscellaneous",
|
||||
"Online Services",
|
||||
"Phone",
|
||||
"Public Transportation",
|
||||
"Rent",
|
||||
"Subscriptions",
|
||||
"Supplies",
|
||||
"Taxes",
|
||||
"Federal",
|
||||
"Medicare",
|
||||
"Other Tax",
|
||||
"Property Tax",
|
||||
"Social Security",
|
||||
"State/Province",
|
||||
"Taxes (Spouse)",
|
||||
"Federal",
|
||||
"Medicare",
|
||||
"Other Tax",
|
||||
"Social Security",
|
||||
"State/Province",
|
||||
"Utilities",
|
||||
"Electric",
|
||||
"Garbage collection",
|
||||
"Gas",
|
||||
"Water",
|
||||
"Opening Balances",
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const gchar* sane_descriptions[] = {
|
||||
"401k Income",
|
||||
"401k match 50%",
|
||||
"Cap. gain (long)",
|
||||
"Cap. gain (short)",
|
||||
"Car Repair",
|
||||
"Charity",
|
||||
"Child Care",
|
||||
"Credit Card Refund",
|
||||
"Dividends",
|
||||
"Fed Est Tax",
|
||||
"Fed Tax Witholding",
|
||||
"Insurance Rembersal",
|
||||
"Interect Earned",
|
||||
"Interest Earned",
|
||||
"Investment Interest",
|
||||
"IRA Contrib, non Deductable",
|
||||
"IRA Contrib, Non work Spouse",
|
||||
"IRA Contrib, Spouse",
|
||||
"IRA Contribution",
|
||||
"IRA Management Fee",
|
||||
"Job One",
|
||||
"Job Two",
|
||||
"Medical, Dental",
|
||||
"Medicare",
|
||||
"Medicine",
|
||||
"Mortgage Interest",
|
||||
"Opening Balance",
|
||||
"Pointe Paid",
|
||||
"Real Estate Tax",
|
||||
"Soc Sec",
|
||||
"State and Local",
|
||||
"test dup ",
|
||||
"Unemployment Comp",
|
||||
NULL,
|
||||
static const gchar* sane_descriptions[] =
|
||||
{
|
||||
"401k Income",
|
||||
"401k match 50%",
|
||||
"Cap. gain (long)",
|
||||
"Cap. gain (short)",
|
||||
"Car Repair",
|
||||
"Charity",
|
||||
"Child Care",
|
||||
"Credit Card Refund",
|
||||
"Dividends",
|
||||
"Fed Est Tax",
|
||||
"Fed Tax Witholding",
|
||||
"Insurance Rembersal",
|
||||
"Interect Earned",
|
||||
"Interest Earned",
|
||||
"Investment Interest",
|
||||
"IRA Contrib, non Deductable",
|
||||
"IRA Contrib, Non work Spouse",
|
||||
"IRA Contrib, Spouse",
|
||||
"IRA Contribution",
|
||||
"IRA Management Fee",
|
||||
"Job One",
|
||||
"Job Two",
|
||||
"Medical, Dental",
|
||||
"Medicare",
|
||||
"Medicine",
|
||||
"Mortgage Interest",
|
||||
"Opening Balance",
|
||||
"Pointe Paid",
|
||||
"Real Estate Tax",
|
||||
"Soc Sec",
|
||||
"State and Local",
|
||||
"test dup ",
|
||||
"Unemployment Comp",
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const gchar* sane_actions[] = {
|
||||
static const gchar* sane_actions[] =
|
||||
{
|
||||
"Dep",
|
||||
"Wthdrw",
|
||||
"Check",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -47,21 +47,21 @@ Account* get_random_account(QofBook * book);
|
||||
Split* get_random_split(QofBook *book, Account *account, Transaction *trn);
|
||||
Transaction* get_random_transaction(QofBook *book);
|
||||
Transaction* get_random_transaction_with_currency(QofBook *book,
|
||||
gnc_commodity *currency,
|
||||
GList *account_list);
|
||||
gnc_commodity *currency,
|
||||
GList *account_list);
|
||||
gnc_commodity* get_random_commodity(QofBook *book);
|
||||
const char *get_random_commodity_namespace(void);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RANDOM_QT = 0,
|
||||
SIMPLE_QT = 1 << 0,
|
||||
ACCOUNT_QT = 1 << 1,
|
||||
SPLIT_KVP_QT = 1 << 2,
|
||||
TRANS_KVP_QT = 1 << 3,
|
||||
ACCOUNT_KVP_QT = 1 << 4,
|
||||
GUID_QT = 1 << 5,
|
||||
ALL_QT = (1 << 8) - 1
|
||||
RANDOM_QT = 0,
|
||||
SIMPLE_QT = 1 << 0,
|
||||
ACCOUNT_QT = 1 << 1,
|
||||
SPLIT_KVP_QT = 1 << 2,
|
||||
TRANS_KVP_QT = 1 << 3,
|
||||
ACCOUNT_KVP_QT = 1 << 4,
|
||||
GUID_QT = 1 << 5,
|
||||
ALL_QT = (1 << 8) - 1
|
||||
} TestQueryTypes;
|
||||
|
||||
Query * get_random_query(void);
|
||||
@@ -80,10 +80,10 @@ void make_random_changes_to_price (QofBook *book, GNCPrice *price);
|
||||
void make_random_changes_to_pricedb (QofBook *book, GNCPriceDB *pdb);
|
||||
void make_random_changes_to_split (Split *split);
|
||||
void make_random_changes_to_transaction (QofBook *book,
|
||||
Transaction *trans);
|
||||
Transaction *trans);
|
||||
void make_random_changes_to_transaction_and_splits (QofBook *book,
|
||||
Transaction *trans,
|
||||
GList *accounts);
|
||||
Transaction *trans,
|
||||
GList *accounts);
|
||||
void make_random_changes_to_account (QofBook *book, Account *account);
|
||||
void make_random_changes_to_level (QofBook *book, Account *parent);
|
||||
void make_random_changes_to_book (QofBook *book);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
/**
|
||||
/**
|
||||
* @file test-account-object.c
|
||||
* @brief Minimal test of reading/writing account parameters
|
||||
* @author David Hampton <hampton@employees.org>
|
||||
@@ -37,43 +37,43 @@
|
||||
static void
|
||||
run_test (void)
|
||||
{
|
||||
QofSession *sess;
|
||||
QofBook *book;
|
||||
Account *acc;
|
||||
gnc_numeric *start, *end, end2, delta, zero, five;
|
||||
QofSession *sess;
|
||||
QofBook *book;
|
||||
Account *acc;
|
||||
gnc_numeric *start, *end, end2, delta, zero, five;
|
||||
|
||||
sess = get_random_session ();
|
||||
book = qof_session_get_book (sess);
|
||||
do_test ((NULL != book), "create random data");
|
||||
acc = get_random_account(book);
|
||||
sess = get_random_session ();
|
||||
book = qof_session_get_book (sess);
|
||||
do_test ((NULL != book), "create random data");
|
||||
acc = get_random_account(book);
|
||||
|
||||
/*****/
|
||||
/*****/
|
||||
|
||||
g_object_get(acc, "start-balance", &start, "end-balance", &end, NULL);
|
||||
end2 = xaccAccountGetBalance(acc);
|
||||
delta = gnc_numeric_sub(*end, *start, GNC_DENOM_AUTO, GNC_HOW_DENOM_FIXED);
|
||||
g_object_get(acc, "start-balance", &start, "end-balance", &end, NULL);
|
||||
end2 = xaccAccountGetBalance(acc);
|
||||
delta = gnc_numeric_sub(*end, *start, GNC_DENOM_AUTO, GNC_HOW_DENOM_FIXED);
|
||||
|
||||
do_test (gnc_numeric_zero_p(*start), "start balance is zero");
|
||||
do_test (gnc_numeric_zero_p(*end), "end balance is zero");
|
||||
do_test (gnc_numeric_zero_p(delta), "delta is zero");
|
||||
do_test (gnc_numeric_zero_p(end2), "end2 balance is zero");
|
||||
do_test (gnc_numeric_zero_p(*start), "start balance is zero");
|
||||
do_test (gnc_numeric_zero_p(*end), "end balance is zero");
|
||||
do_test (gnc_numeric_zero_p(delta), "delta is zero");
|
||||
do_test (gnc_numeric_zero_p(end2), "end2 balance is zero");
|
||||
|
||||
/*****/
|
||||
/*****/
|
||||
|
||||
five = gnc_numeric_create(5, 1);
|
||||
g_object_set(acc, "start-balance", &five, NULL);
|
||||
xaccAccountRecomputeBalance(acc);
|
||||
g_object_get(acc, "start-balance", &start, "end-balance", &end, NULL);
|
||||
end2 = xaccAccountGetBalance(acc);
|
||||
five = gnc_numeric_create(5, 1);
|
||||
g_object_set(acc, "start-balance", &five, NULL);
|
||||
xaccAccountRecomputeBalance(acc);
|
||||
g_object_get(acc, "start-balance", &start, "end-balance", &end, NULL);
|
||||
end2 = xaccAccountGetBalance(acc);
|
||||
|
||||
delta = gnc_numeric_sub(*end, five, GNC_DENOM_AUTO, GNC_HOW_DENOM_FIXED);
|
||||
do_test (gnc_numeric_zero_p(delta), "end balance matches");
|
||||
delta = gnc_numeric_sub(end2, five, GNC_DENOM_AUTO, GNC_HOW_DENOM_FIXED);
|
||||
do_test (gnc_numeric_zero_p(delta), "end2 balance matches");
|
||||
delta = gnc_numeric_sub(*end, five, GNC_DENOM_AUTO, GNC_HOW_DENOM_FIXED);
|
||||
do_test (gnc_numeric_zero_p(delta), "end balance matches");
|
||||
delta = gnc_numeric_sub(end2, five, GNC_DENOM_AUTO, GNC_HOW_DENOM_FIXED);
|
||||
do_test (gnc_numeric_zero_p(delta), "end2 balance matches");
|
||||
|
||||
/*****/
|
||||
/*****/
|
||||
|
||||
qof_session_end (sess);
|
||||
qof_session_end (sess);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
* Boston, MA 02110-1301, USA gnu@gnu.org *
|
||||
* *
|
||||
********************************************************************/
|
||||
/* Test the qof_book_merge infrastructure. */
|
||||
/* Test the qof_book_merge infrastructure. */
|
||||
|
||||
#include "config.h"
|
||||
#include "config.h"
|
||||
#include <glib.h>
|
||||
|
||||
#include "qof.h"
|
||||
@@ -47,20 +47,20 @@ gboolean myobjRegister (void);
|
||||
/* simple object structure */
|
||||
typedef struct obj_s
|
||||
{
|
||||
QofInstance inst;
|
||||
char *Name;
|
||||
gnc_numeric Amount;
|
||||
const GUID *obj_guid;
|
||||
Timespec date;
|
||||
double discount; /* cheap pun, I know. */
|
||||
gboolean active;
|
||||
gint32 version;
|
||||
gint64 minor;
|
||||
}myobj;
|
||||
QofInstance inst;
|
||||
char *Name;
|
||||
gnc_numeric Amount;
|
||||
const GUID *obj_guid;
|
||||
Timespec date;
|
||||
double discount; /* cheap pun, I know. */
|
||||
gboolean active;
|
||||
gint32 version;
|
||||
gint64 minor;
|
||||
} myobj;
|
||||
|
||||
typedef struct objclass_s
|
||||
{
|
||||
QofInstanceClass parent_class;
|
||||
QofInstanceClass parent_class;
|
||||
} myobjClass;
|
||||
|
||||
myobj* obj_create(QofBook*);
|
||||
@@ -120,394 +120,415 @@ gnc_myobj_finalize_real(GObject* objp)
|
||||
myobj*
|
||||
obj_create(QofBook *book)
|
||||
{
|
||||
myobj *g;
|
||||
g_return_val_if_fail(book, NULL);
|
||||
g = g_object_new(GNC_TYPE_MYOBJ, NULL);
|
||||
qof_instance_init_data (&g->inst, TEST_MODULE_NAME, book);
|
||||
obj_setGUID(g,qof_instance_get_guid(&g->inst));
|
||||
g->date.tv_nsec = 0;
|
||||
g->date.tv_sec = 0;
|
||||
g->discount = 0;
|
||||
g->active = TRUE;
|
||||
g->version = 1;
|
||||
g->minor = 1;
|
||||
qof_event_gen(&g->inst, QOF_EVENT_CREATE, NULL);
|
||||
return g;
|
||||
myobj *g;
|
||||
g_return_val_if_fail(book, NULL);
|
||||
g = g_object_new(GNC_TYPE_MYOBJ, NULL);
|
||||
qof_instance_init_data (&g->inst, TEST_MODULE_NAME, book);
|
||||
obj_setGUID(g, qof_instance_get_guid(&g->inst));
|
||||
g->date.tv_nsec = 0;
|
||||
g->date.tv_sec = 0;
|
||||
g->discount = 0;
|
||||
g->active = TRUE;
|
||||
g->version = 1;
|
||||
g->minor = 1;
|
||||
qof_event_gen(&g->inst, QOF_EVENT_CREATE, NULL);
|
||||
return g;
|
||||
}
|
||||
|
||||
void
|
||||
obj_setMinor(myobj *g, gint64 h)
|
||||
{
|
||||
g_return_if_fail(g != NULL);
|
||||
g->minor = h;
|
||||
g_return_if_fail(g != NULL);
|
||||
g->minor = h;
|
||||
}
|
||||
|
||||
gint64
|
||||
obj_getMinor(myobj *g)
|
||||
{
|
||||
g_return_val_if_fail((g != NULL),0);
|
||||
return g->minor;
|
||||
g_return_val_if_fail((g != NULL), 0);
|
||||
return g->minor;
|
||||
}
|
||||
|
||||
void
|
||||
obj_setVersion(myobj *g, gint32 h)
|
||||
{
|
||||
g_return_if_fail(g != NULL);
|
||||
g->version = h;
|
||||
g_return_if_fail(g != NULL);
|
||||
g->version = h;
|
||||
}
|
||||
|
||||
gint32
|
||||
obj_getVersion(myobj *g)
|
||||
{
|
||||
if(!g) return 0;
|
||||
return g->version;
|
||||
if (!g) return 0;
|
||||
return g->version;
|
||||
}
|
||||
|
||||
void
|
||||
obj_setActive(myobj *g, gboolean h)
|
||||
{
|
||||
if(!g) return;
|
||||
g->active = h;
|
||||
if (!g) return;
|
||||
g->active = h;
|
||||
}
|
||||
|
||||
gboolean
|
||||
obj_getActive(myobj *g)
|
||||
{
|
||||
if(!g) return FALSE;
|
||||
return g->active;
|
||||
if (!g) return FALSE;
|
||||
return g->active;
|
||||
}
|
||||
|
||||
void
|
||||
obj_setDiscount(myobj *g, double h)
|
||||
{
|
||||
if(!g) return;
|
||||
g->discount = h;
|
||||
if (!g) return;
|
||||
g->discount = h;
|
||||
}
|
||||
|
||||
double
|
||||
obj_getDiscount(myobj *g)
|
||||
{
|
||||
if(!g) return 0;
|
||||
return g->discount;
|
||||
if (!g) return 0;
|
||||
return g->discount;
|
||||
}
|
||||
|
||||
void
|
||||
obj_setDate(myobj *g, Timespec h)
|
||||
{
|
||||
if(!g) return;
|
||||
g->date = h;
|
||||
if (!g) return;
|
||||
g->date = h;
|
||||
}
|
||||
|
||||
Timespec
|
||||
obj_getDate(myobj *g)
|
||||
{
|
||||
Timespec ts = {0};
|
||||
if(!g) return ts;
|
||||
ts = g->date;
|
||||
return ts;
|
||||
Timespec ts = {0};
|
||||
if (!g) return ts;
|
||||
ts = g->date;
|
||||
return ts;
|
||||
}
|
||||
|
||||
void
|
||||
obj_setGUID(myobj* g, const GUID* h)
|
||||
{
|
||||
if(!g) return;
|
||||
g->obj_guid = h;
|
||||
if (!g) return;
|
||||
g->obj_guid = h;
|
||||
}
|
||||
|
||||
const GUID*
|
||||
const GUID*
|
||||
obj_getGUID(myobj *g)
|
||||
{
|
||||
if(!g) return NULL;
|
||||
return g->obj_guid;
|
||||
if (!g) return NULL;
|
||||
return g->obj_guid;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
obj_setName(myobj* g, char* h)
|
||||
{
|
||||
if(!g || !h) return;
|
||||
g->Name = strdup(h);
|
||||
if (!g || !h) return;
|
||||
g->Name = strdup(h);
|
||||
}
|
||||
|
||||
char*
|
||||
obj_getName(myobj *g)
|
||||
{
|
||||
if(!g) return NULL;
|
||||
return g->Name;
|
||||
if (!g) return NULL;
|
||||
return g->Name;
|
||||
}
|
||||
|
||||
void
|
||||
obj_setAmount(myobj *g, gnc_numeric h)
|
||||
{
|
||||
if(!g) return;
|
||||
g->Amount = h;
|
||||
if (!g) return;
|
||||
g->Amount = h;
|
||||
}
|
||||
|
||||
gnc_numeric
|
||||
obj_getAmount(myobj *g)
|
||||
{
|
||||
if(!g) return gnc_numeric_zero();
|
||||
return g->Amount;
|
||||
if (!g) return gnc_numeric_zero();
|
||||
return g->Amount;
|
||||
}
|
||||
|
||||
static QofObject obj_object_def = {
|
||||
interface_version: QOF_OBJECT_VERSION,
|
||||
e_type: TEST_MODULE_NAME,
|
||||
type_label: TEST_MODULE_DESC,
|
||||
create: (gpointer)obj_create,
|
||||
book_begin: NULL,
|
||||
book_end: NULL,
|
||||
is_dirty: NULL,
|
||||
mark_clean: NULL,
|
||||
foreach: qof_collection_foreach,
|
||||
printable: NULL,
|
||||
version_cmp: (int (*)(gpointer,gpointer)) qof_instance_version_cmp,
|
||||
static QofObject obj_object_def =
|
||||
{
|
||||
interface_version:
|
||||
QOF_OBJECT_VERSION,
|
||||
e_type:
|
||||
TEST_MODULE_NAME,
|
||||
type_label:
|
||||
TEST_MODULE_DESC,
|
||||
create:
|
||||
(gpointer)obj_create,
|
||||
book_begin:
|
||||
NULL,
|
||||
book_end:
|
||||
NULL,
|
||||
is_dirty:
|
||||
NULL,
|
||||
mark_clean:
|
||||
NULL,
|
||||
foreach:
|
||||
qof_collection_foreach,
|
||||
printable:
|
||||
NULL,
|
||||
version_cmp:
|
||||
(int (*)(gpointer, gpointer)) qof_instance_version_cmp,
|
||||
};
|
||||
|
||||
gboolean myobjRegister (void)
|
||||
{
|
||||
static QofParam params[] = {
|
||||
{ OBJ_NAME, QOF_TYPE_STRING, (QofAccessFunc)obj_getName, (QofSetterFunc)obj_setName },
|
||||
{ OBJ_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc)obj_getAmount, (QofSetterFunc)obj_setAmount },
|
||||
{ OBJ_GUID, QOF_TYPE_GUID, (QofAccessFunc)obj_getGUID, (QofSetterFunc)obj_setGUID },
|
||||
{ OBJ_DATE, QOF_TYPE_DATE, (QofAccessFunc)obj_getDate, (QofSetterFunc)obj_setDate },
|
||||
{ OBJ_DISCOUNT, QOF_TYPE_DOUBLE, (QofAccessFunc)obj_getDiscount, (QofSetterFunc)obj_setDiscount },
|
||||
{ OBJ_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)obj_getActive, (QofSetterFunc)obj_setActive },
|
||||
{ OBJ_VERSION, QOF_TYPE_INT32, (QofAccessFunc)obj_getVersion, (QofSetterFunc)obj_setVersion },
|
||||
{ OBJ_MINOR, QOF_TYPE_INT64, (QofAccessFunc)obj_getMinor, (QofSetterFunc)obj_setMinor },
|
||||
{ QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
|
||||
{ QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
|
||||
{ NULL },
|
||||
};
|
||||
static QofParam params[] =
|
||||
{
|
||||
{ OBJ_NAME, QOF_TYPE_STRING, (QofAccessFunc)obj_getName, (QofSetterFunc)obj_setName },
|
||||
{ OBJ_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc)obj_getAmount, (QofSetterFunc)obj_setAmount },
|
||||
{ OBJ_GUID, QOF_TYPE_GUID, (QofAccessFunc)obj_getGUID, (QofSetterFunc)obj_setGUID },
|
||||
{ OBJ_DATE, QOF_TYPE_DATE, (QofAccessFunc)obj_getDate, (QofSetterFunc)obj_setDate },
|
||||
{ OBJ_DISCOUNT, QOF_TYPE_DOUBLE, (QofAccessFunc)obj_getDiscount, (QofSetterFunc)obj_setDiscount },
|
||||
{ OBJ_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)obj_getActive, (QofSetterFunc)obj_setActive },
|
||||
{ OBJ_VERSION, QOF_TYPE_INT32, (QofAccessFunc)obj_getVersion, (QofSetterFunc)obj_setVersion },
|
||||
{ OBJ_MINOR, QOF_TYPE_INT64, (QofAccessFunc)obj_getMinor, (QofSetterFunc)obj_setMinor },
|
||||
{ QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
|
||||
{ QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
qof_class_register (TEST_MODULE_NAME, NULL, params);
|
||||
qof_class_register (TEST_MODULE_NAME, NULL, params);
|
||||
|
||||
return qof_object_register (&obj_object_def);
|
||||
return qof_object_register (&obj_object_def);
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
test_merge (void)
|
||||
{
|
||||
QofBook *target, *import;
|
||||
double init_value, discount;
|
||||
myobj *import_obj, *target_obj, *new_obj;
|
||||
int result;
|
||||
Timespec ts, tc;
|
||||
gboolean active;
|
||||
gint32 version;
|
||||
gint64 minor;
|
||||
gchar *import_init, *target_init;
|
||||
gnc_numeric obj_amount;
|
||||
QofBookMergeData *mergeData;
|
||||
|
||||
target = qof_book_new();
|
||||
import = qof_book_new();
|
||||
init_value = 1.00;
|
||||
result = 0;
|
||||
discount = 0.5;
|
||||
active = TRUE;
|
||||
version = 1;
|
||||
minor = 1;
|
||||
import_init = "test";
|
||||
target_init = "testing";
|
||||
qof_date_format_set(QOF_DATE_FORMAT_UK);
|
||||
timespecFromTime_t(&ts,time(NULL));
|
||||
QofBook *target, *import;
|
||||
double init_value, discount;
|
||||
myobj *import_obj, *target_obj, *new_obj;
|
||||
int result;
|
||||
Timespec ts, tc;
|
||||
gboolean active;
|
||||
gint32 version;
|
||||
gint64 minor;
|
||||
gchar *import_init, *target_init;
|
||||
gnc_numeric obj_amount;
|
||||
QofBookMergeData *mergeData;
|
||||
|
||||
do_test ((NULL != target), "#1 target book is NULL");
|
||||
target = qof_book_new();
|
||||
import = qof_book_new();
|
||||
init_value = 1.00;
|
||||
result = 0;
|
||||
discount = 0.5;
|
||||
active = TRUE;
|
||||
version = 1;
|
||||
minor = 1;
|
||||
import_init = "test";
|
||||
target_init = "testing";
|
||||
qof_date_format_set(QOF_DATE_FORMAT_UK);
|
||||
timespecFromTime_t(&ts, time(NULL));
|
||||
|
||||
/* import book objects - tests used */
|
||||
do_test ((NULL != import), "#2 import book is NULL");
|
||||
import_obj = g_object_new(GNC_TYPE_MYOBJ, NULL);
|
||||
do_test ((NULL != import_obj), "#3 new object create");
|
||||
qof_instance_init_data (&import_obj->inst, TEST_MODULE_NAME, import);
|
||||
do_test ((NULL != &import_obj->inst), "#4 instance init");
|
||||
obj_setGUID(import_obj,qof_instance_get_guid(&import_obj->inst));
|
||||
do_test ((NULL != &import_obj->obj_guid), "#5 guid set");
|
||||
qof_event_gen(&import_obj->inst, QOF_EVENT_CREATE, NULL);
|
||||
do_test ((NULL != &import_obj->inst), "#6 gnc event create");
|
||||
obj_setName(import_obj, import_init);
|
||||
do_test ((NULL != &import_obj->Name), "#7 string set");
|
||||
obj_amount = double_to_gnc_numeric(init_value,1, GNC_HOW_DENOM_EXACT);
|
||||
obj_setAmount(import_obj, obj_amount);
|
||||
do_test ((gnc_numeric_check(obj_getAmount(import_obj)) == GNC_ERROR_OK), "#8 gnc_numeric set");
|
||||
obj_setActive(import_obj, active);
|
||||
do_test ((FALSE != &import_obj->active), "#9 gboolean set");
|
||||
obj_setDiscount(import_obj, discount);
|
||||
do_test ((discount == import_obj->discount), "#10 double set");
|
||||
obj_setVersion(import_obj, version);
|
||||
do_test ((version == import_obj->version), "#11 gint32 set");
|
||||
obj_setMinor(import_obj, minor);
|
||||
do_test ((minor == import_obj->minor), "#12 gint64 set");
|
||||
obj_setDate(import_obj, ts );
|
||||
tc = import_obj->date;
|
||||
do_test ((timespec_cmp(&ts, &tc) == 0), "#13 date set");
|
||||
do_test ((NULL != target), "#1 target book is NULL");
|
||||
|
||||
obj_amount = gnc_numeric_add(obj_amount, obj_amount, 1, GNC_HOW_DENOM_EXACT);
|
||||
discount = 0.25;
|
||||
version = 2;
|
||||
minor = 3;
|
||||
/* import book objects - tests used */
|
||||
do_test ((NULL != import), "#2 import book is NULL");
|
||||
import_obj = g_object_new(GNC_TYPE_MYOBJ, NULL);
|
||||
do_test ((NULL != import_obj), "#3 new object create");
|
||||
qof_instance_init_data (&import_obj->inst, TEST_MODULE_NAME, import);
|
||||
do_test ((NULL != &import_obj->inst), "#4 instance init");
|
||||
obj_setGUID(import_obj, qof_instance_get_guid(&import_obj->inst));
|
||||
do_test ((NULL != &import_obj->obj_guid), "#5 guid set");
|
||||
qof_event_gen(&import_obj->inst, QOF_EVENT_CREATE, NULL);
|
||||
do_test ((NULL != &import_obj->inst), "#6 gnc event create");
|
||||
obj_setName(import_obj, import_init);
|
||||
do_test ((NULL != &import_obj->Name), "#7 string set");
|
||||
obj_amount = double_to_gnc_numeric(init_value, 1, GNC_HOW_DENOM_EXACT);
|
||||
obj_setAmount(import_obj, obj_amount);
|
||||
do_test ((gnc_numeric_check(obj_getAmount(import_obj)) == GNC_ERROR_OK), "#8 gnc_numeric set");
|
||||
obj_setActive(import_obj, active);
|
||||
do_test ((FALSE != &import_obj->active), "#9 gboolean set");
|
||||
obj_setDiscount(import_obj, discount);
|
||||
do_test ((discount == import_obj->discount), "#10 double set");
|
||||
obj_setVersion(import_obj, version);
|
||||
do_test ((version == import_obj->version), "#11 gint32 set");
|
||||
obj_setMinor(import_obj, minor);
|
||||
do_test ((minor == import_obj->minor), "#12 gint64 set");
|
||||
obj_setDate(import_obj, ts );
|
||||
tc = import_obj->date;
|
||||
do_test ((timespec_cmp(&ts, &tc) == 0), "#13 date set");
|
||||
|
||||
/* second import object - test results would be the same, so not tested. */
|
||||
new_obj = g_object_new(GNC_TYPE_MYOBJ, NULL);
|
||||
qof_instance_init_data (&new_obj->inst, TEST_MODULE_NAME, import);
|
||||
obj_setGUID(new_obj,qof_instance_get_guid(&new_obj->inst));
|
||||
qof_event_gen (&new_obj->inst, QOF_EVENT_CREATE, NULL);
|
||||
obj_setName(new_obj, import_init);
|
||||
obj_setAmount(new_obj, obj_amount);
|
||||
obj_setActive(new_obj, active);
|
||||
obj_setDiscount(new_obj, discount);
|
||||
obj_setVersion(new_obj, version);
|
||||
obj_setMinor(new_obj, minor);
|
||||
obj_setDate(new_obj, ts);
|
||||
obj_amount = gnc_numeric_add(obj_amount, obj_amount, 1, GNC_HOW_DENOM_EXACT);
|
||||
discount = 0.25;
|
||||
version = 2;
|
||||
minor = 3;
|
||||
|
||||
obj_amount = gnc_numeric_add(obj_amount, obj_amount, 1, GNC_HOW_DENOM_EXACT);
|
||||
discount = 0.35;
|
||||
version = 2;
|
||||
minor = 3;
|
||||
tc.tv_sec = ts.tv_sec -1;
|
||||
tc.tv_nsec = 0;
|
||||
/* second import object - test results would be the same, so not tested. */
|
||||
new_obj = g_object_new(GNC_TYPE_MYOBJ, NULL);
|
||||
qof_instance_init_data (&new_obj->inst, TEST_MODULE_NAME, import);
|
||||
obj_setGUID(new_obj, qof_instance_get_guid(&new_obj->inst));
|
||||
qof_event_gen (&new_obj->inst, QOF_EVENT_CREATE, NULL);
|
||||
obj_setName(new_obj, import_init);
|
||||
obj_setAmount(new_obj, obj_amount);
|
||||
obj_setActive(new_obj, active);
|
||||
obj_setDiscount(new_obj, discount);
|
||||
obj_setVersion(new_obj, version);
|
||||
obj_setMinor(new_obj, minor);
|
||||
obj_setDate(new_obj, ts);
|
||||
|
||||
/* target object - test results would be the same, so not tested. */
|
||||
target_obj = g_object_new(GNC_TYPE_MYOBJ, NULL);
|
||||
qof_instance_init_data (&target_obj->inst, TEST_MODULE_NAME, target);
|
||||
obj_setGUID(target_obj,qof_instance_get_guid(&target_obj->inst));
|
||||
qof_event_gen (&target_obj->inst, QOF_EVENT_CREATE, NULL);
|
||||
obj_setName(target_obj, target_init);
|
||||
obj_setAmount(target_obj, obj_amount);
|
||||
obj_setActive(target_obj, active);
|
||||
obj_setDiscount(target_obj, discount);
|
||||
obj_setVersion(target_obj, version);
|
||||
obj_setMinor(target_obj, minor);
|
||||
obj_setDate(target_obj, tc );
|
||||
|
||||
mergeData = qof_book_merge_init(import, target);
|
||||
do_test ( mergeData != NULL, "FATAL: Merge could not be initialised!\t aborting . . ");
|
||||
g_return_if_fail(mergeData != NULL);
|
||||
qof_book_merge_rule_foreach(mergeData, test_rule_loop, MERGE_REPORT);
|
||||
qof_book_merge_rule_foreach(mergeData, test_rule_loop, MERGE_UPDATE);
|
||||
qof_book_merge_rule_foreach(mergeData, test_rule_loop, MERGE_NEW);
|
||||
/* reserved calls - test only */
|
||||
qof_book_merge_rule_foreach(mergeData, test_rule_loop, MERGE_ABSOLUTE);
|
||||
qof_book_merge_rule_foreach(mergeData, test_rule_loop, MERGE_DUPLICATE);
|
||||
obj_amount = gnc_numeric_add(obj_amount, obj_amount, 1, GNC_HOW_DENOM_EXACT);
|
||||
discount = 0.35;
|
||||
version = 2;
|
||||
minor = 3;
|
||||
tc.tv_sec = ts.tv_sec - 1;
|
||||
tc.tv_nsec = 0;
|
||||
|
||||
/* import should not be in the target - pass if import_init fails match with target */
|
||||
do_test (((safe_strcmp(obj_getName(import_obj),obj_getName(target_obj))) != 0), "Init value test #1");
|
||||
|
||||
/* a good commit returns zero */
|
||||
do_test (qof_book_merge_commit(mergeData) == 0, "Commit failed");
|
||||
/* target object - test results would be the same, so not tested. */
|
||||
target_obj = g_object_new(GNC_TYPE_MYOBJ, NULL);
|
||||
qof_instance_init_data (&target_obj->inst, TEST_MODULE_NAME, target);
|
||||
obj_setGUID(target_obj, qof_instance_get_guid(&target_obj->inst));
|
||||
qof_event_gen (&target_obj->inst, QOF_EVENT_CREATE, NULL);
|
||||
obj_setName(target_obj, target_init);
|
||||
obj_setAmount(target_obj, obj_amount);
|
||||
obj_setActive(target_obj, active);
|
||||
obj_setDiscount(target_obj, discount);
|
||||
obj_setVersion(target_obj, version);
|
||||
obj_setMinor(target_obj, minor);
|
||||
obj_setDate(target_obj, tc );
|
||||
|
||||
/* import should be in the target - pass if import_init matches target */
|
||||
do_test (((safe_strcmp(import_init,obj_getName(target_obj))) == 0), "Merged value test #1");
|
||||
mergeData = qof_book_merge_init(import, target);
|
||||
do_test ( mergeData != NULL, "FATAL: Merge could not be initialised!\t aborting . . ");
|
||||
g_return_if_fail(mergeData != NULL);
|
||||
qof_book_merge_rule_foreach(mergeData, test_rule_loop, MERGE_REPORT);
|
||||
qof_book_merge_rule_foreach(mergeData, test_rule_loop, MERGE_UPDATE);
|
||||
qof_book_merge_rule_foreach(mergeData, test_rule_loop, MERGE_NEW);
|
||||
/* reserved calls - test only */
|
||||
qof_book_merge_rule_foreach(mergeData, test_rule_loop, MERGE_ABSOLUTE);
|
||||
qof_book_merge_rule_foreach(mergeData, test_rule_loop, MERGE_DUPLICATE);
|
||||
|
||||
/* import should be the same as target - pass if values are the same */
|
||||
do_test (((safe_strcmp(obj_getName(target_obj),obj_getName(import_obj))) == 0), "Merged value test #2");
|
||||
/* import should not be in the target - pass if import_init fails match with target */
|
||||
do_test (((safe_strcmp(obj_getName(import_obj), obj_getName(target_obj))) != 0), "Init value test #1");
|
||||
|
||||
/* check that the Amount really is a gnc_numeric */
|
||||
do_test ((gnc_numeric_check(obj_getAmount(import_obj)) == GNC_ERROR_OK), "import gnc_numeric check");
|
||||
do_test ((gnc_numeric_check(obj_getAmount(target_obj)) == GNC_ERROR_OK), "target gnc_numeric check");
|
||||
/* a good commit returns zero */
|
||||
do_test (qof_book_merge_commit(mergeData) == 0, "Commit failed");
|
||||
|
||||
/* obj_amount was changed after the import object was set, so expect a difference. */
|
||||
do_test ((gnc_numeric_compare(obj_getAmount(import_obj), obj_amount) != GNC_ERROR_OK),
|
||||
"gnc_numeric value check #1");
|
||||
/* import should be in the target - pass if import_init matches target */
|
||||
do_test (((safe_strcmp(import_init, obj_getName(target_obj))) == 0), "Merged value test #1");
|
||||
|
||||
/* obj_amount is in the target object with the import value, expect a difference/ */
|
||||
do_test ((gnc_numeric_compare(obj_getAmount(target_obj), obj_amount) != GNC_ERROR_OK),
|
||||
"gnc_numeric value check #2");
|
||||
|
||||
/* target had a different date, so import date should now be set */
|
||||
/* note: If sensible defaults are not set in the create:
|
||||
an empty Timespec caused problems with the update - fix */
|
||||
tc = target_obj->date;
|
||||
do_test ((timespec_cmp(&ts, &tc) == 0), "date value check: 1");
|
||||
tc = import_obj->date;
|
||||
do_test ((timespec_cmp(&tc, &ts) == 0), "date value check: 2");
|
||||
do_test ((timespec_cmp(&import_obj->date, &target_obj->date) == 0), "date value check: 3");
|
||||
/* import should be the same as target - pass if values are the same */
|
||||
do_test (((safe_strcmp(obj_getName(target_obj), obj_getName(import_obj))) == 0), "Merged value test #2");
|
||||
|
||||
/* check that the Amount really is a gnc_numeric */
|
||||
do_test ((gnc_numeric_check(obj_getAmount(import_obj)) == GNC_ERROR_OK), "import gnc_numeric check");
|
||||
do_test ((gnc_numeric_check(obj_getAmount(target_obj)) == GNC_ERROR_OK), "target gnc_numeric check");
|
||||
|
||||
/* obj_amount was changed after the import object was set, so expect a difference. */
|
||||
do_test ((gnc_numeric_compare(obj_getAmount(import_obj), obj_amount) != GNC_ERROR_OK),
|
||||
"gnc_numeric value check #1");
|
||||
|
||||
/* obj_amount is in the target object with the import value, expect a difference/ */
|
||||
do_test ((gnc_numeric_compare(obj_getAmount(target_obj), obj_amount) != GNC_ERROR_OK),
|
||||
"gnc_numeric value check #2");
|
||||
|
||||
/* target had a different date, so import date should now be set */
|
||||
/* note: If sensible defaults are not set in the create:
|
||||
an empty Timespec caused problems with the update - fix */
|
||||
tc = target_obj->date;
|
||||
do_test ((timespec_cmp(&ts, &tc) == 0), "date value check: 1");
|
||||
tc = import_obj->date;
|
||||
do_test ((timespec_cmp(&tc, &ts) == 0), "date value check: 2");
|
||||
do_test ((timespec_cmp(&import_obj->date, &target_obj->date) == 0), "date value check: 3");
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
test_rule_loop (QofBookMergeData *mergeData, QofBookMergeRule *rule, guint remainder)
|
||||
{
|
||||
GSList *testing;
|
||||
QofParam *eachParam;
|
||||
char *importstring;
|
||||
char *targetstring;
|
||||
/* In this test rule_loop, any lines beginning with do_test() can be removed
|
||||
from a working rule_loop routine. It would be wise to still use some of the
|
||||
more obvious checks, e.g. that an entity or rule exists before querying the parameters.
|
||||
|
||||
Take particular care with MERGE_NEW - targetEnt is always NULL until the Commit.
|
||||
Do not attempt to use param_getfcn on targetEnt in the loop called by
|
||||
QofBookMergeRuleForeach(rule_loop, MERGE_NEW);
|
||||
|
||||
*/
|
||||
gboolean skip_target;
|
||||
|
||||
importstring = NULL;
|
||||
targetstring = NULL;
|
||||
skip_target = FALSE;
|
||||
mergeData->currentRule = rule;
|
||||
do_test ((rule != NULL), "loop:#1 Rule is NULL");
|
||||
do_test (remainder > 0, "loop:#2 remainder error.");
|
||||
do_test ((safe_strcmp(NULL, rule->mergeLabel) != 0), "loop:#3 object label\n");
|
||||
do_test ((rule->importEnt != NULL), "loop:#4 empty import entity");
|
||||
/* targetEnt is always NULL at this stage if MERGE_NEW is set */
|
||||
if(rule->targetEnt == NULL) { skip_target = TRUE; }
|
||||
if(!skip_target) {
|
||||
do_test ((safe_strcmp(rule->importEnt->e_type, rule->targetEnt->e_type) == 0),
|
||||
"loop: entity type mismatch");
|
||||
}
|
||||
do_test ((rule->mergeParam != NULL), "loop: empty parameter list");
|
||||
testing = rule->mergeParam;
|
||||
|
||||
while(testing != NULL) { // start of param loop
|
||||
eachParam = testing->data;
|
||||
do_test ((eachParam != NULL), "loop:#8 no QofParam data");
|
||||
do_test ((eachParam->param_name != NULL), "loop:#9 no parameter name");
|
||||
do_test ((eachParam->param_getfcn != NULL), "loop:#10 no get function");
|
||||
do_test ((eachParam->param_setfcn != NULL), "loop:#11 no set function");
|
||||
/* non-generic - test routines only! */
|
||||
if(safe_strcmp(eachParam->param_type, QOF_TYPE_STRING) == 0) {
|
||||
/* if you use this format, you would need to check the QOF_TYPE and
|
||||
configure the get_fcn pointers yourself. This example only works for strings. */
|
||||
importstring = g_strdup(eachParam->param_getfcn(rule->importEnt, eachParam));
|
||||
do_test ((importstring != NULL), "loop:#12 direct get_fcn import");
|
||||
do_test ((safe_strcmp(importstring, "test") == 0), "loop:#13 direct import comparison");
|
||||
if(!skip_target) {
|
||||
targetstring = eachParam->param_getfcn(rule->targetEnt, eachParam);
|
||||
do_test ((targetstring != NULL), "loop:#14 direct get_fcn target");
|
||||
do_test ((safe_strcmp(targetstring, "testing") == 0), "loop:#15 direct target comparison");
|
||||
}
|
||||
}
|
||||
/* param_as_string does the conversion for display purposes only */
|
||||
/* do NOT use as_string for calculations or set_fcn */
|
||||
importstring = qof_book_merge_param_as_string(eachParam, rule->importEnt);
|
||||
do_test ((importstring != NULL), "loop:#16 import param_as_string is null");
|
||||
/* printf("importstring %s\t%s Type\n", importstring, eachParam->param_type);*/
|
||||
if(!skip_target) {
|
||||
targetstring = qof_book_merge_param_as_string(eachParam, rule->targetEnt);
|
||||
do_test ((targetstring != NULL), "loop:#17 target param_as_string is null");
|
||||
/* printf("targetstring %s\t%s Type\n", targetstring, eachParam->param_type);*/
|
||||
}
|
||||
/* add your own code for user involvement here. */
|
||||
/* either store the importstring and targetstring values and display separately,
|
||||
perhaps in alphabetical/object_type/priority order, or, obtain user input as each
|
||||
string is available. */
|
||||
|
||||
testing = g_slist_next(testing);
|
||||
} // end param loop
|
||||
/* set each rule dependent on the user involvement response above. */
|
||||
/* test routine just sets all MERGE_REPORT to MERGE_UPDATE */
|
||||
mergeData = qof_book_merge_update_result(mergeData, MERGE_UPDATE);
|
||||
do_test ((rule->mergeResult != MERGE_REPORT), "update result fail");
|
||||
GSList *testing;
|
||||
QofParam *eachParam;
|
||||
char *importstring;
|
||||
char *targetstring;
|
||||
/* In this test rule_loop, any lines beginning with do_test() can be removed
|
||||
from a working rule_loop routine. It would be wise to still use some of the
|
||||
more obvious checks, e.g. that an entity or rule exists before querying the parameters.
|
||||
|
||||
Take particular care with MERGE_NEW - targetEnt is always NULL until the Commit.
|
||||
Do not attempt to use param_getfcn on targetEnt in the loop called by
|
||||
QofBookMergeRuleForeach(rule_loop, MERGE_NEW);
|
||||
|
||||
*/
|
||||
gboolean skip_target;
|
||||
|
||||
importstring = NULL;
|
||||
targetstring = NULL;
|
||||
skip_target = FALSE;
|
||||
mergeData->currentRule = rule;
|
||||
do_test ((rule != NULL), "loop:#1 Rule is NULL");
|
||||
do_test (remainder > 0, "loop:#2 remainder error.");
|
||||
do_test ((safe_strcmp(NULL, rule->mergeLabel) != 0), "loop:#3 object label\n");
|
||||
do_test ((rule->importEnt != NULL), "loop:#4 empty import entity");
|
||||
/* targetEnt is always NULL at this stage if MERGE_NEW is set */
|
||||
if (rule->targetEnt == NULL)
|
||||
{
|
||||
skip_target = TRUE;
|
||||
}
|
||||
if (!skip_target)
|
||||
{
|
||||
do_test ((safe_strcmp(rule->importEnt->e_type, rule->targetEnt->e_type) == 0),
|
||||
"loop: entity type mismatch");
|
||||
}
|
||||
do_test ((rule->mergeParam != NULL), "loop: empty parameter list");
|
||||
testing = rule->mergeParam;
|
||||
|
||||
while (testing != NULL) // start of param loop
|
||||
{
|
||||
eachParam = testing->data;
|
||||
do_test ((eachParam != NULL), "loop:#8 no QofParam data");
|
||||
do_test ((eachParam->param_name != NULL), "loop:#9 no parameter name");
|
||||
do_test ((eachParam->param_getfcn != NULL), "loop:#10 no get function");
|
||||
do_test ((eachParam->param_setfcn != NULL), "loop:#11 no set function");
|
||||
/* non-generic - test routines only! */
|
||||
if (safe_strcmp(eachParam->param_type, QOF_TYPE_STRING) == 0)
|
||||
{
|
||||
/* if you use this format, you would need to check the QOF_TYPE and
|
||||
configure the get_fcn pointers yourself. This example only works for strings. */
|
||||
importstring = g_strdup(eachParam->param_getfcn(rule->importEnt, eachParam));
|
||||
do_test ((importstring != NULL), "loop:#12 direct get_fcn import");
|
||||
do_test ((safe_strcmp(importstring, "test") == 0), "loop:#13 direct import comparison");
|
||||
if (!skip_target)
|
||||
{
|
||||
targetstring = eachParam->param_getfcn(rule->targetEnt, eachParam);
|
||||
do_test ((targetstring != NULL), "loop:#14 direct get_fcn target");
|
||||
do_test ((safe_strcmp(targetstring, "testing") == 0), "loop:#15 direct target comparison");
|
||||
}
|
||||
}
|
||||
/* param_as_string does the conversion for display purposes only */
|
||||
/* do NOT use as_string for calculations or set_fcn */
|
||||
importstring = qof_book_merge_param_as_string(eachParam, rule->importEnt);
|
||||
do_test ((importstring != NULL), "loop:#16 import param_as_string is null");
|
||||
/* printf("importstring %s\t%s Type\n", importstring, eachParam->param_type);*/
|
||||
if (!skip_target)
|
||||
{
|
||||
targetstring = qof_book_merge_param_as_string(eachParam, rule->targetEnt);
|
||||
do_test ((targetstring != NULL), "loop:#17 target param_as_string is null");
|
||||
/* printf("targetstring %s\t%s Type\n", targetstring, eachParam->param_type);*/
|
||||
}
|
||||
/* add your own code for user involvement here. */
|
||||
/* either store the importstring and targetstring values and display separately,
|
||||
perhaps in alphabetical/object_type/priority order, or, obtain user input as each
|
||||
string is available. */
|
||||
|
||||
testing = g_slist_next(testing);
|
||||
} // end param loop
|
||||
/* set each rule dependent on the user involvement response above. */
|
||||
/* test routine just sets all MERGE_REPORT to MERGE_UPDATE */
|
||||
mergeData = qof_book_merge_update_result(mergeData, MERGE_UPDATE);
|
||||
do_test ((rule->mergeResult != MERGE_REPORT), "update result fail");
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
qof_init();
|
||||
myobjRegister();
|
||||
test_merge();
|
||||
print_test_results();
|
||||
qof_close();
|
||||
return get_rv();
|
||||
qof_init();
|
||||
myobjRegister();
|
||||
test_merge();
|
||||
print_test_results();
|
||||
qof_close();
|
||||
return get_rv();
|
||||
}
|
||||
|
||||
@@ -125,9 +125,9 @@ test_commodity(void)
|
||||
do_test(
|
||||
gnc_commodity_equiv(com, com2), "commodity equiv");
|
||||
|
||||
qof_book_destroy (book);
|
||||
qof_book_destroy (book);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
int i, j, num_total = 0;
|
||||
gnc_commodity_table *tbl;
|
||||
@@ -140,13 +140,13 @@ test_commodity(void)
|
||||
do_test(gnc_commodity_table_get_size(tbl) == 0,
|
||||
"test size for 0 table");
|
||||
|
||||
for(i = 0; i < 20; i++)
|
||||
for (i = 0; i < 20; i++)
|
||||
{
|
||||
coms[i] = get_random_commodity(book);
|
||||
|
||||
if (!gnc_commodity_table_lookup(
|
||||
tbl, gnc_commodity_get_namespace(coms[i]),
|
||||
gnc_commodity_get_mnemonic(coms[i])))
|
||||
tbl, gnc_commodity_get_namespace(coms[i]),
|
||||
gnc_commodity_get_mnemonic(coms[i])))
|
||||
num_total++;
|
||||
do_test(
|
||||
gnc_commodity_table_insert(tbl, coms[i]) != NULL,
|
||||
@@ -158,14 +158,14 @@ test_commodity(void)
|
||||
"should be %d and is %d", num_total,
|
||||
gnc_commodity_table_get_size(tbl));
|
||||
|
||||
for(j = 0; j <= i; j++)
|
||||
for (j = 0; j <= i; j++)
|
||||
{
|
||||
gnc_commodity *testcom;
|
||||
|
||||
do_test(
|
||||
(testcom = gnc_commodity_table_lookup(
|
||||
tbl, gnc_commodity_get_namespace(coms[j]),
|
||||
gnc_commodity_get_mnemonic(coms[j]))) != NULL,
|
||||
tbl, gnc_commodity_get_namespace(coms[j]),
|
||||
gnc_commodity_get_mnemonic(coms[j]))) != NULL,
|
||||
"lookup commodity");
|
||||
do_test(
|
||||
gnc_commodity_equiv(testcom, coms[j]),
|
||||
@@ -178,7 +178,7 @@ test_commodity(void)
|
||||
"test have namespace");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -16,370 +16,370 @@
|
||||
static gboolean
|
||||
check_time (Timespec ts, gboolean always_print)
|
||||
{
|
||||
Timespec ts_2;
|
||||
char str[128];
|
||||
gboolean ok;
|
||||
Timespec ts_2;
|
||||
char str[128];
|
||||
gboolean ok;
|
||||
|
||||
ts.tv_nsec = MIN (ts.tv_nsec, 999999999);
|
||||
ts.tv_nsec /= 1000;
|
||||
ts.tv_nsec *= 1000;
|
||||
ts.tv_nsec = MIN (ts.tv_nsec, 999999999);
|
||||
ts.tv_nsec /= 1000;
|
||||
ts.tv_nsec *= 1000;
|
||||
|
||||
/* We just can't handle dates whose time_t doesn't fit in int - skip those
|
||||
* cases. */
|
||||
if (ts.tv_sec > (0x7fffffff - 3600*25))
|
||||
return TRUE;
|
||||
/* We just can't handle dates whose time_t doesn't fit in int - skip those
|
||||
* cases. */
|
||||
if (ts.tv_sec > (0x7fffffff - 3600 * 25))
|
||||
return TRUE;
|
||||
|
||||
/* If we are east of UTC, we also can't handle dates whose tv_sec member
|
||||
* falls in the range [0, -gnc_timezone(tm)) - make sure were are at least 12
|
||||
* hours past the epoch to skip those cases too */
|
||||
if (ts.tv_sec < 3600*12)
|
||||
return TRUE;
|
||||
/* If we are east of UTC, we also can't handle dates whose tv_sec member
|
||||
* falls in the range [0, -gnc_timezone(tm)) - make sure were are at least 12
|
||||
* hours past the epoch to skip those cases too */
|
||||
if (ts.tv_sec < 3600 * 12)
|
||||
return TRUE;
|
||||
|
||||
gnc_timespec_to_iso8601_buff (ts, str);
|
||||
gnc_timespec_to_iso8601_buff (ts, str);
|
||||
|
||||
/* The time, in seconds, everywhere on the planet, is always
|
||||
* the same, and is independent of location. In particular,
|
||||
* the time, in seconds, is identical to the local time in
|
||||
* Greenwich (GMT).
|
||||
*/
|
||||
ts_2 = gnc_iso8601_to_timespec_gmt (str);
|
||||
/* The time, in seconds, everywhere on the planet, is always
|
||||
* the same, and is independent of location. In particular,
|
||||
* the time, in seconds, is identical to the local time in
|
||||
* Greenwich (GMT).
|
||||
*/
|
||||
ts_2 = gnc_iso8601_to_timespec_gmt (str);
|
||||
|
||||
ok = timespec_equal (&ts, &ts_2);
|
||||
ok = timespec_equal (&ts, &ts_2);
|
||||
|
||||
if (!ok || always_print)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"\n%" G_GINT64_FORMAT ":%ld -> %s ->\n"
|
||||
"\t%" G_GINT64_FORMAT ":%ld"
|
||||
" (diff of %" G_GINT64_FORMAT " secs %ld nsecs)\n",
|
||||
ts.tv_sec, ts.tv_nsec, str,
|
||||
ts_2.tv_sec, ts_2.tv_nsec,
|
||||
ts.tv_sec - ts_2.tv_sec, ts.tv_nsec - ts_2.tv_nsec);
|
||||
|
||||
if (!ok)
|
||||
if (!ok || always_print)
|
||||
{
|
||||
failure ("timespec to iso8601 string conversion failed");
|
||||
return FALSE;
|
||||
fprintf (stderr,
|
||||
"\n%" G_GINT64_FORMAT ":%ld -> %s ->\n"
|
||||
"\t%" G_GINT64_FORMAT ":%ld"
|
||||
" (diff of %" G_GINT64_FORMAT " secs %ld nsecs)\n",
|
||||
ts.tv_sec, ts.tv_nsec, str,
|
||||
ts_2.tv_sec, ts_2.tv_nsec,
|
||||
ts.tv_sec - ts_2.tv_sec, ts.tv_nsec - ts_2.tv_nsec);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
failure ("timespec to iso8601 string conversion failed");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
success ("timespec to iso8601 string conversion passes");
|
||||
success ("timespec to iso8601 string conversion passes");
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_conversion (const char * str, Timespec expected_ts)
|
||||
{
|
||||
Timespec ts;
|
||||
Timespec ts;
|
||||
|
||||
ts = gnc_iso8601_to_timespec_gmt (str);
|
||||
ts = gnc_iso8601_to_timespec_gmt (str);
|
||||
|
||||
if ((expected_ts.tv_sec != ts.tv_sec) || (expected_ts.tv_nsec != ts.tv_nsec))
|
||||
{
|
||||
fprintf (stderr,
|
||||
"\nmis-converted \"%s\" to %" G_GUINT64_FORMAT ".%09ld seconds\n"
|
||||
"\twas expecting %" G_GUINT64_FORMAT ".%09ld seconds\n",
|
||||
str, ts.tv_sec, ts.tv_nsec,
|
||||
expected_ts.tv_sec, expected_ts.tv_nsec);
|
||||
failure ("misconverted timespec");
|
||||
return FALSE;
|
||||
}
|
||||
success ("good conversion");
|
||||
return TRUE;
|
||||
if ((expected_ts.tv_sec != ts.tv_sec) || (expected_ts.tv_nsec != ts.tv_nsec))
|
||||
{
|
||||
fprintf (stderr,
|
||||
"\nmis-converted \"%s\" to %" G_GUINT64_FORMAT ".%09ld seconds\n"
|
||||
"\twas expecting %" G_GUINT64_FORMAT ".%09ld seconds\n",
|
||||
str, ts.tv_sec, ts.tv_nsec,
|
||||
expected_ts.tv_sec, expected_ts.tv_nsec);
|
||||
failure ("misconverted timespec");
|
||||
return FALSE;
|
||||
}
|
||||
success ("good conversion");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
run_test (void)
|
||||
{
|
||||
Timespec ts;
|
||||
int i;
|
||||
gboolean do_print = FALSE;
|
||||
Timespec ts;
|
||||
int i;
|
||||
gboolean do_print = FALSE;
|
||||
|
||||
/* Now leaving the 60's:
|
||||
*
|
||||
* Black Panthers
|
||||
* Weather Underground
|
||||
* Kent State
|
||||
* Evacuation of Vietnam
|
||||
* Impeachment
|
||||
* Gas Crisis
|
||||
* New York Garbage Crisis
|
||||
* Stagflation
|
||||
* Delapidated Bicentennial
|
||||
* Sex Pistols
|
||||
* Punk Rock
|
||||
*
|
||||
* Of course, anything had to be better than the miserable 70's,
|
||||
* which explains why Reagan was elected. Food for thought.
|
||||
*/
|
||||
ts.tv_sec = 10*365*24*3600 + 2*24*3600;
|
||||
ts.tv_nsec = 0;
|
||||
check_conversion ("1979-12-31 15:00:00.000000 -0900", ts);
|
||||
check_conversion ("1979-12-31 16:00:00.000000 -0800", ts);
|
||||
check_conversion ("1979-12-31 17:00:00.000000 -0700", ts);
|
||||
check_conversion ("1979-12-31 18:00:00.000000 -0600", ts);
|
||||
check_conversion ("1979-12-31 19:00:00.000000 -0500", ts);
|
||||
check_conversion ("1979-12-31 20:00:00.000000 -0400", ts);
|
||||
check_conversion ("1979-12-31 21:00:00.000000 -0300", ts);
|
||||
check_conversion ("1979-12-31 22:00:00.000000 -0200", ts);
|
||||
check_conversion ("1979-12-31 23:00:00.000000 -0100", ts);
|
||||
/* Now leaving the 60's:
|
||||
*
|
||||
* Black Panthers
|
||||
* Weather Underground
|
||||
* Kent State
|
||||
* Evacuation of Vietnam
|
||||
* Impeachment
|
||||
* Gas Crisis
|
||||
* New York Garbage Crisis
|
||||
* Stagflation
|
||||
* Delapidated Bicentennial
|
||||
* Sex Pistols
|
||||
* Punk Rock
|
||||
*
|
||||
* Of course, anything had to be better than the miserable 70's,
|
||||
* which explains why Reagan was elected. Food for thought.
|
||||
*/
|
||||
ts.tv_sec = 10 * 365 * 24 * 3600 + 2 * 24 * 3600;
|
||||
ts.tv_nsec = 0;
|
||||
check_conversion ("1979-12-31 15:00:00.000000 -0900", ts);
|
||||
check_conversion ("1979-12-31 16:00:00.000000 -0800", ts);
|
||||
check_conversion ("1979-12-31 17:00:00.000000 -0700", ts);
|
||||
check_conversion ("1979-12-31 18:00:00.000000 -0600", ts);
|
||||
check_conversion ("1979-12-31 19:00:00.000000 -0500", ts);
|
||||
check_conversion ("1979-12-31 20:00:00.000000 -0400", ts);
|
||||
check_conversion ("1979-12-31 21:00:00.000000 -0300", ts);
|
||||
check_conversion ("1979-12-31 22:00:00.000000 -0200", ts);
|
||||
check_conversion ("1979-12-31 23:00:00.000000 -0100", ts);
|
||||
|
||||
check_conversion ("1980-01-01 00:00:00.000000 -0000", ts);
|
||||
check_conversion ("1980-01-01 00:00:00.000000 +0000", ts);
|
||||
check_conversion ("1980-01-01 00:00:00.000000 -0000", ts);
|
||||
check_conversion ("1980-01-01 00:00:00.000000 +0000", ts);
|
||||
|
||||
check_conversion ("1980-01-01 01:00:00.000000 +0100", ts);
|
||||
check_conversion ("1980-01-01 02:00:00.000000 +0200", ts);
|
||||
check_conversion ("1980-01-01 03:00:00.000000 +0300", ts);
|
||||
check_conversion ("1980-01-01 04:00:00.000000 +0400", ts);
|
||||
check_conversion ("1980-01-01 05:00:00.000000 +0500", ts);
|
||||
check_conversion ("1980-01-01 06:00:00.000000 +0600", ts);
|
||||
check_conversion ("1980-01-01 07:00:00.000000 +0700", ts);
|
||||
check_conversion ("1980-01-01 08:00:00.000000 +0800", ts);
|
||||
check_conversion ("1980-01-01 01:00:00.000000 +0100", ts);
|
||||
check_conversion ("1980-01-01 02:00:00.000000 +0200", ts);
|
||||
check_conversion ("1980-01-01 03:00:00.000000 +0300", ts);
|
||||
check_conversion ("1980-01-01 04:00:00.000000 +0400", ts);
|
||||
check_conversion ("1980-01-01 05:00:00.000000 +0500", ts);
|
||||
check_conversion ("1980-01-01 06:00:00.000000 +0600", ts);
|
||||
check_conversion ("1980-01-01 07:00:00.000000 +0700", ts);
|
||||
check_conversion ("1980-01-01 08:00:00.000000 +0800", ts);
|
||||
|
||||
/* check minute-offsets as well */
|
||||
check_conversion ("1980-01-01 08:01:00.000000 +0801", ts);
|
||||
check_conversion ("1980-01-01 08:02:00.000000 +0802", ts);
|
||||
check_conversion ("1980-01-01 08:03:00.000000 +0803", ts);
|
||||
check_conversion ("1980-01-01 08:23:00.000000 +0823", ts);
|
||||
check_conversion ("1980-01-01 08:35:00.000000 +0835", ts);
|
||||
check_conversion ("1980-01-01 08:47:00.000000 +0847", ts);
|
||||
check_conversion ("1980-01-01 08:59:00.000000 +0859", ts);
|
||||
/* check minute-offsets as well */
|
||||
check_conversion ("1980-01-01 08:01:00.000000 +0801", ts);
|
||||
check_conversion ("1980-01-01 08:02:00.000000 +0802", ts);
|
||||
check_conversion ("1980-01-01 08:03:00.000000 +0803", ts);
|
||||
check_conversion ("1980-01-01 08:23:00.000000 +0823", ts);
|
||||
check_conversion ("1980-01-01 08:35:00.000000 +0835", ts);
|
||||
check_conversion ("1980-01-01 08:47:00.000000 +0847", ts);
|
||||
check_conversion ("1980-01-01 08:59:00.000000 +0859", ts);
|
||||
|
||||
check_conversion ("1979-12-31 15:01:00.000000 -0859", ts);
|
||||
check_conversion ("1979-12-31 15:02:00.000000 -0858", ts);
|
||||
check_conversion ("1979-12-31 15:03:00.000000 -0857", ts);
|
||||
check_conversion ("1979-12-31 15:23:00.000000 -0837", ts);
|
||||
check_conversion ("1979-12-31 15:45:00.000000 -0815", ts);
|
||||
check_conversion ("1979-12-31 15:01:00.000000 -0859", ts);
|
||||
check_conversion ("1979-12-31 15:02:00.000000 -0858", ts);
|
||||
check_conversion ("1979-12-31 15:03:00.000000 -0857", ts);
|
||||
check_conversion ("1979-12-31 15:23:00.000000 -0837", ts);
|
||||
check_conversion ("1979-12-31 15:45:00.000000 -0815", ts);
|
||||
|
||||
|
||||
/* The 90's */
|
||||
ts.tv_sec = 20*365*24*3600 + 5*24*3600;
|
||||
ts.tv_nsec = 0;
|
||||
check_conversion ("1989-12-31 15:00:00.000000 -0900", ts);
|
||||
check_conversion ("1989-12-31 16:00:00.000000 -0800", ts);
|
||||
check_conversion ("1989-12-31 17:00:00.000000 -0700", ts);
|
||||
check_conversion ("1989-12-31 18:00:00.000000 -0600", ts);
|
||||
check_conversion ("1989-12-31 19:00:00.000000 -0500", ts);
|
||||
check_conversion ("1989-12-31 20:00:00.000000 -0400", ts);
|
||||
check_conversion ("1989-12-31 21:00:00.000000 -0300", ts);
|
||||
check_conversion ("1989-12-31 22:00:00.000000 -0200", ts);
|
||||
check_conversion ("1989-12-31 23:00:00.000000 -0100", ts);
|
||||
/* The 90's */
|
||||
ts.tv_sec = 20 * 365 * 24 * 3600 + 5 * 24 * 3600;
|
||||
ts.tv_nsec = 0;
|
||||
check_conversion ("1989-12-31 15:00:00.000000 -0900", ts);
|
||||
check_conversion ("1989-12-31 16:00:00.000000 -0800", ts);
|
||||
check_conversion ("1989-12-31 17:00:00.000000 -0700", ts);
|
||||
check_conversion ("1989-12-31 18:00:00.000000 -0600", ts);
|
||||
check_conversion ("1989-12-31 19:00:00.000000 -0500", ts);
|
||||
check_conversion ("1989-12-31 20:00:00.000000 -0400", ts);
|
||||
check_conversion ("1989-12-31 21:00:00.000000 -0300", ts);
|
||||
check_conversion ("1989-12-31 22:00:00.000000 -0200", ts);
|
||||
check_conversion ("1989-12-31 23:00:00.000000 -0100", ts);
|
||||
|
||||
check_conversion ("1990-01-01 00:00:00.000000 -0000", ts);
|
||||
check_conversion ("1990-01-01 00:00:00.000000 +0000", ts);
|
||||
check_conversion ("1990-01-01 00:00:00.000000 -0000", ts);
|
||||
check_conversion ("1990-01-01 00:00:00.000000 +0000", ts);
|
||||
|
||||
check_conversion ("1990-01-01 01:00:00.000000 +0100", ts);
|
||||
check_conversion ("1990-01-01 02:00:00.000000 +0200", ts);
|
||||
check_conversion ("1990-01-01 03:00:00.000000 +0300", ts);
|
||||
check_conversion ("1990-01-01 04:00:00.000000 +0400", ts);
|
||||
check_conversion ("1990-01-01 05:00:00.000000 +0500", ts);
|
||||
check_conversion ("1990-01-01 06:00:00.000000 +0600", ts);
|
||||
check_conversion ("1990-01-01 07:00:00.000000 +0700", ts);
|
||||
check_conversion ("1990-01-01 08:00:00.000000 +0800", ts);
|
||||
check_conversion ("1990-01-01 01:00:00.000000 +0100", ts);
|
||||
check_conversion ("1990-01-01 02:00:00.000000 +0200", ts);
|
||||
check_conversion ("1990-01-01 03:00:00.000000 +0300", ts);
|
||||
check_conversion ("1990-01-01 04:00:00.000000 +0400", ts);
|
||||
check_conversion ("1990-01-01 05:00:00.000000 +0500", ts);
|
||||
check_conversion ("1990-01-01 06:00:00.000000 +0600", ts);
|
||||
check_conversion ("1990-01-01 07:00:00.000000 +0700", ts);
|
||||
check_conversion ("1990-01-01 08:00:00.000000 +0800", ts);
|
||||
|
||||
/* check minute-offsets as well */
|
||||
check_conversion ("1990-01-01 08:01:00.000000 +0801", ts);
|
||||
check_conversion ("1990-01-01 08:02:00.000000 +0802", ts);
|
||||
check_conversion ("1990-01-01 08:03:00.000000 +0803", ts);
|
||||
check_conversion ("1990-01-01 08:23:00.000000 +0823", ts);
|
||||
check_conversion ("1990-01-01 08:35:00.000000 +0835", ts);
|
||||
check_conversion ("1990-01-01 08:47:00.000000 +0847", ts);
|
||||
check_conversion ("1990-01-01 08:59:00.000000 +0859", ts);
|
||||
/* check minute-offsets as well */
|
||||
check_conversion ("1990-01-01 08:01:00.000000 +0801", ts);
|
||||
check_conversion ("1990-01-01 08:02:00.000000 +0802", ts);
|
||||
check_conversion ("1990-01-01 08:03:00.000000 +0803", ts);
|
||||
check_conversion ("1990-01-01 08:23:00.000000 +0823", ts);
|
||||
check_conversion ("1990-01-01 08:35:00.000000 +0835", ts);
|
||||
check_conversion ("1990-01-01 08:47:00.000000 +0847", ts);
|
||||
check_conversion ("1990-01-01 08:59:00.000000 +0859", ts);
|
||||
|
||||
check_conversion ("1989-12-31 15:01:00.000000 -0859", ts);
|
||||
check_conversion ("1989-12-31 15:02:00.000000 -0858", ts);
|
||||
check_conversion ("1989-12-31 15:03:00.000000 -0857", ts);
|
||||
check_conversion ("1989-12-31 15:23:00.000000 -0837", ts);
|
||||
check_conversion ("1989-12-31 15:45:00.000000 -0815", ts);
|
||||
check_conversion ("1989-12-31 15:01:00.000000 -0859", ts);
|
||||
check_conversion ("1989-12-31 15:02:00.000000 -0858", ts);
|
||||
check_conversion ("1989-12-31 15:03:00.000000 -0857", ts);
|
||||
check_conversion ("1989-12-31 15:23:00.000000 -0837", ts);
|
||||
check_conversion ("1989-12-31 15:45:00.000000 -0815", ts);
|
||||
|
||||
|
||||
/* The naughties */
|
||||
ts.tv_sec = 30*365*24*3600 + 7*24*3600;
|
||||
ts.tv_nsec = 0;
|
||||
check_conversion ("1999-12-31 15:00:00.000000 -0900", ts);
|
||||
check_conversion ("1999-12-31 16:00:00.000000 -0800", ts);
|
||||
check_conversion ("1999-12-31 17:00:00.000000 -0700", ts);
|
||||
check_conversion ("1999-12-31 18:00:00.000000 -0600", ts);
|
||||
check_conversion ("1999-12-31 19:00:00.000000 -0500", ts);
|
||||
check_conversion ("1999-12-31 20:00:00.000000 -0400", ts);
|
||||
check_conversion ("1999-12-31 21:00:00.000000 -0300", ts);
|
||||
check_conversion ("1999-12-31 22:00:00.000000 -0200", ts);
|
||||
check_conversion ("1999-12-31 23:00:00.000000 -0100", ts);
|
||||
/* The naughties */
|
||||
ts.tv_sec = 30 * 365 * 24 * 3600 + 7 * 24 * 3600;
|
||||
ts.tv_nsec = 0;
|
||||
check_conversion ("1999-12-31 15:00:00.000000 -0900", ts);
|
||||
check_conversion ("1999-12-31 16:00:00.000000 -0800", ts);
|
||||
check_conversion ("1999-12-31 17:00:00.000000 -0700", ts);
|
||||
check_conversion ("1999-12-31 18:00:00.000000 -0600", ts);
|
||||
check_conversion ("1999-12-31 19:00:00.000000 -0500", ts);
|
||||
check_conversion ("1999-12-31 20:00:00.000000 -0400", ts);
|
||||
check_conversion ("1999-12-31 21:00:00.000000 -0300", ts);
|
||||
check_conversion ("1999-12-31 22:00:00.000000 -0200", ts);
|
||||
check_conversion ("1999-12-31 23:00:00.000000 -0100", ts);
|
||||
|
||||
check_conversion ("2000-01-01 00:00:00.000000 -0000", ts);
|
||||
check_conversion ("2000-01-01 00:00:00.000000 +0000", ts);
|
||||
check_conversion ("2000-01-01 00:00:00.000000 -0000", ts);
|
||||
check_conversion ("2000-01-01 00:00:00.000000 +0000", ts);
|
||||
|
||||
check_conversion ("2000-01-01 01:00:00.000000 +0100", ts);
|
||||
check_conversion ("2000-01-01 02:00:00.000000 +0200", ts);
|
||||
check_conversion ("2000-01-01 03:00:00.000000 +0300", ts);
|
||||
check_conversion ("2000-01-01 04:00:00.000000 +0400", ts);
|
||||
check_conversion ("2000-01-01 05:00:00.000000 +0500", ts);
|
||||
check_conversion ("2000-01-01 06:00:00.000000 +0600", ts);
|
||||
check_conversion ("2000-01-01 07:00:00.000000 +0700", ts);
|
||||
check_conversion ("2000-01-01 08:00:00.000000 +0800", ts);
|
||||
check_conversion ("2000-01-01 01:00:00.000000 +0100", ts);
|
||||
check_conversion ("2000-01-01 02:00:00.000000 +0200", ts);
|
||||
check_conversion ("2000-01-01 03:00:00.000000 +0300", ts);
|
||||
check_conversion ("2000-01-01 04:00:00.000000 +0400", ts);
|
||||
check_conversion ("2000-01-01 05:00:00.000000 +0500", ts);
|
||||
check_conversion ("2000-01-01 06:00:00.000000 +0600", ts);
|
||||
check_conversion ("2000-01-01 07:00:00.000000 +0700", ts);
|
||||
check_conversion ("2000-01-01 08:00:00.000000 +0800", ts);
|
||||
|
||||
/* check minute-offsets as well */
|
||||
check_conversion ("2000-01-01 08:01:00.000000 +0801", ts);
|
||||
check_conversion ("2000-01-01 08:02:00.000000 +0802", ts);
|
||||
check_conversion ("2000-01-01 08:03:00.000000 +0803", ts);
|
||||
check_conversion ("2000-01-01 08:23:00.000000 +0823", ts);
|
||||
check_conversion ("2000-01-01 08:35:00.000000 +0835", ts);
|
||||
check_conversion ("2000-01-01 08:47:00.000000 +0847", ts);
|
||||
check_conversion ("2000-01-01 08:59:00.000000 +0859", ts);
|
||||
/* check minute-offsets as well */
|
||||
check_conversion ("2000-01-01 08:01:00.000000 +0801", ts);
|
||||
check_conversion ("2000-01-01 08:02:00.000000 +0802", ts);
|
||||
check_conversion ("2000-01-01 08:03:00.000000 +0803", ts);
|
||||
check_conversion ("2000-01-01 08:23:00.000000 +0823", ts);
|
||||
check_conversion ("2000-01-01 08:35:00.000000 +0835", ts);
|
||||
check_conversion ("2000-01-01 08:47:00.000000 +0847", ts);
|
||||
check_conversion ("2000-01-01 08:59:00.000000 +0859", ts);
|
||||
|
||||
check_conversion ("1999-12-31 15:01:00.000000 -0859", ts);
|
||||
check_conversion ("1999-12-31 15:02:00.000000 -0858", ts);
|
||||
check_conversion ("1999-12-31 15:03:00.000000 -0857", ts);
|
||||
check_conversion ("1999-12-31 15:23:00.000000 -0837", ts);
|
||||
check_conversion ("1999-12-31 15:45:00.000000 -0815", ts);
|
||||
check_conversion ("1999-12-31 15:01:00.000000 -0859", ts);
|
||||
check_conversion ("1999-12-31 15:02:00.000000 -0858", ts);
|
||||
check_conversion ("1999-12-31 15:03:00.000000 -0857", ts);
|
||||
check_conversion ("1999-12-31 15:23:00.000000 -0837", ts);
|
||||
check_conversion ("1999-12-31 15:45:00.000000 -0815", ts);
|
||||
|
||||
|
||||
/* The nows */
|
||||
ts.tv_sec = 35*365*24*3600 + 9*24*3600;
|
||||
ts.tv_nsec = 0;
|
||||
check_conversion ("2004-12-31 15:00:00.000000 -0900", ts);
|
||||
check_conversion ("2004-12-31 16:00:00.000000 -0800", ts);
|
||||
check_conversion ("2004-12-31 17:00:00.000000 -0700", ts);
|
||||
check_conversion ("2004-12-31 18:00:00.000000 -0600", ts);
|
||||
check_conversion ("2004-12-31 19:00:00.000000 -0500", ts);
|
||||
check_conversion ("2004-12-31 20:00:00.000000 -0400", ts);
|
||||
check_conversion ("2004-12-31 21:00:00.000000 -0300", ts);
|
||||
check_conversion ("2004-12-31 22:00:00.000000 -0200", ts);
|
||||
check_conversion ("2004-12-31 23:00:00.000000 -0100", ts);
|
||||
/* The nows */
|
||||
ts.tv_sec = 35 * 365 * 24 * 3600 + 9 * 24 * 3600;
|
||||
ts.tv_nsec = 0;
|
||||
check_conversion ("2004-12-31 15:00:00.000000 -0900", ts);
|
||||
check_conversion ("2004-12-31 16:00:00.000000 -0800", ts);
|
||||
check_conversion ("2004-12-31 17:00:00.000000 -0700", ts);
|
||||
check_conversion ("2004-12-31 18:00:00.000000 -0600", ts);
|
||||
check_conversion ("2004-12-31 19:00:00.000000 -0500", ts);
|
||||
check_conversion ("2004-12-31 20:00:00.000000 -0400", ts);
|
||||
check_conversion ("2004-12-31 21:00:00.000000 -0300", ts);
|
||||
check_conversion ("2004-12-31 22:00:00.000000 -0200", ts);
|
||||
check_conversion ("2004-12-31 23:00:00.000000 -0100", ts);
|
||||
|
||||
check_conversion ("2005-01-01 00:00:00.000000 -0000", ts);
|
||||
check_conversion ("2005-01-01 00:00:00.000000 +0000", ts);
|
||||
check_conversion ("2005-01-01 00:00:00.000000 -0000", ts);
|
||||
check_conversion ("2005-01-01 00:00:00.000000 +0000", ts);
|
||||
|
||||
check_conversion ("2005-01-01 01:00:00.000000 +0100", ts);
|
||||
check_conversion ("2005-01-01 02:00:00.000000 +0200", ts);
|
||||
check_conversion ("2005-01-01 03:00:00.000000 +0300", ts);
|
||||
check_conversion ("2005-01-01 04:00:00.000000 +0400", ts);
|
||||
check_conversion ("2005-01-01 05:00:00.000000 +0500", ts);
|
||||
check_conversion ("2005-01-01 06:00:00.000000 +0600", ts);
|
||||
check_conversion ("2005-01-01 07:00:00.000000 +0700", ts);
|
||||
check_conversion ("2005-01-01 08:00:00.000000 +0800", ts);
|
||||
check_conversion ("2005-01-01 01:00:00.000000 +0100", ts);
|
||||
check_conversion ("2005-01-01 02:00:00.000000 +0200", ts);
|
||||
check_conversion ("2005-01-01 03:00:00.000000 +0300", ts);
|
||||
check_conversion ("2005-01-01 04:00:00.000000 +0400", ts);
|
||||
check_conversion ("2005-01-01 05:00:00.000000 +0500", ts);
|
||||
check_conversion ("2005-01-01 06:00:00.000000 +0600", ts);
|
||||
check_conversion ("2005-01-01 07:00:00.000000 +0700", ts);
|
||||
check_conversion ("2005-01-01 08:00:00.000000 +0800", ts);
|
||||
|
||||
/* check minute-offsets as well */
|
||||
check_conversion ("2005-01-01 08:01:00.000000 +0801", ts);
|
||||
check_conversion ("2005-01-01 08:02:00.000000 +0802", ts);
|
||||
check_conversion ("2005-01-01 08:03:00.000000 +0803", ts);
|
||||
check_conversion ("2005-01-01 08:23:00.000000 +0823", ts);
|
||||
check_conversion ("2005-01-01 08:35:00.000000 +0835", ts);
|
||||
check_conversion ("2005-01-01 08:47:00.000000 +0847", ts);
|
||||
check_conversion ("2005-01-01 08:59:00.000000 +0859", ts);
|
||||
/* check minute-offsets as well */
|
||||
check_conversion ("2005-01-01 08:01:00.000000 +0801", ts);
|
||||
check_conversion ("2005-01-01 08:02:00.000000 +0802", ts);
|
||||
check_conversion ("2005-01-01 08:03:00.000000 +0803", ts);
|
||||
check_conversion ("2005-01-01 08:23:00.000000 +0823", ts);
|
||||
check_conversion ("2005-01-01 08:35:00.000000 +0835", ts);
|
||||
check_conversion ("2005-01-01 08:47:00.000000 +0847", ts);
|
||||
check_conversion ("2005-01-01 08:59:00.000000 +0859", ts);
|
||||
|
||||
check_conversion ("2004-12-31 15:01:00.000000 -0859", ts);
|
||||
check_conversion ("2004-12-31 15:02:00.000000 -0858", ts);
|
||||
check_conversion ("2004-12-31 15:03:00.000000 -0857", ts);
|
||||
check_conversion ("2004-12-31 15:23:00.000000 -0837", ts);
|
||||
check_conversion ("2004-12-31 15:45:00.000000 -0815", ts);
|
||||
check_conversion ("2004-12-31 15:01:00.000000 -0859", ts);
|
||||
check_conversion ("2004-12-31 15:02:00.000000 -0858", ts);
|
||||
check_conversion ("2004-12-31 15:03:00.000000 -0857", ts);
|
||||
check_conversion ("2004-12-31 15:23:00.000000 -0837", ts);
|
||||
check_conversion ("2004-12-31 15:45:00.000000 -0815", ts);
|
||||
|
||||
|
||||
/* Various leap-year days and near-leap times. */
|
||||
ts = gnc_iso8601_to_timespec_gmt ("1980-02-29 00:00:00.000000 -0000");
|
||||
check_time (ts, do_print);
|
||||
/* Various leap-year days and near-leap times. */
|
||||
ts = gnc_iso8601_to_timespec_gmt ("1980-02-29 00:00:00.000000 -0000");
|
||||
check_time (ts, do_print);
|
||||
|
||||
ts = gnc_iso8601_to_timespec_gmt ("1979-02-28 00:00:00.000000 -0000");
|
||||
check_time (ts, do_print);
|
||||
ts = gnc_iso8601_to_timespec_gmt ("1979-02-28 00:00:00.000000 -0000");
|
||||
check_time (ts, do_print);
|
||||
|
||||
ts = gnc_iso8601_to_timespec_gmt ("1990-02-28 00:00:00.000000 -0000");
|
||||
check_time (ts, do_print);
|
||||
ts = gnc_iso8601_to_timespec_gmt ("1990-02-28 00:00:00.000000 -0000");
|
||||
check_time (ts, do_print);
|
||||
|
||||
ts = gnc_iso8601_to_timespec_gmt ("2000-02-29 00:00:00.000000 -0000");
|
||||
check_time (ts, do_print);
|
||||
ts = gnc_iso8601_to_timespec_gmt ("2000-02-29 00:00:00.000000 -0000");
|
||||
check_time (ts, do_print);
|
||||
|
||||
ts = gnc_iso8601_to_timespec_gmt ("2004-02-29 00:00:00.000000 -0000");
|
||||
check_time (ts, do_print);
|
||||
ts = gnc_iso8601_to_timespec_gmt ("2004-02-29 00:00:00.000000 -0000");
|
||||
check_time (ts, do_print);
|
||||
|
||||
ts = gnc_iso8601_to_timespec_gmt ("2008-02-29 00:00:00.000000 -0000");
|
||||
check_time (ts, do_print);
|
||||
ts = gnc_iso8601_to_timespec_gmt ("2008-02-29 00:00:00.000000 -0000");
|
||||
check_time (ts, do_print);
|
||||
|
||||
ts = gnc_iso8601_to_timespec_gmt ("2008-02-29 00:01:00.000000 -0000");
|
||||
check_time (ts, do_print);
|
||||
ts = gnc_iso8601_to_timespec_gmt ("2008-02-29 00:01:00.000000 -0000");
|
||||
check_time (ts, do_print);
|
||||
|
||||
ts = gnc_iso8601_to_timespec_gmt ("2008-02-29 02:02:00.000000 -0000");
|
||||
check_time (ts, do_print);
|
||||
ts = gnc_iso8601_to_timespec_gmt ("2008-02-29 02:02:00.000000 -0000");
|
||||
check_time (ts, do_print);
|
||||
|
||||
ts = gnc_iso8601_to_timespec_gmt ("2008-02-28 23:23:23.000000 -0000");
|
||||
check_time (ts, do_print);
|
||||
ts = gnc_iso8601_to_timespec_gmt ("2008-02-28 23:23:23.000000 -0000");
|
||||
check_time (ts, do_print);
|
||||
|
||||
/* Here's a date ten days after the 2038 rollover that should work
|
||||
if/when we support it. */
|
||||
ts.tv_nsec = 0;
|
||||
ts.tv_sec = (long long int) 0x7fffffff + 3600*24*10;
|
||||
//check_time(ts, do_print);
|
||||
/* Here's a date ten days after the 2038 rollover that should work
|
||||
if/when we support it. */
|
||||
ts.tv_nsec = 0;
|
||||
ts.tv_sec = (long long int) 0x7fffffff + 3600 * 24 * 10;
|
||||
//check_time(ts, do_print);
|
||||
|
||||
/* Various 'special' times. What makes these so special? */
|
||||
ts.tv_sec = 152098136;
|
||||
ts.tv_nsec = 0;
|
||||
check_time (ts, do_print);
|
||||
/* Various 'special' times. What makes these so special? */
|
||||
ts.tv_sec = 152098136;
|
||||
ts.tv_nsec = 0;
|
||||
check_time (ts, do_print);
|
||||
|
||||
ts.tv_sec = 1162088421;
|
||||
ts.tv_nsec = 12548000;
|
||||
check_time (ts, do_print);
|
||||
ts.tv_sec = 1162088421;
|
||||
ts.tv_nsec = 12548000;
|
||||
check_time (ts, do_print);
|
||||
|
||||
ts.tv_sec = 325659000 - 6500;
|
||||
ts.tv_nsec = 0;
|
||||
check_time (ts, do_print);
|
||||
ts.tv_sec = 325659000 - 6500;
|
||||
ts.tv_nsec = 0;
|
||||
check_time (ts, do_print);
|
||||
|
||||
ts.tv_sec = 1143943200;
|
||||
ts.tv_nsec = 0;
|
||||
check_time (ts, do_print);
|
||||
ts.tv_sec = 1143943200;
|
||||
ts.tv_nsec = 0;
|
||||
check_time (ts, do_print);
|
||||
|
||||
ts.tv_sec = 1603591171;
|
||||
ts.tv_nsec = 595311000;
|
||||
check_time (ts, do_print);
|
||||
ts.tv_sec = 1603591171;
|
||||
ts.tv_nsec = 595311000;
|
||||
check_time (ts, do_print);
|
||||
|
||||
ts.tv_sec = 1738909365;
|
||||
ts.tv_nsec = 204102000;
|
||||
check_time (ts, do_print);
|
||||
ts.tv_sec = 1738909365;
|
||||
ts.tv_nsec = 204102000;
|
||||
check_time (ts, do_print);
|
||||
|
||||
ts.tv_sec = 1603591171;
|
||||
ts.tv_nsec = 595311000;
|
||||
check_time (ts, do_print);
|
||||
ts.tv_sec = 1603591171;
|
||||
ts.tv_nsec = 595311000;
|
||||
check_time (ts, do_print);
|
||||
|
||||
ts.tv_sec = 1143943200 - 1;
|
||||
ts.tv_nsec = 0;
|
||||
check_time (ts, do_print);
|
||||
ts.tv_sec = 1143943200 - 1;
|
||||
ts.tv_nsec = 0;
|
||||
check_time (ts, do_print);
|
||||
|
||||
ts.tv_sec = 1143943200;
|
||||
ts.tv_nsec = 0;
|
||||
check_time (ts, do_print);
|
||||
ts.tv_sec = 1143943200;
|
||||
ts.tv_nsec = 0;
|
||||
check_time (ts, do_print);
|
||||
|
||||
ts.tv_sec = 1143943200 + (7 * 60 * 60);
|
||||
ts.tv_nsec = 0;
|
||||
check_time (ts, do_print);
|
||||
ts.tv_sec = 1143943200 + (7 * 60 * 60);
|
||||
ts.tv_nsec = 0;
|
||||
check_time (ts, do_print);
|
||||
|
||||
ts.tv_sec = 1143943200 + (8 * 60 * 60);
|
||||
ts.tv_nsec = 0;
|
||||
check_time (ts, do_print);
|
||||
ts.tv_sec = 1143943200 + (8 * 60 * 60);
|
||||
ts.tv_nsec = 0;
|
||||
check_time (ts, do_print);
|
||||
|
||||
ts = *get_random_timespec ();
|
||||
|
||||
for (i = 0; i < 10000; i++)
|
||||
{
|
||||
ts.tv_sec += 10800;
|
||||
if (!check_time (ts, FALSE))
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 5000; i++)
|
||||
{
|
||||
ts = *get_random_timespec ();
|
||||
|
||||
if (!check_time (ts, FALSE))
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < 10000; i++)
|
||||
{
|
||||
ts.tv_sec += 10800;
|
||||
if (!check_time (ts, FALSE))
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 5000; i++)
|
||||
{
|
||||
ts = *get_random_timespec ();
|
||||
|
||||
if (!check_time (ts, FALSE))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
run_test ();
|
||||
run_test ();
|
||||
|
||||
success ("dates seem to work");
|
||||
success ("dates seem to work");
|
||||
|
||||
print_test_results();
|
||||
exit(get_rv());
|
||||
print_test_results();
|
||||
exit(get_rv());
|
||||
}
|
||||
|
||||
@@ -34,142 +34,143 @@
|
||||
static gboolean
|
||||
account_tree_has_book (Account *parent, QofBook *book)
|
||||
{
|
||||
GList *children, *node;
|
||||
GList *children, *node;
|
||||
|
||||
if (!parent)
|
||||
return (book == NULL);
|
||||
if (!parent)
|
||||
return (book == NULL);
|
||||
|
||||
if (gnc_account_get_book(parent) != book)
|
||||
return FALSE;
|
||||
if (gnc_account_get_book(parent) != book)
|
||||
return FALSE;
|
||||
|
||||
children = gnc_account_get_children(parent);
|
||||
for (node = children; node; node = node->next)
|
||||
{
|
||||
if (!account_tree_has_book (node->data, book))
|
||||
return FALSE;
|
||||
}
|
||||
g_list_free(children);
|
||||
children = gnc_account_get_children(parent);
|
||||
for (node = children; node; node = node->next)
|
||||
{
|
||||
if (!account_tree_has_book (node->data, book))
|
||||
return FALSE;
|
||||
}
|
||||
g_list_free(children);
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
run_test (void)
|
||||
{
|
||||
Account *root1;
|
||||
Account *root2;
|
||||
Account *account1;
|
||||
Account *account2;
|
||||
QofBook *book;
|
||||
Account *root1;
|
||||
Account *root2;
|
||||
Account *account1;
|
||||
Account *account2;
|
||||
QofBook *book;
|
||||
|
||||
book = qof_book_new ();
|
||||
if (!book)
|
||||
{
|
||||
failure("book not created");
|
||||
exit(get_rv());
|
||||
}
|
||||
book = qof_book_new ();
|
||||
if (!book)
|
||||
{
|
||||
failure("book not created");
|
||||
exit(get_rv());
|
||||
}
|
||||
|
||||
root1 = get_random_account (book);
|
||||
if(!root1)
|
||||
{
|
||||
failure("root1 not created");
|
||||
exit(get_rv());
|
||||
}
|
||||
root1 = get_random_account (book);
|
||||
if (!root1)
|
||||
{
|
||||
failure("root1 not created");
|
||||
exit(get_rv());
|
||||
}
|
||||
|
||||
if (!account_tree_has_book (root1, book))
|
||||
{
|
||||
failure("new root has wrong book");
|
||||
exit(get_rv());
|
||||
}
|
||||
if (!account_tree_has_book (root1, book))
|
||||
{
|
||||
failure("new root has wrong book");
|
||||
exit(get_rv());
|
||||
}
|
||||
|
||||
/* This test is testing routines that are private
|
||||
* to the engine. these tests are intended to test
|
||||
* the engine as a whole, not just the public
|
||||
* interface. the maintenance of the correct
|
||||
* book pointers is important for correct
|
||||
* engine operation. */
|
||||
gnc_book_set_root_account (book, root1);
|
||||
if (!account_tree_has_book (root1, book))
|
||||
{
|
||||
failure("gnc_book_set_root_account didn't take");
|
||||
exit(get_rv());
|
||||
}
|
||||
/* This test is testing routines that are private
|
||||
* to the engine. these tests are intended to test
|
||||
* the engine as a whole, not just the public
|
||||
* interface. the maintenance of the correct
|
||||
* book pointers is important for correct
|
||||
* engine operation. */
|
||||
gnc_book_set_root_account (book, root1);
|
||||
if (!account_tree_has_book (root1, book))
|
||||
{
|
||||
failure("gnc_book_set_root_account didn't take");
|
||||
exit(get_rv());
|
||||
}
|
||||
|
||||
root2 = get_random_account (book);
|
||||
if(!root2)
|
||||
{
|
||||
failure("root2 not created");
|
||||
exit(get_rv());
|
||||
}
|
||||
root2 = get_random_account (book);
|
||||
if (!root2)
|
||||
{
|
||||
failure("root2 not created");
|
||||
exit(get_rv());
|
||||
}
|
||||
|
||||
gnc_book_set_root_account (book, root2);
|
||||
gnc_book_set_root_account (book, root2);
|
||||
|
||||
#if 0
|
||||
/* a group cannot have a 'null' book; this test is nonsense. */
|
||||
if (!account_tree_has_book (root1, NULL))
|
||||
{
|
||||
failure("gnc_book_set_root_account didn't clear old");
|
||||
exit(get_rv());
|
||||
}
|
||||
/* a group cannot have a 'null' book; this test is nonsense. */
|
||||
if (!account_tree_has_book (root1, NULL))
|
||||
{
|
||||
failure("gnc_book_set_root_account didn't clear old");
|
||||
exit(get_rv());
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!account_tree_has_book (root2, book))
|
||||
{
|
||||
failure("gnc_book_set_root_account didn't take");
|
||||
exit(get_rv());
|
||||
}
|
||||
if (!account_tree_has_book (root2, book))
|
||||
{
|
||||
failure("gnc_book_set_root_account didn't take");
|
||||
exit(get_rv());
|
||||
}
|
||||
|
||||
account1 = get_random_account (book);
|
||||
if(!account1)
|
||||
{
|
||||
failure("account1 not created");
|
||||
exit(get_rv());
|
||||
}
|
||||
account1 = get_random_account (book);
|
||||
if (!account1)
|
||||
{
|
||||
failure("account1 not created");
|
||||
exit(get_rv());
|
||||
}
|
||||
|
||||
gnc_account_append_child (root2, account1);
|
||||
if (root2 != gnc_account_get_parent (account1))
|
||||
{
|
||||
failure("group insert account didn't work");
|
||||
exit(get_rv());
|
||||
}
|
||||
gnc_account_append_child (root2, account1);
|
||||
if (root2 != gnc_account_get_parent (account1))
|
||||
{
|
||||
failure("group insert account didn't work");
|
||||
exit(get_rv());
|
||||
}
|
||||
|
||||
account2 = get_random_account (book);
|
||||
if(!account2)
|
||||
{
|
||||
failure("account2 not created");
|
||||
exit(get_rv());
|
||||
}
|
||||
account2 = get_random_account (book);
|
||||
if (!account2)
|
||||
{
|
||||
failure("account2 not created");
|
||||
exit(get_rv());
|
||||
}
|
||||
|
||||
gnc_account_append_child (account1, account2);
|
||||
if (!account_tree_has_book (gnc_account_get_parent (account2), book))
|
||||
{
|
||||
failure("account2 has wrong book");
|
||||
exit(get_rv());
|
||||
}
|
||||
gnc_account_append_child (account1, account2);
|
||||
if (!account_tree_has_book (gnc_account_get_parent (account2), book))
|
||||
{
|
||||
failure("account2 has wrong book");
|
||||
exit(get_rv());
|
||||
}
|
||||
|
||||
gnc_account_remove_child (root2, account1);
|
||||
if (gnc_account_get_parent (account1) != NULL)
|
||||
{
|
||||
failure("remove group didn't take");
|
||||
exit(get_rv());
|
||||
}
|
||||
gnc_account_remove_child (root2, account1);
|
||||
if (gnc_account_get_parent (account1) != NULL)
|
||||
{
|
||||
failure("remove group didn't take");
|
||||
exit(get_rv());
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
gint i;
|
||||
qof_init();
|
||||
if(cashobjects_register()) {
|
||||
xaccLogDisable ();
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
run_test ();
|
||||
}
|
||||
success ("group/book stuff seems to work");
|
||||
print_test_results();
|
||||
}
|
||||
qof_close();
|
||||
return get_rv();
|
||||
gint i;
|
||||
qof_init();
|
||||
if (cashobjects_register())
|
||||
{
|
||||
xaccLogDisable ();
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
run_test ();
|
||||
}
|
||||
success ("group/book stuff seems to work");
|
||||
print_test_results();
|
||||
}
|
||||
qof_close();
|
||||
return get_rv();
|
||||
}
|
||||
|
||||
@@ -38,62 +38,63 @@
|
||||
|
||||
static void test_null_guid(void)
|
||||
{
|
||||
GUID g;
|
||||
GUID *gp;
|
||||
GUID g;
|
||||
GUID *gp;
|
||||
|
||||
g = guid_new_return();
|
||||
gp = guid_malloc();
|
||||
guid_new(gp);
|
||||
g = guid_new_return();
|
||||
gp = guid_malloc();
|
||||
guid_new(gp);
|
||||
|
||||
do_test(guid_equal(guid_null(), guid_null()), "null guids equal");
|
||||
do_test(!guid_equal(&g, gp), "two guids equal");
|
||||
do_test(guid_equal(guid_null(), guid_null()), "null guids equal");
|
||||
do_test(!guid_equal(&g, gp), "two guids equal");
|
||||
}
|
||||
|
||||
static void
|
||||
run_test (void)
|
||||
{
|
||||
int i;
|
||||
QofSession *sess;
|
||||
QofBook *book;
|
||||
QofInstance *ent, *eblk[NENT];
|
||||
QofCollection *col;
|
||||
QofIdType type;
|
||||
GUID guid;
|
||||
int i;
|
||||
QofSession *sess;
|
||||
QofBook *book;
|
||||
QofInstance *ent, *eblk[NENT];
|
||||
QofCollection *col;
|
||||
QofIdType type;
|
||||
GUID guid;
|
||||
|
||||
sess = get_random_session ();
|
||||
book = qof_session_get_book (sess);
|
||||
do_test ((NULL != book), "book not created");
|
||||
sess = get_random_session ();
|
||||
book = qof_session_get_book (sess);
|
||||
do_test ((NULL != book), "book not created");
|
||||
|
||||
col = qof_book_get_collection (book, "asdf");
|
||||
type = qof_collection_get_type (col);
|
||||
|
||||
for (i=0; i<NENT; i++)
|
||||
{
|
||||
ent = g_object_new(QOF_TYPE_INSTANCE, NULL);
|
||||
eblk[i] = ent;
|
||||
guid_new(&guid);
|
||||
ent = g_object_new(QOF_TYPE_INSTANCE, "guid", &guid, NULL);
|
||||
do_test ((NULL == qof_collection_lookup_entity (col, &guid)),
|
||||
"duplicate guid");
|
||||
ent->e_type = type;
|
||||
qof_collection_insert_entity (col, ent);
|
||||
do_test ((NULL != qof_collection_lookup_entity (col, &guid)),
|
||||
"guid not found");
|
||||
}
|
||||
col = qof_book_get_collection (book, "asdf");
|
||||
type = qof_collection_get_type (col);
|
||||
|
||||
/* Make valgrind happy -- destroy the session. */
|
||||
qof_session_destroy(sess);
|
||||
for (i = 0; i < NENT; i++)
|
||||
{
|
||||
ent = g_object_new(QOF_TYPE_INSTANCE, NULL);
|
||||
eblk[i] = ent;
|
||||
guid_new(&guid);
|
||||
ent = g_object_new(QOF_TYPE_INSTANCE, "guid", &guid, NULL);
|
||||
do_test ((NULL == qof_collection_lookup_entity (col, &guid)),
|
||||
"duplicate guid");
|
||||
ent->e_type = type;
|
||||
qof_collection_insert_entity (col, ent);
|
||||
do_test ((NULL != qof_collection_lookup_entity (col, &guid)),
|
||||
"guid not found");
|
||||
}
|
||||
|
||||
/* Make valgrind happy -- destroy the session. */
|
||||
qof_session_destroy(sess);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
qof_init();
|
||||
if(cashobjects_register()) {
|
||||
test_null_guid();
|
||||
run_test ();
|
||||
print_test_results();
|
||||
}
|
||||
qof_close();
|
||||
return get_rv();
|
||||
qof_init();
|
||||
if (cashobjects_register())
|
||||
{
|
||||
test_null_guid();
|
||||
run_test ();
|
||||
print_test_results();
|
||||
}
|
||||
qof_close();
|
||||
return get_rv();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
int
|
||||
main(int argc, char ** argv)
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -31,17 +31,18 @@
|
||||
static void
|
||||
run_test(void)
|
||||
{
|
||||
do_test(TRUE, "test engine loaded OK");
|
||||
do_test(TRUE, "test engine loaded OK");
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char ** argv)
|
||||
{
|
||||
qof_init();
|
||||
if(cashobjects_register()) {
|
||||
run_test ();
|
||||
print_test_results();
|
||||
}
|
||||
qof_close();
|
||||
return get_rv();
|
||||
qof_init();
|
||||
if (cashobjects_register())
|
||||
{
|
||||
run_test ();
|
||||
print_test_results();
|
||||
}
|
||||
qof_close();
|
||||
return get_rv();
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
/**
|
||||
/**
|
||||
* @file test-lots.c
|
||||
* @brief Minimal test to see if automatic lot scrubbing works.
|
||||
* @author Linas Vepstas <linas@linas.org>
|
||||
@@ -42,30 +42,30 @@ static gint max_iterate = 30;
|
||||
static void
|
||||
run_test (void)
|
||||
{
|
||||
QofSession *sess;
|
||||
QofBook *book;
|
||||
Account *root;
|
||||
QofSession *sess;
|
||||
QofBook *book;
|
||||
Account *root;
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
/* In the first test, we will merely try to see if we can run
|
||||
* without crashing. We don't check to see if data is good. */
|
||||
sess = get_random_session ();
|
||||
book = qof_session_get_book (sess);
|
||||
do_test ((NULL != book), "create random data");
|
||||
/* --------------------------------------------------------- */
|
||||
/* In the first test, we will merely try to see if we can run
|
||||
* without crashing. We don't check to see if data is good. */
|
||||
sess = get_random_session ();
|
||||
book = qof_session_get_book (sess);
|
||||
do_test ((NULL != book), "create random data");
|
||||
|
||||
add_random_transactions_to_book (book, transaction_num);
|
||||
add_random_transactions_to_book (book, transaction_num);
|
||||
|
||||
root = gnc_book_get_root_account (book);
|
||||
xaccAccountTreeScrubLots (root);
|
||||
root = gnc_book_get_root_account (book);
|
||||
xaccAccountTreeScrubLots (root);
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
/* In the second test, we create an account with unrealized gains,
|
||||
* and see if that gets fixed correctly, with the correct balances,
|
||||
* and etc.
|
||||
* XXX not implemented
|
||||
*/
|
||||
success ("automatic lot scrubbing lightly tested and seem to work");
|
||||
qof_session_end (sess);
|
||||
/* --------------------------------------------------------- */
|
||||
/* In the second test, we create an account with unrealized gains,
|
||||
* and see if that gets fixed correctly, with the correct balances,
|
||||
* and etc.
|
||||
* XXX not implemented
|
||||
*/
|
||||
success ("automatic lot scrubbing lightly tested and seem to work");
|
||||
qof_session_end (sess);
|
||||
|
||||
}
|
||||
|
||||
@@ -84,9 +84,10 @@ main (int argc, char **argv)
|
||||
/* Set up a reproducible test-case */
|
||||
srand(0);
|
||||
/* Iterate the test a number of times */
|
||||
for (i=0; i< max_iterate; i++) {
|
||||
for (i = 0; i < max_iterate; i++)
|
||||
{
|
||||
fprintf(stdout, " Lots: %d of %d paired tests . . . \r",
|
||||
(i + 1)*2, max_iterate * 2);
|
||||
(i + 1) * 2, max_iterate * 2);
|
||||
fflush(stdout);
|
||||
run_test ();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,9 +20,9 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
/*
|
||||
* Lightly test the QofObject infrastructure.
|
||||
*/
|
||||
/*
|
||||
* Lightly test the QofObject infrastructure.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
@@ -38,121 +38,134 @@ static const char * printable (gpointer obj);
|
||||
static void test_printable (const char *name, gpointer obj);
|
||||
static void test_foreach (QofBook *, const char *);
|
||||
|
||||
static QofObject bus_obj = {
|
||||
interface_version: QOF_OBJECT_VERSION,
|
||||
e_type: TEST_MODULE_NAME,
|
||||
type_label: TEST_MODULE_DESC,
|
||||
create: NULL,
|
||||
book_begin: NULL,
|
||||
book_end: NULL,
|
||||
is_dirty: NULL,
|
||||
mark_clean: NULL,
|
||||
foreach: obj_foreach,
|
||||
printable: printable,
|
||||
version_cmp: NULL,
|
||||
static QofObject bus_obj =
|
||||
{
|
||||
interface_version:
|
||||
QOF_OBJECT_VERSION,
|
||||
e_type:
|
||||
TEST_MODULE_NAME,
|
||||
type_label:
|
||||
TEST_MODULE_DESC,
|
||||
create:
|
||||
NULL,
|
||||
book_begin:
|
||||
NULL,
|
||||
book_end:
|
||||
NULL,
|
||||
is_dirty:
|
||||
NULL,
|
||||
mark_clean:
|
||||
NULL,
|
||||
foreach:
|
||||
obj_foreach,
|
||||
printable:
|
||||
printable,
|
||||
version_cmp:
|
||||
NULL,
|
||||
};
|
||||
|
||||
static void
|
||||
static void
|
||||
test_object (void)
|
||||
{
|
||||
QofBook *book = qof_book_new();
|
||||
QofBook *book = qof_book_new();
|
||||
|
||||
do_test ((NULL != book), "book null");
|
||||
do_test ((NULL != book), "book null");
|
||||
|
||||
/* Test the global registration and lookup functions */
|
||||
{
|
||||
do_test (!qof_object_register (NULL), "register NULL");
|
||||
do_test (qof_object_register (&bus_obj), "register test object");
|
||||
do_test (!qof_object_register (&bus_obj), "register test object again");
|
||||
do_test (qof_object_lookup (TEST_MODULE_NAME) == &bus_obj,
|
||||
"lookup our installed object");
|
||||
do_test (qof_object_lookup ("snm98sn snml say dyikh9y9ha") == NULL,
|
||||
"lookup non-existant object object");
|
||||
/* Test the global registration and lookup functions */
|
||||
{
|
||||
do_test (!qof_object_register (NULL), "register NULL");
|
||||
do_test (qof_object_register (&bus_obj), "register test object");
|
||||
do_test (!qof_object_register (&bus_obj), "register test object again");
|
||||
do_test (qof_object_lookup (TEST_MODULE_NAME) == &bus_obj,
|
||||
"lookup our installed object");
|
||||
do_test (qof_object_lookup ("snm98sn snml say dyikh9y9ha") == NULL,
|
||||
"lookup non-existant object object");
|
||||
|
||||
do_test (!safe_strcmp (qof_object_get_type_label (TEST_MODULE_NAME),
|
||||
_(TEST_MODULE_DESC)),
|
||||
"test description return");
|
||||
}
|
||||
do_test (!safe_strcmp (qof_object_get_type_label (TEST_MODULE_NAME),
|
||||
_(TEST_MODULE_DESC)),
|
||||
"test description return");
|
||||
}
|
||||
|
||||
test_foreach (book, TEST_MODULE_NAME);
|
||||
test_printable (TEST_MODULE_NAME, (gpointer)1);
|
||||
test_foreach (book, TEST_MODULE_NAME);
|
||||
test_printable (TEST_MODULE_NAME, (gpointer)1);
|
||||
}
|
||||
|
||||
static void
|
||||
obj_foreach (const QofCollection *col, QofInstanceForeachCB cb, gpointer u_d)
|
||||
{
|
||||
int *foo = u_d;
|
||||
int *foo = u_d;
|
||||
|
||||
do_test (col != NULL, "foreach: NULL collection");
|
||||
success ("called foreach callback");
|
||||
do_test (col != NULL, "foreach: NULL collection");
|
||||
success ("called foreach callback");
|
||||
|
||||
*foo = 1;
|
||||
*foo = 1;
|
||||
}
|
||||
|
||||
static void foreachCB (QofInstance *ent, gpointer u_d)
|
||||
{
|
||||
do_test (FALSE, "FAIL");
|
||||
do_test (FALSE, "FAIL");
|
||||
}
|
||||
|
||||
static const char *
|
||||
printable (gpointer obj)
|
||||
{
|
||||
do_test (obj != NULL, "printable: object is NULL");
|
||||
success ("called printable callback");
|
||||
return ((const char *)obj);
|
||||
do_test (obj != NULL, "printable: object is NULL");
|
||||
success ("called printable callback");
|
||||
return ((const char *)obj);
|
||||
}
|
||||
|
||||
static void
|
||||
test_foreach (QofBook *book, const char *name)
|
||||
{
|
||||
int res = 0;
|
||||
int res = 0;
|
||||
|
||||
qof_object_foreach (NULL, NULL, NULL, &res);
|
||||
do_test (res == 0, "object: Foreach: NULL, NULL, NULL");
|
||||
qof_object_foreach (NULL, NULL, foreachCB, &res);
|
||||
do_test (res == 0, "object: Foreach: NULL, NULL, foreachCB");
|
||||
qof_object_foreach (NULL, NULL, NULL, &res);
|
||||
do_test (res == 0, "object: Foreach: NULL, NULL, NULL");
|
||||
qof_object_foreach (NULL, NULL, foreachCB, &res);
|
||||
do_test (res == 0, "object: Foreach: NULL, NULL, foreachCB");
|
||||
|
||||
qof_object_foreach (NULL, book, NULL, &res);
|
||||
do_test (res == 0, "object: Foreach: NULL, book, NULL");
|
||||
qof_object_foreach (NULL, book, foreachCB, &res);
|
||||
do_test (res == 0, "object: Foreach: NULL, book, foreachCB");
|
||||
qof_object_foreach (NULL, book, NULL, &res);
|
||||
do_test (res == 0, "object: Foreach: NULL, book, NULL");
|
||||
qof_object_foreach (NULL, book, foreachCB, &res);
|
||||
do_test (res == 0, "object: Foreach: NULL, book, foreachCB");
|
||||
|
||||
qof_object_foreach (name, NULL, NULL, &res);
|
||||
do_test (res == 0, "object: Foreach: name, NULL, NULL");
|
||||
qof_object_foreach (name, NULL, foreachCB, &res);
|
||||
do_test (res == 0, "object: Foreach: name, NULL, foreachCB");
|
||||
qof_object_foreach (name, NULL, NULL, &res);
|
||||
do_test (res == 0, "object: Foreach: name, NULL, NULL");
|
||||
qof_object_foreach (name, NULL, foreachCB, &res);
|
||||
do_test (res == 0, "object: Foreach: name, NULL, foreachCB");
|
||||
|
||||
qof_object_foreach (name, book, NULL, &res);
|
||||
do_test (res != 0, "object: Foreach: name, book, NULL");
|
||||
qof_object_foreach (name, book, NULL, &res);
|
||||
do_test (res != 0, "object: Foreach: name, book, NULL");
|
||||
|
||||
res = 0;
|
||||
qof_object_foreach (name, book, foreachCB, &res);
|
||||
do_test (res != 0, "object: Foreach: name, book, foreachCB");
|
||||
res = 0;
|
||||
qof_object_foreach (name, book, foreachCB, &res);
|
||||
do_test (res != 0, "object: Foreach: name, book, foreachCB");
|
||||
}
|
||||
|
||||
static void
|
||||
test_printable (const char *name, gpointer obj)
|
||||
{
|
||||
const char *res;
|
||||
const char *res;
|
||||
|
||||
do_test (qof_object_printable (NULL, NULL) == NULL,
|
||||
"object: Printable: NULL, NULL");
|
||||
do_test (qof_object_printable (NULL, obj) == NULL,
|
||||
"object: Printable: NULL, object");
|
||||
do_test (qof_object_printable (name, NULL) == NULL,
|
||||
"object: Printable: mod_name, NULL");
|
||||
res = qof_object_printable (name, obj);
|
||||
do_test (res != NULL, "object: Printable: mod_name, object");
|
||||
do_test (qof_object_printable (NULL, NULL) == NULL,
|
||||
"object: Printable: NULL, NULL");
|
||||
do_test (qof_object_printable (NULL, obj) == NULL,
|
||||
"object: Printable: NULL, object");
|
||||
do_test (qof_object_printable (name, NULL) == NULL,
|
||||
"object: Printable: mod_name, NULL");
|
||||
res = qof_object_printable (name, obj);
|
||||
do_test (res != NULL, "object: Printable: mod_name, object");
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
qof_init();
|
||||
if(cashobjects_register()) {
|
||||
test_object();
|
||||
print_test_results();
|
||||
}
|
||||
qof_close();
|
||||
return get_rv();
|
||||
qof_init();
|
||||
if (cashobjects_register())
|
||||
{
|
||||
test_object();
|
||||
print_test_results();
|
||||
}
|
||||
qof_close();
|
||||
return get_rv();
|
||||
}
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
/*
|
||||
* Minimal test to see if a book can be split into two periods
|
||||
* without crashing.
|
||||
*/
|
||||
/*
|
||||
* Minimal test to see if a book can be split into two periods
|
||||
* without crashing.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <ctype.h>
|
||||
@@ -41,93 +41,93 @@ static int num_trans = 0;
|
||||
static void
|
||||
run_test (void)
|
||||
{
|
||||
QofSession *sess1, *sess2;
|
||||
QofBook *openbook, *closedbook;
|
||||
GList *acclist, *anode;
|
||||
Account *root, *acc, *equity;
|
||||
SplitList *splist;
|
||||
Split *sfirst, *slast;
|
||||
Transaction *tfirst, *tlast;
|
||||
Timespec tsfirst, tslast, tsmiddle;
|
||||
|
||||
sess1 = get_random_session ();
|
||||
openbook = qof_session_get_book (sess1);
|
||||
sess2 = get_random_session ();
|
||||
closedbook = qof_session_get_book(sess2);
|
||||
acc = NULL;
|
||||
equity = get_random_account(openbook);
|
||||
if (!openbook)
|
||||
{
|
||||
failure("book not created");
|
||||
exit(get_rv());
|
||||
}
|
||||
QofSession *sess1, *sess2;
|
||||
QofBook *openbook, *closedbook;
|
||||
GList *acclist, *anode;
|
||||
Account *root, *acc, *equity;
|
||||
SplitList *splist;
|
||||
Split *sfirst, *slast;
|
||||
Transaction *tfirst, *tlast;
|
||||
Timespec tsfirst, tslast, tsmiddle;
|
||||
|
||||
add_random_transactions_to_book (openbook, num_trans);
|
||||
|
||||
root = gnc_book_get_root_account (openbook);
|
||||
|
||||
acclist = gnc_account_get_descendants (root);
|
||||
for (anode=acclist; anode; anode=anode->next)
|
||||
{
|
||||
int ns;
|
||||
acc = anode->data;
|
||||
ns = g_list_length (xaccAccountGetSplitList (acc));
|
||||
if (2 <= ns) break;
|
||||
sess1 = get_random_session ();
|
||||
openbook = qof_session_get_book (sess1);
|
||||
sess2 = get_random_session ();
|
||||
closedbook = qof_session_get_book(sess2);
|
||||
acc = NULL;
|
||||
}
|
||||
g_list_free(acclist);
|
||||
equity = get_random_account(openbook);
|
||||
if (!openbook)
|
||||
{
|
||||
failure("book not created");
|
||||
exit(get_rv());
|
||||
}
|
||||
|
||||
if(!acc)
|
||||
{
|
||||
failure("book didn't have accounts with enough splits");
|
||||
exit(get_rv());
|
||||
}
|
||||
add_random_transactions_to_book (openbook, num_trans);
|
||||
|
||||
splist = xaccAccountGetSplitList(acc);
|
||||
if(!splist)
|
||||
{
|
||||
failure("account has no transactions");
|
||||
exit(get_rv());
|
||||
}
|
||||
root = gnc_book_get_root_account (openbook);
|
||||
|
||||
sfirst = splist->data;
|
||||
slast = g_list_last(splist) ->data;
|
||||
if (sfirst == slast)
|
||||
{
|
||||
failure("account doesn't have enough transactions");
|
||||
exit(get_rv());
|
||||
}
|
||||
acclist = gnc_account_get_descendants (root);
|
||||
for (anode = acclist; anode; anode = anode->next)
|
||||
{
|
||||
int ns;
|
||||
acc = anode->data;
|
||||
ns = g_list_length (xaccAccountGetSplitList (acc));
|
||||
if (2 <= ns) break;
|
||||
acc = NULL;
|
||||
}
|
||||
g_list_free(acclist);
|
||||
|
||||
tfirst = xaccSplitGetParent (sfirst);
|
||||
tlast = xaccSplitGetParent (slast);
|
||||
|
||||
if (!tfirst || !tlast)
|
||||
{
|
||||
failure("malformed transactions in account");
|
||||
exit(get_rv());
|
||||
}
|
||||
if (!acc)
|
||||
{
|
||||
failure("book didn't have accounts with enough splits");
|
||||
exit(get_rv());
|
||||
}
|
||||
|
||||
tsfirst = xaccTransRetDatePostedTS (tfirst);
|
||||
tslast = xaccTransRetDatePostedTS (tlast);
|
||||
splist = xaccAccountGetSplitList(acc);
|
||||
if (!splist)
|
||||
{
|
||||
failure("account has no transactions");
|
||||
exit(get_rv());
|
||||
}
|
||||
|
||||
if (tsfirst.tv_sec == tslast.tv_sec)
|
||||
{
|
||||
failure("transactions not time separated");
|
||||
exit(get_rv());
|
||||
}
|
||||
sfirst = splist->data;
|
||||
slast = g_list_last(splist) ->data;
|
||||
if (sfirst == slast)
|
||||
{
|
||||
failure("account doesn't have enough transactions");
|
||||
exit(get_rv());
|
||||
}
|
||||
|
||||
tsmiddle = tsfirst;
|
||||
tsmiddle.tv_sec = (tsfirst.tv_sec + tslast.tv_sec)/2;
|
||||
closedbook = gnc_book_close_period (openbook, tsmiddle,
|
||||
equity, "this is opening balance dude");
|
||||
tfirst = xaccSplitGetParent (sfirst);
|
||||
tlast = xaccSplitGetParent (slast);
|
||||
|
||||
if (!closedbook)
|
||||
{
|
||||
failure("closed book not created");
|
||||
exit(get_rv());
|
||||
}
|
||||
if (!tfirst || !tlast)
|
||||
{
|
||||
failure("malformed transactions in account");
|
||||
exit(get_rv());
|
||||
}
|
||||
|
||||
success ("periods lightly tested and seem to work");
|
||||
tsfirst = xaccTransRetDatePostedTS (tfirst);
|
||||
tslast = xaccTransRetDatePostedTS (tlast);
|
||||
|
||||
if (tsfirst.tv_sec == tslast.tv_sec)
|
||||
{
|
||||
failure("transactions not time separated");
|
||||
exit(get_rv());
|
||||
}
|
||||
|
||||
tsmiddle = tsfirst;
|
||||
tsmiddle.tv_sec = (tsfirst.tv_sec + tslast.tv_sec) / 2;
|
||||
closedbook = gnc_book_close_period (openbook, tsmiddle,
|
||||
equity, "this is opening balance dude");
|
||||
|
||||
if (!closedbook)
|
||||
{
|
||||
failure("closed book not created");
|
||||
exit(get_rv());
|
||||
}
|
||||
|
||||
success ("periods lightly tested and seem to work");
|
||||
}
|
||||
|
||||
int
|
||||
@@ -140,7 +140,8 @@ main (int argc, char **argv)
|
||||
qof_init();
|
||||
g_log_set_always_fatal( G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING );
|
||||
|
||||
if(cashobjects_register()) {
|
||||
if (cashobjects_register())
|
||||
{
|
||||
srand(num_trans);
|
||||
run_test ();
|
||||
print_test_results();
|
||||
|
||||
@@ -34,80 +34,81 @@
|
||||
static int
|
||||
test_trans_query (Transaction *trans, gpointer data)
|
||||
{
|
||||
QofBook *book = data;
|
||||
GList *list;
|
||||
Query *q;
|
||||
QofBook *book = data;
|
||||
GList *list;
|
||||
Query *q;
|
||||
|
||||
q = make_trans_query (trans, ALL_QT);
|
||||
xaccQuerySetBook (q, book);
|
||||
q = make_trans_query (trans, ALL_QT);
|
||||
xaccQuerySetBook (q, book);
|
||||
|
||||
list = xaccQueryGetTransactions (q, QUERY_TXN_MATCH_ANY);
|
||||
if (g_list_length (list) != 1)
|
||||
{
|
||||
failure_args ("test number returned", __FILE__, __LINE__,
|
||||
"number of matching transactions %d not 1",
|
||||
g_list_length (list));
|
||||
list = xaccQueryGetTransactions (q, QUERY_TXN_MATCH_ANY);
|
||||
if (g_list_length (list) != 1)
|
||||
{
|
||||
failure_args ("test number returned", __FILE__, __LINE__,
|
||||
"number of matching transactions %d not 1",
|
||||
g_list_length (list));
|
||||
g_list_free (list);
|
||||
return 13;
|
||||
}
|
||||
|
||||
if (list->data != trans)
|
||||
{
|
||||
failure ("matching transaction is wrong");
|
||||
g_list_free (list);
|
||||
return 13;
|
||||
}
|
||||
|
||||
success ("found right transaction");
|
||||
xaccFreeQuery (q);
|
||||
g_list_free (list);
|
||||
return 13;
|
||||
}
|
||||
|
||||
if (list->data != trans)
|
||||
{
|
||||
failure ("matching transaction is wrong");
|
||||
g_list_free (list);
|
||||
return 13;
|
||||
}
|
||||
|
||||
success ("found right transaction");
|
||||
xaccFreeQuery (q);
|
||||
g_list_free (list);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
run_test (void)
|
||||
{
|
||||
QofSession *session;
|
||||
Account *root;
|
||||
QofBook *book;
|
||||
QofSession *session;
|
||||
Account *root;
|
||||
QofBook *book;
|
||||
|
||||
session = get_random_session ();
|
||||
book = qof_session_get_book (session);
|
||||
root = gnc_book_get_root_account (book);
|
||||
session = get_random_session ();
|
||||
book = qof_session_get_book (session);
|
||||
root = gnc_book_get_root_account (book);
|
||||
|
||||
add_random_transactions_to_book (book, 20);
|
||||
add_random_transactions_to_book (book, 20);
|
||||
|
||||
xaccAccountTreeForEachTransaction (root, test_trans_query, book);
|
||||
xaccAccountTreeForEachTransaction (root, test_trans_query, book);
|
||||
|
||||
qof_session_end (session);
|
||||
qof_session_end (session);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
qof_init();
|
||||
g_log_set_always_fatal( G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING );
|
||||
qof_init();
|
||||
g_log_set_always_fatal( G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING );
|
||||
|
||||
xaccLogDisable ();
|
||||
xaccLogDisable ();
|
||||
|
||||
/* Always start from the same random seed so we fail consistently */
|
||||
srand(0);
|
||||
if(!cashobjects_register()) {
|
||||
failure("can't register cashbojects");
|
||||
goto cleanup;
|
||||
}
|
||||
/* Always start from the same random seed so we fail consistently */
|
||||
srand(0);
|
||||
if (!cashobjects_register())
|
||||
{
|
||||
failure("can't register cashbojects");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Loop the test. */
|
||||
for (i=0; i < 10; i++)
|
||||
{
|
||||
run_test ();
|
||||
}
|
||||
success("queries seem to work");
|
||||
/* Loop the test. */
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
run_test ();
|
||||
}
|
||||
success("queries seem to work");
|
||||
|
||||
cleanup:
|
||||
qof_close();
|
||||
return get_rv();
|
||||
cleanup:
|
||||
qof_close();
|
||||
return get_rv();
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
@@ -35,49 +35,50 @@
|
||||
|
||||
static int test_sort (gpointer a, gpointer b)
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_core_param (gpointer a)
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test_class (void)
|
||||
{
|
||||
static QofParam params[] = {
|
||||
{ TEST_PARAM, TEST_CORE, (QofAccessFunc)test_core_param, NULL },
|
||||
{ NULL },
|
||||
};
|
||||
static QofParam params[] =
|
||||
{
|
||||
{ TEST_PARAM, TEST_CORE, (QofAccessFunc)test_core_param, NULL },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
fprintf (stderr, "\tTesting the qof_query_object interface. \n"
|
||||
"\tYou may see some \"** CRITICAL **\" messages, which you can safely ignore\n");
|
||||
fprintf (stderr, "\tTesting the qof_query_object interface. \n"
|
||||
"\tYou may see some \"** CRITICAL **\" messages, which you can safely ignore\n");
|
||||
|
||||
qof_class_register (TEST_MODULE_NAME, (QofSortFunc)test_sort, params);
|
||||
qof_class_register (TEST_MODULE_NAME, (QofSortFunc)test_sort, params);
|
||||
|
||||
do_test (qof_class_get_parameter (TEST_MODULE_NAME, TEST_PARAM)
|
||||
== ¶ms[0], "qof_class_get_parameter");
|
||||
do_test (qof_class_get_parameter (NULL, NULL) == NULL,
|
||||
"qof_class_get_parameter (NULL, NULL)");
|
||||
do_test (qof_class_get_parameter (TEST_MODULE_NAME, NULL) == NULL,
|
||||
"qof_class_get_parameter (TEST_MODULE_NAME, NULL)");
|
||||
do_test (qof_class_get_parameter (TEST_MODULE_NAME, BAD_PARAM) == NULL,
|
||||
"qof_class_get_parameter (TEST_MODULE_NAME, BAD_PARAM)");
|
||||
do_test (qof_class_get_parameter (NULL, TEST_PARAM) == NULL,
|
||||
"qof_class_get_parameter (NULL, TEST_PARAM)");
|
||||
do_test (qof_class_get_parameter (TEST_MODULE_NAME, TEST_PARAM)
|
||||
== ¶ms[0], "qof_class_get_parameter");
|
||||
do_test (qof_class_get_parameter (NULL, NULL) == NULL,
|
||||
"qof_class_get_parameter (NULL, NULL)");
|
||||
do_test (qof_class_get_parameter (TEST_MODULE_NAME, NULL) == NULL,
|
||||
"qof_class_get_parameter (TEST_MODULE_NAME, NULL)");
|
||||
do_test (qof_class_get_parameter (TEST_MODULE_NAME, BAD_PARAM) == NULL,
|
||||
"qof_class_get_parameter (TEST_MODULE_NAME, BAD_PARAM)");
|
||||
do_test (qof_class_get_parameter (NULL, TEST_PARAM) == NULL,
|
||||
"qof_class_get_parameter (NULL, TEST_PARAM)");
|
||||
|
||||
do_test (qof_class_get_parameter_getter (TEST_MODULE_NAME, TEST_PARAM)
|
||||
== (QofAccessFunc)test_core_param,
|
||||
"qof_class_get_parameter_getter");
|
||||
do_test (qof_class_get_parameter_getter (TEST_MODULE_NAME, TEST_PARAM)
|
||||
== (QofAccessFunc)test_core_param,
|
||||
"qof_class_get_parameter_getter");
|
||||
|
||||
do_test (safe_strcmp (qof_class_get_parameter_type (TEST_MODULE_NAME,
|
||||
TEST_PARAM),
|
||||
TEST_CORE) == 0, "qof_class_get_parameter_type");
|
||||
do_test (safe_strcmp (qof_class_get_parameter_type (TEST_MODULE_NAME,
|
||||
TEST_PARAM),
|
||||
TEST_CORE) == 0, "qof_class_get_parameter_type");
|
||||
|
||||
/* do_test (qof_class_get_default_sort (TEST_MODULE_NAME) == test_sort,
|
||||
"qof_class_get_default_sort");
|
||||
do_test (qof_class_get_default_sort (NULL) == NULL,
|
||||
"qof_class_get_default_sort (NULL)");*/
|
||||
/* do_test (qof_class_get_default_sort (TEST_MODULE_NAME) == test_sort,
|
||||
"qof_class_get_default_sort");
|
||||
do_test (qof_class_get_default_sort (NULL) == NULL,
|
||||
"qof_class_get_default_sort (NULL)");*/
|
||||
}
|
||||
|
||||
static void test_query_core (void)
|
||||
@@ -92,13 +93,14 @@ static void test_querynew (void)
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
qof_init();
|
||||
if(cashobjects_register()) {
|
||||
test_query_core();
|
||||
test_class();
|
||||
test_querynew();
|
||||
}
|
||||
qof_close();
|
||||
print_test_results();
|
||||
return get_rv();
|
||||
qof_init();
|
||||
if (cashobjects_register())
|
||||
{
|
||||
test_query_core();
|
||||
test_class();
|
||||
test_querynew();
|
||||
}
|
||||
qof_close();
|
||||
print_test_results();
|
||||
return get_rv();
|
||||
}
|
||||
|
||||
@@ -51,7 +51,8 @@ static void check_valid(GDate *next, GDate *ref, GDate *start,
|
||||
startToNext = g_date_get_julian(next) - g_date_get_julian(start);
|
||||
|
||||
// Phase test
|
||||
switch (pt) {
|
||||
switch (pt)
|
||||
{
|
||||
case PERIOD_YEAR:
|
||||
do_test((g_date_get_year(next) - g_date_get_year(start)) % mult == 0,
|
||||
"year period phase wrong"); // redundant
|
||||
@@ -63,21 +64,23 @@ static void check_valid(GDate *next, GDate *ref, GDate *start,
|
||||
// fall-through
|
||||
case PERIOD_LAST_WEEKDAY:
|
||||
case PERIOD_NTH_WEEKDAY:
|
||||
case PERIOD_MONTH: {
|
||||
case PERIOD_MONTH:
|
||||
{
|
||||
gint monthdiff;
|
||||
GDateDay day_start, day_next;
|
||||
|
||||
monthdiff = (g_date_get_month(next) - g_date_get_month(start)) +
|
||||
12 * (g_date_get_year(next) - g_date_get_year(start));
|
||||
12 * (g_date_get_year(next) - g_date_get_year(start));
|
||||
do_test(monthdiff % mult == 0, "month or year phase wrong");
|
||||
|
||||
if (pt == PERIOD_NTH_WEEKDAY || pt == PERIOD_LAST_WEEKDAY) {
|
||||
if (pt == PERIOD_NTH_WEEKDAY || pt == PERIOD_LAST_WEEKDAY)
|
||||
{
|
||||
guint sweek, nweek;
|
||||
|
||||
do_test(g_date_get_weekday(next) == g_date_get_weekday(start),
|
||||
"weekday phase wrong");
|
||||
sweek = (g_date_get_day(start)-1) / 7;
|
||||
nweek = (g_date_get_day(next)-1) / 7;
|
||||
sweek = (g_date_get_day(start) - 1) / 7;
|
||||
nweek = (g_date_get_day(next) - 1) / 7;
|
||||
|
||||
/* 3 cases: either the weeks agree, OR 'next' didn't have
|
||||
5 of the weekday that 'start' did, so it's only the
|
||||
@@ -86,17 +89,20 @@ static void check_valid(GDate *next, GDate *ref, GDate *start,
|
||||
5th of that weekday */
|
||||
do_test(sweek == nweek ||
|
||||
(sweek == 4 && nweek == 3 && (g_date_get_day(next) + 7) >
|
||||
g_date_get_days_in_month(
|
||||
g_date_get_month(next), g_date_get_year(next))) ||
|
||||
g_date_get_days_in_month(
|
||||
g_date_get_month(next), g_date_get_year(next))) ||
|
||||
(sweek == 3 && nweek == 4 && (pt == PERIOD_LAST_WEEKDAY)),
|
||||
"week of month phase wrong");
|
||||
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
day_start = g_date_get_day(start);
|
||||
day_next = g_date_get_day(next);
|
||||
if (day_start < 28)
|
||||
do_test(day_start == day_next, "dom don't match");
|
||||
else if (pt != PERIOD_END_OF_MONTH) {
|
||||
else if (pt != PERIOD_END_OF_MONTH)
|
||||
{
|
||||
// the end of month case was already checked above. near
|
||||
// the end of the month, the days should still agree,
|
||||
// unless they can't because of a short month.
|
||||
@@ -105,7 +111,7 @@ static void check_valid(GDate *next, GDate *ref, GDate *start,
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case PERIOD_WEEK:
|
||||
mult *= 7;
|
||||
// fall-through
|
||||
@@ -140,15 +146,20 @@ static void test_all()
|
||||
gint32 j1, j2;
|
||||
gint i_ref;
|
||||
|
||||
for (pt = PERIOD_ONCE; pt < NUM_PERIOD_TYPES; pt++) {
|
||||
for (wadj = WEEKEND_ADJ_NONE; wadj < NUM_WEEKEND_ADJS; wadj++) {
|
||||
for (j1 = JULIAN_START; j1 < JULIAN_START + NUM_DATES_TO_TEST; j1++) {
|
||||
for (pt = PERIOD_ONCE; pt < NUM_PERIOD_TYPES; pt++)
|
||||
{
|
||||
for (wadj = WEEKEND_ADJ_NONE; wadj < NUM_WEEKEND_ADJS; wadj++)
|
||||
{
|
||||
for (j1 = JULIAN_START; j1 < JULIAN_START + NUM_DATES_TO_TEST; j1++)
|
||||
{
|
||||
g_date_set_julian(&d_start, j1);
|
||||
for (i_ref = 0; i_ref < NUM_DATES_TO_TEST_REF; i_ref++) {
|
||||
for (i_ref = 0; i_ref < NUM_DATES_TO_TEST_REF; i_ref++)
|
||||
{
|
||||
j2 = (guint32) get_random_int_in_range(1, 1 << 19);
|
||||
g_date_set_julian(&d_ref, j2);
|
||||
|
||||
for (mult = 0; mult < NUM_MULT_TO_TEST; mult++) {
|
||||
for (mult = 0; mult < NUM_MULT_TO_TEST; mult++)
|
||||
{
|
||||
recurrenceSet(&r, mult, pt, &d_start, wadj);
|
||||
pt_reg = recurrenceGetPeriodType(&r);
|
||||
d_start_reg = recurrenceGetDate(&r);
|
||||
@@ -160,7 +171,7 @@ static void test_all()
|
||||
mult_reg, pt_reg, wadj_reg);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -168,7 +179,8 @@ static void test_all()
|
||||
|
||||
static gboolean test_equal(GDate *d1, GDate *d2)
|
||||
{
|
||||
if (!do_test(g_date_compare(d1, d2) == 0, "dates don't match")) {
|
||||
if (!do_test(g_date_compare(d1, d2) == 0, "dates don't match"))
|
||||
{
|
||||
gchar s1[21];
|
||||
gchar s2[21];
|
||||
g_date_strftime(s1, 20, "%x", d1);
|
||||
@@ -199,7 +211,8 @@ static void test_specific(PeriodType pt, guint16 mult,
|
||||
recurrenceNextInstance(&r, &ref, &next);
|
||||
|
||||
check_valid(&next, &ref, &start, mult, pt, WEEKEND_ADJ_NONE);
|
||||
if (!test_equal(&next, &true_next)) {
|
||||
if (!test_equal(&next, &true_next))
|
||||
{
|
||||
gchar s1[21], s2[21], s3[21];
|
||||
g_date_strftime(s1, 20, "%x", &start);
|
||||
g_date_strftime(s2, 20, "%x", &ref);
|
||||
@@ -226,89 +239,89 @@ static void test_nth(GDateMonth sm, GDateDay sd, GDateYear sy,
|
||||
|
||||
static void test_nth_compare()
|
||||
{
|
||||
test_nth(4,1,2005, 4,2,2005, -1, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,1,2005, 4,4,2005, -3, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,1,2005, 4,7,2005, -6, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,1,2005, 4,8,2005, -7, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,1,2005, 4,14,2005, -13, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,1,2005, 4,30,2005, -29, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,1,2005, 5,1,2005, 5, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,1,2005, 5,5,2005, 1, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,1,2005, 5,6,2005, 0, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,1,2005, 5,7,2005, -1, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,1,2005, 5,8,2005, -2, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,1,2005, 5,21,2005, -15, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 1, 2005, 4, 2, 2005, -1, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 1, 2005, 4, 4, 2005, -3, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 1, 2005, 4, 7, 2005, -6, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 1, 2005, 4, 8, 2005, -7, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 1, 2005, 4, 14, 2005, -13, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 1, 2005, 4, 30, 2005, -29, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 1, 2005, 5, 1, 2005, 5, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 1, 2005, 5, 5, 2005, 1, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 1, 2005, 5, 6, 2005, 0, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 1, 2005, 5, 7, 2005, -1, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 1, 2005, 5, 8, 2005, -2, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 1, 2005, 5, 21, 2005, -15, PERIOD_NTH_WEEKDAY);
|
||||
|
||||
|
||||
test_nth(4,6,2005, 4,1,2005, 5, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,6,2005, 4,4,2005, 2, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,6,2005, 4,6,2005, 0, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,6,2005, 4,9,2005, -3, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,6,2005, 4,11,2005, -5, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,6,2005, 4,13,2005, -7, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,6,2005, 4,14,2005, -8, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,6,2005, 4,29,2005, -23, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 6, 2005, 4, 1, 2005, 5, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 6, 2005, 4, 4, 2005, 2, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 6, 2005, 4, 6, 2005, 0, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 6, 2005, 4, 9, 2005, -3, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 6, 2005, 4, 11, 2005, -5, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 6, 2005, 4, 13, 2005, -7, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 6, 2005, 4, 14, 2005, -8, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 6, 2005, 4, 29, 2005, -23, PERIOD_NTH_WEEKDAY);
|
||||
|
||||
test_nth(4,12,2005, 4,1,2005, 11, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,12,2005, 4,4,2005, 8, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,12,2005, 4,11,2005, 1, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,12,2005, 4,12,2005, 0, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,12,2005, 4,13,2005, -1, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,12,2005, 4,17,2005, -5, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,12,2005, 4,19,2005, -7, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4,12,2005, 4,28,2005, -16, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 12, 2005, 4, 1, 2005, 11, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 12, 2005, 4, 4, 2005, 8, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 12, 2005, 4, 11, 2005, 1, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 12, 2005, 4, 12, 2005, 0, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 12, 2005, 4, 13, 2005, -1, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 12, 2005, 4, 17, 2005, -5, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 12, 2005, 4, 19, 2005, -7, PERIOD_NTH_WEEKDAY);
|
||||
test_nth(4, 12, 2005, 4, 28, 2005, -16, PERIOD_NTH_WEEKDAY);
|
||||
|
||||
test_nth(4,29,2005, 4,30,2005, -1, PERIOD_LAST_WEEKDAY);
|
||||
test_nth(4,29,2005, 5,1,2005, 26, PERIOD_LAST_WEEKDAY);
|
||||
test_nth(4,29,2005, 7,9,2005, 20, PERIOD_LAST_WEEKDAY);
|
||||
test_nth(4,29,2005, 7,31,2005, -2, PERIOD_LAST_WEEKDAY);
|
||||
test_nth(4, 29, 2005, 4, 30, 2005, -1, PERIOD_LAST_WEEKDAY);
|
||||
test_nth(4, 29, 2005, 5, 1, 2005, 26, PERIOD_LAST_WEEKDAY);
|
||||
test_nth(4, 29, 2005, 7, 9, 2005, 20, PERIOD_LAST_WEEKDAY);
|
||||
test_nth(4, 29, 2005, 7, 31, 2005, -2, PERIOD_LAST_WEEKDAY);
|
||||
|
||||
test_nth(4,28,2005, 4,30,2005, -2, PERIOD_LAST_WEEKDAY);
|
||||
test_nth(4,28,2005, 5,1,2005, 25, PERIOD_LAST_WEEKDAY);
|
||||
test_nth(4,28,2005, 7,9,2005, 19, PERIOD_LAST_WEEKDAY);
|
||||
test_nth(4,28,2005, 7,31,2005, -3, PERIOD_LAST_WEEKDAY);
|
||||
test_nth(4,28,2005, 9,21,2005, 8, PERIOD_LAST_WEEKDAY);
|
||||
test_nth(4, 28, 2005, 4, 30, 2005, -2, PERIOD_LAST_WEEKDAY);
|
||||
test_nth(4, 28, 2005, 5, 1, 2005, 25, PERIOD_LAST_WEEKDAY);
|
||||
test_nth(4, 28, 2005, 7, 9, 2005, 19, PERIOD_LAST_WEEKDAY);
|
||||
test_nth(4, 28, 2005, 7, 31, 2005, -3, PERIOD_LAST_WEEKDAY);
|
||||
test_nth(4, 28, 2005, 9, 21, 2005, 8, PERIOD_LAST_WEEKDAY);
|
||||
|
||||
}
|
||||
#endif
|
||||
static void test_some()
|
||||
{
|
||||
test_specific(PERIOD_NTH_WEEKDAY, 1, 4,1,2005, 4,2,2005, 5,6,2005);
|
||||
test_specific(PERIOD_NTH_WEEKDAY, 1, 7,14,2005, 11,15,2005, 12,8,2005);
|
||||
test_specific(PERIOD_NTH_WEEKDAY, 1, 7,14,2005, 11,5,2005, 11,10,2005);
|
||||
test_specific(PERIOD_NTH_WEEKDAY, 1, 4,1,2005, 4,2,2005, 5,6,2005);
|
||||
test_specific(PERIOD_NTH_WEEKDAY, 1, 4,1,2005, 4,2,2005, 5,6,2005);
|
||||
test_specific(PERIOD_NTH_WEEKDAY, 1, 4, 1, 2005, 4, 2, 2005, 5, 6, 2005);
|
||||
test_specific(PERIOD_NTH_WEEKDAY, 1, 7, 14, 2005, 11, 15, 2005, 12, 8, 2005);
|
||||
test_specific(PERIOD_NTH_WEEKDAY, 1, 7, 14, 2005, 11, 5, 2005, 11, 10, 2005);
|
||||
test_specific(PERIOD_NTH_WEEKDAY, 1, 4, 1, 2005, 4, 2, 2005, 5, 6, 2005);
|
||||
test_specific(PERIOD_NTH_WEEKDAY, 1, 4, 1, 2005, 4, 2, 2005, 5, 6, 2005);
|
||||
|
||||
test_specific(PERIOD_LAST_WEEKDAY, 1, 4,29,2005, 4,30,2005, 5,27,2005);
|
||||
test_specific(PERIOD_LAST_WEEKDAY, 1, 4,29,2005, 5,1,2005, 5,27,2005);
|
||||
test_specific(PERIOD_LAST_WEEKDAY, 1, 4,29,2005, 7,9,2005, 7,29,2005);
|
||||
test_specific(PERIOD_LAST_WEEKDAY, 1, 4,29,2005, 6,30,2005, 7,29,2005);
|
||||
test_specific(PERIOD_LAST_WEEKDAY, 1, 4,29,2005, 7,31,2005, 8,26,2005);
|
||||
test_specific(PERIOD_LAST_WEEKDAY, 1, 4, 29, 2005, 4, 30, 2005, 5, 27, 2005);
|
||||
test_specific(PERIOD_LAST_WEEKDAY, 1, 4, 29, 2005, 5, 1, 2005, 5, 27, 2005);
|
||||
test_specific(PERIOD_LAST_WEEKDAY, 1, 4, 29, 2005, 7, 9, 2005, 7, 29, 2005);
|
||||
test_specific(PERIOD_LAST_WEEKDAY, 1, 4, 29, 2005, 6, 30, 2005, 7, 29, 2005);
|
||||
test_specific(PERIOD_LAST_WEEKDAY, 1, 4, 29, 2005, 7, 31, 2005, 8, 26, 2005);
|
||||
|
||||
test_specific(PERIOD_NTH_WEEKDAY, 2, 4,27,2005, 4,27,2005, 6,22,2005);
|
||||
test_specific(PERIOD_NTH_WEEKDAY, 2, 4, 27, 2005, 4, 27, 2005, 6, 22, 2005);
|
||||
//exit(1);
|
||||
//return;
|
||||
test_specific(PERIOD_YEAR, 3, 9,8,838, 6,30,1094, 9,8,1096);
|
||||
test_specific(PERIOD_YEAR, 2, 9,8,838, 6,30,1094, 9,8,1094);
|
||||
test_specific(PERIOD_YEAR, 1, 1,10,1000, 1,5,1002, 1,10,1002);
|
||||
test_specific(PERIOD_YEAR, 3, 9, 8, 838, 6, 30, 1094, 9, 8, 1096);
|
||||
test_specific(PERIOD_YEAR, 2, 9, 8, 838, 6, 30, 1094, 9, 8, 1094);
|
||||
test_specific(PERIOD_YEAR, 1, 1, 10, 1000, 1, 5, 1002, 1, 10, 1002);
|
||||
//return;
|
||||
test_specific(PERIOD_MONTH, 1, 1,12,1, 2,6,1, 2,12,1);
|
||||
test_specific(PERIOD_MONTH, 1, 1, 12, 1, 2, 6, 1, 2, 12, 1);
|
||||
|
||||
test_specific(PERIOD_MONTH, 1, 1,12,1, 2,12,1, 3,12,1);
|
||||
test_specific(PERIOD_MONTH, 1, 1,12,1, 2,20,1, 3,12,1);
|
||||
test_specific(PERIOD_MONTH, 1, 1,30,1, 2,28,1, 3,30,1);
|
||||
test_specific(PERIOD_MONTH, 1, 1,30,1, 2,27,1, 2,28,1);
|
||||
test_specific(PERIOD_MONTH, 1, 2,28,1, 3,30,1, 4,28,1);
|
||||
test_specific(PERIOD_MONTH, 1, 1, 12, 1, 2, 12, 1, 3, 12, 1);
|
||||
test_specific(PERIOD_MONTH, 1, 1, 12, 1, 2, 20, 1, 3, 12, 1);
|
||||
test_specific(PERIOD_MONTH, 1, 1, 30, 1, 2, 28, 1, 3, 30, 1);
|
||||
test_specific(PERIOD_MONTH, 1, 1, 30, 1, 2, 27, 1, 2, 28, 1);
|
||||
test_specific(PERIOD_MONTH, 1, 2, 28, 1, 3, 30, 1, 4, 28, 1);
|
||||
|
||||
test_specific(PERIOD_END_OF_MONTH, 1, 2,28,1, 3,30,1, 3,31,1);
|
||||
test_specific(PERIOD_END_OF_MONTH, 5, 4,30,1, 4,21,1, 4,30,1);
|
||||
test_specific(PERIOD_END_OF_MONTH, 5, 2,28,1, 5,21,1, 7,31,1);
|
||||
test_specific(PERIOD_END_OF_MONTH, 1, 2, 28, 1, 3, 30, 1, 3, 31, 1);
|
||||
test_specific(PERIOD_END_OF_MONTH, 5, 4, 30, 1, 4, 21, 1, 4, 30, 1);
|
||||
test_specific(PERIOD_END_OF_MONTH, 5, 2, 28, 1, 5, 21, 1, 7, 31, 1);
|
||||
|
||||
test_specific(PERIOD_YEAR, 7, 6,8,199, 9,10,1338, 6,8,1340);
|
||||
test_specific(PERIOD_YEAR, 2, 9,8,838, 6,30,1094, 9,8,1094);
|
||||
test_specific(PERIOD_YEAR, 7, 6, 8, 199, 9, 10, 1338, 6, 8, 1340);
|
||||
test_specific(PERIOD_YEAR, 2, 9, 8, 838, 6, 30, 1094, 9, 8, 1094);
|
||||
|
||||
test_specific(PERIOD_YEAR,1, 5,2,13, 1,11,101, 5,2,101);
|
||||
test_specific(PERIOD_DAY, 7, 4,1,2000, 4,8,2000, 4,15,2000);
|
||||
test_specific(PERIOD_YEAR, 1, 5, 2, 13, 1, 11, 101, 5, 2, 101);
|
||||
test_specific(PERIOD_DAY, 7, 4, 1, 2000, 4, 8, 2000, 4, 15, 2000);
|
||||
}
|
||||
|
||||
static void test_use()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -39,15 +39,24 @@ struct test_strings_struct
|
||||
|
||||
typedef struct test_strings_struct test_strings;
|
||||
|
||||
test_strings strs[] = {
|
||||
{ G_DIR_SEPARATOR_S ".gnucash" G_DIR_SEPARATOR_S "test-account-name",
|
||||
G_DIR_SEPARATOR_S ".gnucash" G_DIR_SEPARATOR_S "test-account-name", 1 },
|
||||
{ G_DIR_SEPARATOR_S "tmp" G_DIR_SEPARATOR_S "test-account-name2",
|
||||
G_DIR_SEPARATOR_S "tmp" G_DIR_SEPARATOR_S "test-account-name2", 0 },
|
||||
{ "postgres://localhost/foo/bar",
|
||||
G_DIR_SEPARATOR_S ".gnucash" G_DIR_SEPARATOR_S "data" G_DIR_SEPARATOR_S "postgres___localhost_foo_bar", 2 },
|
||||
{ "file:" G_DIR_SEPARATOR_S "tmp" G_DIR_SEPARATOR_S "test-account-name3",
|
||||
G_DIR_SEPARATOR_S "tmp" G_DIR_SEPARATOR_S "test-account-name3", 0 },
|
||||
test_strings strs[] =
|
||||
{
|
||||
{
|
||||
G_DIR_SEPARATOR_S ".gnucash" G_DIR_SEPARATOR_S "test-account-name",
|
||||
G_DIR_SEPARATOR_S ".gnucash" G_DIR_SEPARATOR_S "test-account-name", 1
|
||||
},
|
||||
{
|
||||
G_DIR_SEPARATOR_S "tmp" G_DIR_SEPARATOR_S "test-account-name2",
|
||||
G_DIR_SEPARATOR_S "tmp" G_DIR_SEPARATOR_S "test-account-name2", 0
|
||||
},
|
||||
{
|
||||
"postgres://localhost/foo/bar",
|
||||
G_DIR_SEPARATOR_S ".gnucash" G_DIR_SEPARATOR_S "data" G_DIR_SEPARATOR_S "postgres___localhost_foo_bar", 2
|
||||
},
|
||||
{
|
||||
"file:" G_DIR_SEPARATOR_S "tmp" G_DIR_SEPARATOR_S "test-account-name3",
|
||||
G_DIR_SEPARATOR_S "tmp" G_DIR_SEPARATOR_S "test-account-name3", 0
|
||||
},
|
||||
{ NULL, NULL, 0 },
|
||||
};
|
||||
|
||||
@@ -58,26 +67,26 @@ main(int argc, char **argv)
|
||||
|
||||
qof_init();
|
||||
|
||||
for(i = 0; strs[i].input != NULL; i++)
|
||||
for (i = 0; strs[i].input != NULL; i++)
|
||||
{
|
||||
char *daout;
|
||||
char *dain;
|
||||
char *wantout;
|
||||
|
||||
if(strs[i].prefix_home == 1)
|
||||
|
||||
if (strs[i].prefix_home == 1)
|
||||
{
|
||||
dain = g_build_filename(g_get_home_dir(), strs[i].input,
|
||||
(gchar *)NULL);
|
||||
(gchar *)NULL);
|
||||
wantout = g_build_filename(g_get_home_dir(), strs[i].output,
|
||||
(gchar *)NULL);
|
||||
(gchar *)NULL);
|
||||
}
|
||||
else if(strs[i].prefix_home == 2)
|
||||
else if (strs[i].prefix_home == 2)
|
||||
{
|
||||
dain = g_strdup(strs[i].input);
|
||||
wantout = g_build_filename(g_get_home_dir(), strs[i].output,
|
||||
(gchar *)NULL);
|
||||
(gchar *)NULL);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
dain = g_strdup(strs[i].input);
|
||||
wantout = g_strdup(strs[i].output);
|
||||
|
||||
@@ -14,71 +14,71 @@
|
||||
static void
|
||||
test_query (Query *q)
|
||||
{
|
||||
SCM scm_q;
|
||||
Query *q2;
|
||||
SCM scm_q;
|
||||
Query *q2;
|
||||
|
||||
scm_q = gnc_query2scm (q);
|
||||
scm_q = gnc_query2scm (q);
|
||||
|
||||
q2 = gnc_scm2query (scm_q);
|
||||
q2 = gnc_scm2query (scm_q);
|
||||
|
||||
if (!xaccQueryEqual (q, q2))
|
||||
{
|
||||
failure ("queries don't match");
|
||||
scm_display (scm_q, SCM_UNDEFINED);
|
||||
scm_newline (SCM_UNDEFINED);
|
||||
scm_q = gnc_query2scm (q2);
|
||||
scm_display (scm_q, SCM_UNDEFINED);
|
||||
scm_newline (SCM_UNDEFINED);
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
success ("queries match");
|
||||
}
|
||||
if (!xaccQueryEqual (q, q2))
|
||||
{
|
||||
failure ("queries don't match");
|
||||
scm_display (scm_q, SCM_UNDEFINED);
|
||||
scm_newline (SCM_UNDEFINED);
|
||||
scm_q = gnc_query2scm (q2);
|
||||
scm_display (scm_q, SCM_UNDEFINED);
|
||||
scm_newline (SCM_UNDEFINED);
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
success ("queries match");
|
||||
}
|
||||
|
||||
xaccFreeQuery (q2);
|
||||
xaccFreeQuery (q2);
|
||||
}
|
||||
|
||||
static void
|
||||
run_tests (void)
|
||||
{
|
||||
Query *q;
|
||||
int i;
|
||||
Query *q;
|
||||
int i;
|
||||
|
||||
test_query (NULL);
|
||||
test_query (NULL);
|
||||
|
||||
q = xaccMallocQuery ();
|
||||
test_query (q);
|
||||
xaccFreeQuery (q);
|
||||
|
||||
for (i = 0; i < 50; i++)
|
||||
{
|
||||
q = get_random_query ();
|
||||
q = xaccMallocQuery ();
|
||||
test_query (q);
|
||||
xaccFreeQuery (q);
|
||||
}
|
||||
|
||||
for (i = 0; i < 50; i++)
|
||||
{
|
||||
q = get_random_query ();
|
||||
test_query (q);
|
||||
xaccFreeQuery (q);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
main_helper (void *closure, int argc, char **argv)
|
||||
{
|
||||
gnc_module_load("gnucash/engine", 0);
|
||||
gnc_module_load("gnucash/engine", 0);
|
||||
|
||||
xaccLogDisable ();
|
||||
xaccLogDisable ();
|
||||
|
||||
/* scm conversion doesn't handle binary atm */
|
||||
kvp_exclude_type (KVP_TYPE_BINARY);
|
||||
/* scm conversion doesn't handle binary atm */
|
||||
kvp_exclude_type (KVP_TYPE_BINARY);
|
||||
|
||||
run_tests ();
|
||||
run_tests ();
|
||||
|
||||
print_test_results ();
|
||||
print_test_results ();
|
||||
|
||||
exit (get_rv ());
|
||||
exit (get_rv ());
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
scm_boot_guile (argc, argv, main_helper, NULL);
|
||||
return 0;
|
||||
scm_boot_guile (argc, argv, main_helper, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -65,7 +65,8 @@ int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
qof_init();
|
||||
if(cashobjects_register()) {
|
||||
if (cashobjects_register())
|
||||
{
|
||||
xaccLogDisable ();
|
||||
run_test ();
|
||||
print_test_results();
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
@@ -37,91 +37,93 @@
|
||||
static void
|
||||
transaction_set_splits_to_accounts(Transaction *tr, Account *a1, Account *a2)
|
||||
{
|
||||
Split *split;
|
||||
Split *split;
|
||||
|
||||
split = xaccTransGetSplit(tr, 0);
|
||||
|
||||
xaccAccountInsertSplit(a1, split);
|
||||
split = xaccTransGetSplit(tr, 0);
|
||||
|
||||
split = xaccTransGetSplit(tr, 1);
|
||||
xaccAccountInsertSplit(a2, split);
|
||||
return;
|
||||
xaccAccountInsertSplit(a1, split);
|
||||
|
||||
split = xaccTransGetSplit(tr, 1);
|
||||
xaccAccountInsertSplit(a2, split);
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
run_test (void)
|
||||
{
|
||||
Account *acc1, *acc2;
|
||||
Transaction *transaction, *new_trans;
|
||||
gnc_numeric old, new, result;
|
||||
QofBook *book;
|
||||
char *msg;
|
||||
int i;
|
||||
Account *acc1, *acc2;
|
||||
Transaction *transaction, *new_trans;
|
||||
gnc_numeric old, new, result;
|
||||
QofBook *book;
|
||||
char *msg;
|
||||
int i;
|
||||
|
||||
book = qof_book_new();
|
||||
book = qof_book_new();
|
||||
|
||||
acc1 = get_random_account(book);
|
||||
acc2 = get_random_account(book);
|
||||
acc1 = get_random_account(book);
|
||||
acc2 = get_random_account(book);
|
||||
|
||||
if (!acc1 || !acc2)
|
||||
{
|
||||
failure("accounts not created");
|
||||
if (!acc1 || !acc2)
|
||||
{
|
||||
failure("accounts not created");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find a transaction that isn't voided */
|
||||
do
|
||||
{
|
||||
gboolean voyd;
|
||||
|
||||
transaction = get_random_transaction (book);
|
||||
voyd = xaccTransGetVoidStatus (transaction);
|
||||
if (voyd)
|
||||
{
|
||||
xaccTransBeginEdit (transaction);
|
||||
xaccTransDestroy (transaction);
|
||||
xaccTransCommitEdit (transaction);
|
||||
transaction = NULL;
|
||||
}
|
||||
}
|
||||
while (!transaction);
|
||||
transaction_set_splits_to_accounts(transaction, acc1, acc2);
|
||||
xaccTransSortSplits(transaction);
|
||||
|
||||
new_trans = xaccTransReverse(transaction);
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
old = xaccSplitGetAmount(xaccTransGetSplit(transaction, i));
|
||||
new = xaccSplitGetAmount(xaccTransGetSplit(new_trans, i));
|
||||
result = gnc_numeric_add(old, new, GNC_DENOM_AUTO, GNC_DENOM_FIXED);
|
||||
if (gnc_numeric_eq(old, gnc_numeric_neg(new)))
|
||||
{
|
||||
msg = g_strdup_printf("Amount of split %d wrong after reversal\n", i);
|
||||
failure(msg);
|
||||
}
|
||||
|
||||
old = xaccSplitGetValue(xaccTransGetSplit(transaction, i));
|
||||
new = xaccSplitGetValue(xaccTransGetSplit(new_trans, i));
|
||||
result = gnc_numeric_add(old, new, GNC_DENOM_AUTO, GNC_DENOM_FIXED);
|
||||
if (gnc_numeric_eq(old, gnc_numeric_neg(new)))
|
||||
{
|
||||
msg = g_strdup_printf("Value of split %d wrong after reversal\n", i);
|
||||
failure(msg);
|
||||
}
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find a transaction that isn't voided */
|
||||
do
|
||||
{
|
||||
gboolean voyd;
|
||||
|
||||
transaction = get_random_transaction (book);
|
||||
voyd = xaccTransGetVoidStatus (transaction);
|
||||
if (voyd)
|
||||
{
|
||||
xaccTransBeginEdit (transaction);
|
||||
xaccTransDestroy (transaction);
|
||||
xaccTransCommitEdit (transaction);
|
||||
transaction = NULL;
|
||||
}
|
||||
} while (!transaction);
|
||||
transaction_set_splits_to_accounts(transaction, acc1, acc2);
|
||||
xaccTransSortSplits(transaction);
|
||||
|
||||
new_trans = xaccTransReverse(transaction);
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
old = xaccSplitGetAmount(xaccTransGetSplit(transaction, i));
|
||||
new = xaccSplitGetAmount(xaccTransGetSplit(new_trans, i));
|
||||
result = gnc_numeric_add(old, new, GNC_DENOM_AUTO, GNC_DENOM_FIXED);
|
||||
if (gnc_numeric_eq(old, gnc_numeric_neg(new)))
|
||||
{
|
||||
msg = g_strdup_printf("Amount of split %d wrong after reversal\n", i);
|
||||
failure(msg);
|
||||
}
|
||||
|
||||
old = xaccSplitGetValue(xaccTransGetSplit(transaction, i));
|
||||
new = xaccSplitGetValue(xaccTransGetSplit(new_trans, i));
|
||||
result = gnc_numeric_add(old, new, GNC_DENOM_AUTO, GNC_DENOM_FIXED);
|
||||
if (gnc_numeric_eq(old, gnc_numeric_neg(new)))
|
||||
{
|
||||
msg = g_strdup_printf("Value of split %d wrong after reversal\n", i);
|
||||
failure(msg);
|
||||
}
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
qof_init();
|
||||
if(cashobjects_register()) {
|
||||
set_success_print (TRUE);
|
||||
run_test ();
|
||||
success("transaction voiding seems OK");
|
||||
print_test_results();
|
||||
}
|
||||
qof_close();
|
||||
return get_rv();
|
||||
qof_init();
|
||||
if (cashobjects_register())
|
||||
{
|
||||
set_success_print (TRUE);
|
||||
run_test ();
|
||||
success("transaction voiding seems OK");
|
||||
print_test_results();
|
||||
}
|
||||
qof_close();
|
||||
return get_rv();
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
@@ -38,169 +38,170 @@ static void
|
||||
transaction_set_splits_to_accounts(Transaction *tr, Account *a1, Account *a2)
|
||||
{
|
||||
|
||||
Split *split;
|
||||
Split *split;
|
||||
|
||||
split = xaccTransGetSplit(tr, 0);
|
||||
|
||||
xaccAccountInsertSplit(a1, split);
|
||||
split = xaccTransGetSplit(tr, 0);
|
||||
|
||||
split = xaccTransGetSplit(tr, 1);
|
||||
xaccAccountInsertSplit(a2, split);
|
||||
return;
|
||||
xaccAccountInsertSplit(a1, split);
|
||||
|
||||
split = xaccTransGetSplit(tr, 1);
|
||||
xaccAccountInsertSplit(a2, split);
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
run_test (void)
|
||||
{
|
||||
Account *acc1, *acc2;
|
||||
Transaction *transaction;
|
||||
gnc_numeric old_amt, new_amt, old_val, new_val;
|
||||
QofBook *book;
|
||||
Timespec ts;
|
||||
time_t now;
|
||||
Account *acc1, *acc2;
|
||||
Transaction *transaction;
|
||||
gnc_numeric old_amt, new_amt, old_val, new_val;
|
||||
QofBook *book;
|
||||
Timespec ts;
|
||||
time_t now;
|
||||
|
||||
char *reason = "because I can";
|
||||
char *reason = "because I can";
|
||||
|
||||
book = qof_book_new();
|
||||
book = qof_book_new();
|
||||
|
||||
acc1 = get_random_account(book);
|
||||
acc2 = get_random_account(book);
|
||||
acc1 = get_random_account(book);
|
||||
acc2 = get_random_account(book);
|
||||
|
||||
if (!acc1 || !acc2)
|
||||
{
|
||||
failure("accounts not created");
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
transaction = get_random_transaction (book);
|
||||
if (xaccTransGetVoidStatus (transaction))
|
||||
if (!acc1 || !acc2)
|
||||
{
|
||||
xaccTransBeginEdit (transaction);
|
||||
xaccTransDestroy (transaction);
|
||||
xaccTransCommitEdit (transaction);
|
||||
transaction = NULL;
|
||||
failure("accounts not created");
|
||||
}
|
||||
} while (!transaction);
|
||||
|
||||
transaction_set_splits_to_accounts(transaction, acc1, acc2);
|
||||
do
|
||||
{
|
||||
transaction = get_random_transaction (book);
|
||||
if (xaccTransGetVoidStatus (transaction))
|
||||
{
|
||||
xaccTransBeginEdit (transaction);
|
||||
xaccTransDestroy (transaction);
|
||||
xaccTransCommitEdit (transaction);
|
||||
transaction = NULL;
|
||||
}
|
||||
}
|
||||
while (!transaction);
|
||||
|
||||
/* Compromise, check amount on one and value on the other */
|
||||
transaction_set_splits_to_accounts(transaction, acc1, acc2);
|
||||
|
||||
old_amt = xaccSplitGetAmount(xaccTransGetSplit(transaction, 0));
|
||||
old_val = xaccSplitGetValue(xaccTransGetSplit(transaction, 1));
|
||||
/* Compromise, check amount on one and value on the other */
|
||||
|
||||
now = time (NULL);
|
||||
old_amt = xaccSplitGetAmount(xaccTransGetSplit(transaction, 0));
|
||||
old_val = xaccSplitGetValue(xaccTransGetSplit(transaction, 1));
|
||||
|
||||
xaccTransVoid(transaction, reason);
|
||||
now = time (NULL);
|
||||
|
||||
ts = xaccTransGetVoidTime (transaction);
|
||||
xaccTransVoid(transaction, reason);
|
||||
|
||||
/* figure at most 2 seconds difference */
|
||||
if ((ts.tv_sec < now) || ((ts.tv_sec - now) > 2))
|
||||
{
|
||||
failure("bad void time");
|
||||
}
|
||||
ts = xaccTransGetVoidTime (transaction);
|
||||
|
||||
if (!xaccTransGetVoidStatus(transaction))
|
||||
{
|
||||
failure("void status reports false after setting void");
|
||||
}
|
||||
/* figure at most 2 seconds difference */
|
||||
if ((ts.tv_sec < now) || ((ts.tv_sec - now) > 2))
|
||||
{
|
||||
failure("bad void time");
|
||||
}
|
||||
|
||||
if (strcmp(reason, xaccTransGetVoidReason(transaction)) != 0)
|
||||
{
|
||||
failure("Reasons didn't match");
|
||||
}
|
||||
|
||||
new_amt = xaccSplitGetAmount(xaccTransGetSplit(transaction, 0));
|
||||
/* print_gnc_numeric(new_amt); */
|
||||
if (!xaccTransGetVoidStatus(transaction))
|
||||
{
|
||||
failure("void status reports false after setting void");
|
||||
}
|
||||
|
||||
if (!gnc_numeric_zero_p( new_amt))
|
||||
{
|
||||
failure("Amount of split0 not zero after voiding");
|
||||
}
|
||||
if (strcmp(reason, xaccTransGetVoidReason(transaction)) != 0)
|
||||
{
|
||||
failure("Reasons didn't match");
|
||||
}
|
||||
|
||||
new_val = xaccSplitGetValue(xaccTransGetSplit(transaction, 1));
|
||||
|
||||
if (!(gnc_numeric_zero_p(new_val)))
|
||||
{
|
||||
failure("Value of split1 not zero after voiding");
|
||||
}
|
||||
|
||||
new_amt = xaccSplitGetAmount(xaccTransGetSplit(transaction, 0));
|
||||
/* print_gnc_numeric(new_amt); */
|
||||
|
||||
if(!(gnc_numeric_eq(old_amt, xaccSplitVoidFormerAmount(xaccTransGetSplit(transaction, 0)))))
|
||||
{
|
||||
failure("former amount (after voiding) didn't match actual old amount");
|
||||
}
|
||||
if (!gnc_numeric_zero_p( new_amt))
|
||||
{
|
||||
failure("Amount of split0 not zero after voiding");
|
||||
}
|
||||
|
||||
if(!(gnc_numeric_eq(old_val, xaccSplitVoidFormerValue(xaccTransGetSplit(transaction, 1)))))
|
||||
{
|
||||
failure("former value (after voiding) didn't match actual old value");
|
||||
}
|
||||
new_val = xaccSplitGetValue(xaccTransGetSplit(transaction, 1));
|
||||
|
||||
/*
|
||||
* Retore the transaction to its former glory.
|
||||
*/
|
||||
xaccTransUnvoid(transaction);
|
||||
if (!(gnc_numeric_zero_p(new_val)))
|
||||
{
|
||||
failure("Value of split1 not zero after voiding");
|
||||
}
|
||||
|
||||
ts = xaccTransGetVoidTime (transaction);
|
||||
|
||||
/* figure at most 2 seconds difference */
|
||||
if ((ts.tv_sec != 0) || (ts.tv_sec != 0))
|
||||
{
|
||||
failure("void time not zero after restore");
|
||||
}
|
||||
if (!(gnc_numeric_eq(old_amt, xaccSplitVoidFormerAmount(xaccTransGetSplit(transaction, 0)))))
|
||||
{
|
||||
failure("former amount (after voiding) didn't match actual old amount");
|
||||
}
|
||||
|
||||
if (xaccTransGetVoidStatus(transaction))
|
||||
{
|
||||
failure("void status reports trus after restoring transaction");
|
||||
}
|
||||
if (!(gnc_numeric_eq(old_val, xaccSplitVoidFormerValue(xaccTransGetSplit(transaction, 1)))))
|
||||
{
|
||||
failure("former value (after voiding) didn't match actual old value");
|
||||
}
|
||||
|
||||
if (xaccTransGetVoidReason(transaction))
|
||||
{
|
||||
failure("void reason exists after restoring transaction");
|
||||
}
|
||||
|
||||
new_amt = xaccSplitGetAmount(xaccTransGetSplit(transaction, 0));
|
||||
/* print_gnc_numeric(new_amt); */
|
||||
/*
|
||||
* Retore the transaction to its former glory.
|
||||
*/
|
||||
xaccTransUnvoid(transaction);
|
||||
|
||||
if(!(gnc_numeric_eq(old_amt, new_amt)))
|
||||
{
|
||||
failure("Amount of split0 not correct after restoring transaction");
|
||||
}
|
||||
ts = xaccTransGetVoidTime (transaction);
|
||||
|
||||
new_val = xaccSplitGetValue(xaccTransGetSplit(transaction, 1));
|
||||
|
||||
if(!(gnc_numeric_eq(old_val, new_val)))
|
||||
{
|
||||
failure("Value of split1 not correct after restoring transaction");
|
||||
}
|
||||
|
||||
/* figure at most 2 seconds difference */
|
||||
if ((ts.tv_sec != 0) || (ts.tv_sec != 0))
|
||||
{
|
||||
failure("void time not zero after restore");
|
||||
}
|
||||
|
||||
if (!(gnc_numeric_zero_p(xaccSplitVoidFormerAmount(xaccTransGetSplit(transaction, 0)))))
|
||||
{
|
||||
failure("former amount (after restore) should be zero");
|
||||
}
|
||||
if (xaccTransGetVoidStatus(transaction))
|
||||
{
|
||||
failure("void status reports trus after restoring transaction");
|
||||
}
|
||||
|
||||
if (!(gnc_numeric_zero_p(xaccSplitVoidFormerValue(xaccTransGetSplit(transaction, 1)))))
|
||||
{
|
||||
failure("former value (after restore) should be zero");
|
||||
}
|
||||
if (xaccTransGetVoidReason(transaction))
|
||||
{
|
||||
failure("void reason exists after restoring transaction");
|
||||
}
|
||||
|
||||
return;
|
||||
new_amt = xaccSplitGetAmount(xaccTransGetSplit(transaction, 0));
|
||||
/* print_gnc_numeric(new_amt); */
|
||||
|
||||
if (!(gnc_numeric_eq(old_amt, new_amt)))
|
||||
{
|
||||
failure("Amount of split0 not correct after restoring transaction");
|
||||
}
|
||||
|
||||
new_val = xaccSplitGetValue(xaccTransGetSplit(transaction, 1));
|
||||
|
||||
if (!(gnc_numeric_eq(old_val, new_val)))
|
||||
{
|
||||
failure("Value of split1 not correct after restoring transaction");
|
||||
}
|
||||
|
||||
|
||||
if (!(gnc_numeric_zero_p(xaccSplitVoidFormerAmount(xaccTransGetSplit(transaction, 0)))))
|
||||
{
|
||||
failure("former amount (after restore) should be zero");
|
||||
}
|
||||
|
||||
if (!(gnc_numeric_zero_p(xaccSplitVoidFormerValue(xaccTransGetSplit(transaction, 1)))))
|
||||
{
|
||||
failure("former value (after restore) should be zero");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
qof_init();
|
||||
if(cashobjects_register())
|
||||
qof_init();
|
||||
if (cashobjects_register())
|
||||
{
|
||||
xaccLogDisable ();
|
||||
run_test ();
|
||||
success("transaction voiding seems OK");
|
||||
print_test_results();
|
||||
xaccLogDisable ();
|
||||
run_test ();
|
||||
success("transaction voiding seems OK");
|
||||
print_test_results();
|
||||
}
|
||||
qof_close();
|
||||
return get_rv();
|
||||
qof_close();
|
||||
return get_rv();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,7 @@
|
||||
|
||||
typedef struct _GNCSearchWindow GNCSearchWindow;
|
||||
|
||||
/* The two types of callbacks.
|
||||
/* The two types of callbacks.
|
||||
*
|
||||
* In the first callback, (used in the callback button list) the obj_p
|
||||
* argument will be a pointer to the selected item (if one is
|
||||
@@ -43,7 +43,7 @@ typedef struct _GNCSearchWindow GNCSearchWindow;
|
||||
*/
|
||||
typedef void (*GNCSearchCallback) (gpointer *obj_p, gpointer user_data);
|
||||
typedef void (*GNCSearchResultCB) (QueryNew *query, gpointer user_data,
|
||||
gpointer *result);
|
||||
gpointer *result);
|
||||
|
||||
/*
|
||||
* This callback will create a new item and return a handle to the
|
||||
@@ -61,11 +61,12 @@ typedef void (*GNCSearchFree) (gpointer user_data);
|
||||
* returns.
|
||||
*/
|
||||
typedef void (*GNCSearchSelectedCB) (gpointer selected_object,
|
||||
gpointer user_data);
|
||||
gpointer user_data);
|
||||
|
||||
typedef struct {
|
||||
const char * label;
|
||||
GNCSearchCallback cb_fcn;
|
||||
typedef struct
|
||||
{
|
||||
const char * label;
|
||||
GNCSearchCallback cb_fcn;
|
||||
} GNCSearchCallbackButton;
|
||||
|
||||
/* Caller MUST supply _EITHER_ a result_callback or a list of callback
|
||||
@@ -75,7 +76,7 @@ typedef struct {
|
||||
* but will NOT be destroyed.. They should be a GList of
|
||||
* GNCSearchParam objects. The display_list defines which paramters
|
||||
* of the found transactions are printed, and how.
|
||||
*
|
||||
*
|
||||
* The start_query is the property of the caller and will only be copied.
|
||||
* The show_start_query, if it exists, will become the property of the
|
||||
* dialog and will be automatically destroyed.
|
||||
@@ -90,23 +91,23 @@ typedef struct {
|
||||
*/
|
||||
GNCSearchWindow *
|
||||
gnc_search_dialog_create (GNCIdTypeConst obj_type, const gchar *title,
|
||||
GList *param_list,
|
||||
GList *display_list,
|
||||
QueryNew *start_query, QueryNew *show_start_query,
|
||||
GNCSearchCallbackButton *callbacks,
|
||||
GNCSearchResultCB result_callback,
|
||||
GNCSearchNewItemCB new_item_cb,
|
||||
gpointer user_data, GNCSearchFree free_user_data,
|
||||
const gchar *gconf_section,
|
||||
const gchar *type_label);
|
||||
GList *param_list,
|
||||
GList *display_list,
|
||||
QueryNew *start_query, QueryNew *show_start_query,
|
||||
GNCSearchCallbackButton *callbacks,
|
||||
GNCSearchResultCB result_callback,
|
||||
GNCSearchNewItemCB new_item_cb,
|
||||
gpointer user_data, GNCSearchFree free_user_data,
|
||||
const gchar *gconf_section,
|
||||
const gchar *type_label);
|
||||
|
||||
void gnc_search_dialog_destroy (GNCSearchWindow *sw);
|
||||
void gnc_search_dialog_raise (GNCSearchWindow *sw);
|
||||
|
||||
/* Register an on-close signal with the Search Dialog */
|
||||
guint gnc_search_dialog_connect_on_close (GNCSearchWindow *sw,
|
||||
GCallback func,
|
||||
gpointer user_data);
|
||||
GCallback func,
|
||||
gpointer user_data);
|
||||
|
||||
/* Un-register the signal handlers with the Search Dialog */
|
||||
void gnc_search_dialog_disconnect (GNCSearchWindow *sw, gpointer user_data);
|
||||
@@ -119,9 +120,9 @@ void gnc_search_dialog_disconnect (GNCSearchWindow *sw, gpointer user_data);
|
||||
* with "NULL".
|
||||
*/
|
||||
void gnc_search_dialog_set_select_cb (GNCSearchWindow *sw,
|
||||
GNCSearchSelectedCB selected_cb,
|
||||
gpointer user_data,
|
||||
gboolean allow_clear);
|
||||
GNCSearchSelectedCB selected_cb,
|
||||
gpointer user_data,
|
||||
gboolean allow_clear);
|
||||
|
||||
/* Test the dialog */
|
||||
void gnc_search_dialog_test (void);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user