Engine
******

The Engine provides an interface to a financial engine with three basic financial entities: Accounts, Transactions (known as Journal Entries in accounting practice), and Splits (known as Ledger Entries). These three entities are the central data structures of the GnuCash financial data model.

In addition, the Engine provides the abstraction of Account Groups (collections of related accounts) and GNCBooks. A GNCBook abstracts both a set of related GnuCash data (financial entities plus additional information such as budgets, per-file preferences, etc.) plus a file-editing session allowing transparent support for locking and implementation with other backends such as SQL.

The Engine code contains no GUI code whatsoever and is designed to be created as a shared library for use by other programs.

Introduction
============

Splits (see Splits), or "Ledger Entries" are the fundamental accounting units. Each Split consists of a quantity (number of dollar bills, number of shares, etc.), the value of that quantity expressed in a (possibly) different currency than the quantity, 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 (see Key-Value Pair Frames).

Transactions (see Transactions) embody the notion of "double entry" accounting. A Transaction consists of a date, a description, a number, a list of one or more Splits, and a key-value frame. When double-entry rules are enforced, the total value of the splits is zero. Note that if there is just one split, its value must be zero for double-entry accounting; this used to be used for storing prices, but with the advent of the Price DB, this is no longer the case. If there are 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. Positive Split values are 'debits' and negative Split values are 'credits'. Ensuring the Splits to 'add up' to zero causes a double-entry accounting system to always balance.

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. See Scrub.

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 enforced by the engine. The engine user cannnot accidentally destroy this relationship as long as they stick to using the API and never access internal structures directly.

Splits are grouped into Accounts (see Accounts) which are also known as "Ledgers" in accounting practice. Each Account consists of a list of Splits that debit that Account. To ensure consistency, if a Split points to an Account, then the Account must point to the Split, and vice-versa. A Split can belong to at most one Account. Besides merely containing a list of Splits, the Account structure also give the Account a name, a code number, description and notes fields, a key-value frame, a pointer to the currency that is used for all splits in this account, and a pointer to the "security" used for all splits in this account. The "security" can be the name of a stock (e.g. "IBM", "McDonald's"), or another currency (e.g. "USD", "GBP").  The security is used during Transaction balancing to enable trading between accounts denominated in different currencies, or to, for example, move stocks from one Account to another.

Accounts can be arranged in a hierarchical tree. The nodes of the tree are called "Account Groups" (see Account Groups). By accounting 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.

Using and Extending the Engine API
==================================

Engine API calls are named using a specific convention. For example, the function to access the Memo field of a Split is xaccSplitGetMemo.  The prefix xacc comes first (The xacc prefix is a historical artifact. GnuCash was derived from X-Accountant by Robin Clark.), followed by the name of the entity for which the API call applies (Split), followed by the action performed by the call (Get), followed by the name of the field being accessed (Memo). Future API calls should conform to this naming convention.

The formal arguments to Engine API calls always begin with the entity to which the call applies. Thus, the arguments to xaccSplitSetMemo are the Split pointer followed by the pointer to a memo string. Future API calls should also conform to this convention.

Engine API calls should be implemented to behave as gracefully as possible with unexpected input. Specifically, public API calls should gracefully handle NULL pointer arguments. User code should be able to handle NULL return values from Engine calls as well.

Globally Unique Identifiers
===========================

It is common for Engine structures to reference other Engine structures. For example, an Account must reference its Splits, its parent Account Group, and its child Account Group. Furthermore, other GnuCash modules may need to reference Engine structures. For example, a GUI implementation may wish to save a list of Accounts which the user has open when the application exits in order to restore that same state upon the next invocation.

One way to uniquely identify an Engine structure, at least while the program is running, is using the C pointer which points to the structure. C pointers have the advantage of speed, but also have some disadvantages:

  * Pointers cannot be used in data files and are not persistant across different program invocations.

  * When an entity is destroyed, every other structure which references that entity through a direct pointer must be immediately updated to prevent illegal accesses.

The GUID (Globally Unique Identifier) provides a way to reference Engine structures that is more flexible than C pointers. Each Engine structure has an associated GUID which can be used to reference that structure. Engine GUIDs have the following features:

  * The GUID is permanent, i.e., it persists between invocations of GnuCash.

  * The GUID is guaranteed to be unique with the set of all Splits, Transactions, and Accounts in the hierarchy of which the structure is a member.

  * With very high probability, the GUID is unique among all GUIDs created by any invocation of GnuCash, all over the world.

  * GUIDs can be efficiently encoded in a string representation.

When to use GUIDs
-----------------

Although GUIDs are very flexible, the engine structures like Accounts will probably continue to use C pointers for the forseeable future, since they are much faster (and in certain respects more convenient) than using GUIDs. In general, however, it is much safer to use GUIDs. In particular, you should consider using GUIDs if any of the following is true:

  * You need to save a reference to an engine structure in a file.

  * You need to save a reference to an engine structure that could be deleted in between accesses to the saved reference.

GUID Types
----------

The GUIDs in GnuCash are typed using the enum GNCIdType. Possible values and their meanings for GUID types are:

GNC_ID_NONE
     The GUID does not currently refer to a GnuCash entity, though it could refer to one in the future.

GNC_ID_NULL
     The GUID does not, and never will, refer to a GnuCash entity.

GNC_ID_ACCOUNT
     The GUID refers to an Account (see Accounts).

GNC_ID_TRANS
     The GUID refers to a Transation (see Transactions).

GNC_ID_SPLIT
     The GUID refers to a Split (see Splits).

 -- Function: GNCIdType xaccGUIDType (const GUID * GUID)
     Return the type associated with GUID.

 -- Function: const GUID * xaccGUIDNull (void)
     Return a GUID which is guaranteed to always have type GNC_ID_NULL.

How to use GUIDs
----------------

The Engine API functions which access the GUID for a specific entity return a pointer to the GUID. Note: Do not store the pointer itself! Instead, store a copy of the GUID. Storing the pointer itself would present some of the same problems as using the account pointer directly. Example:

     {
       GUID saved_guid;
       Account *account;

       account = < something to get an Account pointer >

       saved_guid = *xaccAccountGetGUID(account);

       ...

       account = xaccAccountLookup(&saved_guid);

       ...
     }

You can compare two GUIDs with the following functions.

 -- Function: gboolean guid_equal (const GUID * GUID_1, const GUID * GUID_2)
     Compare two guids and return TRUE if they are both non-NULL and equal.

 -- Function: gint guid_compare (const GUID * G1, const GUID * G2)
     Return the memcmp of the two GUID's.

You can encode and decode GUIDs and their string representations using the next two functions.

 -- Function: char * guid_to_string (const GUID * GUID)
     Return a null-terminated string encoding of GUID. String encodings of identifiers are hex numbers printed only with the characters 0 through 9 and a through f.  The encoding will always be GUID_ENCODING_LENGTH characters long. The returned string should be freed when no longer needed.

 -- Function: char * guid_to_string_buff (const GUID * GUID, char * BUFF)
     This routine does the same work as guid_to_string, except that the string is written into the memory pointed at by BUFF. The buffer must be at least GUID_ENCODING_LENGTH+1 characters long. This routine is handy for avoiding a malloc/free cycle. It returns a pointer to the end of what was written. (i.e. it can be used like stpcpy during string concatenation)

 -- Function: gboolean string_to_guid (const char * STRING, GUID * GUID)
     Given a string, decode an id into GUID if GUID is non-NULL. The function returns TRUE if the string was a valid 32 character hexadecimal number. This function accepts both upper and lower case hex digits. If the return value is FALSE, the effect on GUID is undefined.

You can allocate and deallocate space for GUIDs using standard memory routines. However, if your code is allocating and deallocating lots of GUID objects, then the next two functions should be used.

 -- Function: GUID * xaccGUIDMalloc (void)
     Return newly allocated memory for a GUID object. The memory must be freed with xaccGUIDFree. In general, this function is faster than using the standard libc allocators.

 -- Function: void xaccGUIDFree (GUID * GUID)
     Free the space for a GUID that was allocated with xaccGUIDMalloc.

You can use the following two functions to aid in using GUIDS in hash tables.

 -- Function: guint guid_hash_to_guint (gconstpointer PTR)
     Return a hash value suitable for use with a GHashTable. PTR must point to a GUID.

 -- Function: GHashTable * guid_hash_table_new (void)
     Return a new GHashTable which uses GUIDs as keys.

GUIDs and GnuCash Entities
--------------------------

This section documents a low-level API for associating entities with GUIDs. User code and general engine code should not use this API; instead use the API documented in the sections for the specific GnuCash entities such as Accounts and Transactions.

 -- Function: void xaccGUIDNew (GUID * GUID)
     Generate a new guid. This function is guaranteed to return a guid that is unique within the scope of all GnuCash entities being managed by the the current invocation of GnuCash. GnuCash routines should always use this function and not guid_new!

 -- Function: void * xaccLookupEntity (const GUID * GUID, GNCIdType ENTITY_TYPE)
     Lookup an entity given an id and a type. If there is no entity associated with the id, or if it has a different type, NULL is returned.

 -- Function: void xaccStoreEntity (void * ENTITY, const GUID * GUID, GNCIdType entity_type)
     Store the given entity under the given id with the given type.

 -- Function: void xaccRemoveEntity (const GUID * GUID)
     Remove any existing association between an entity and the given id. The entity is not changed in any way.

The GUID Generator
------------------

GUIDs are created by the GUID generator. The API for this generator is low-level and should not be used by user-code.

 -- Function: void guid_init (void)
     Initialize the GUID generator with a variety of random sources including common system files and /dev/random.

 -- Function: void guid_init_with_salt (const void * SALT, size_t SALT_LEN)
     Initialize the GUID generator with guid_init() and with the given sequence of arbitrary binary data.

 -- Function: void guid_init_only_salt (const void * SALT, size_t SALT_LEN)
     Initialize the GUID generator using only the given sequence of arbitrary binary data. This provides a way to reliably obtain a given sequence of GUIDs.

 -- Function: void guid_new (GUID * GUID)
     Create a new GUID and store it in GUID. This is a low-level function! GnuCash code should use xaccGUIDNew.

Numeric Library
===============

Financial quantities in GnuCash (Split quantities and values) are stored as exact quantities measured in the smallest denominational unit of the appropriate currency. For example, 100.50 US Dollars would be stored as (10050 / 100) US Dollars. GnuCash uses the gnc_numeric datatype to store financial quantities.

The gnc_numeric API provides data types and functions for manipulating exact numeric quantities. While the gnc_numeric library was developed to represent and operate on exact financial quantities in GnuCash, the library is also (hopefully) suitable for use in any application where exact numeric representation for rational numbers is needed.

A gnc_numeric value represents a number in rational form, with a 64-bit long long integer as numerator and denominator. If more precision, a higher-precision representation of irrational numbers, or a wider dynamic range is needed, a floating point format may be appropriate. There are reasonable rational approximations to common irrational constants (see Numeric Example), but the transcendental functions have not been implemented for gnc_numeric objects.

Standard Numeric Arguments
--------------------------

It is useful to specify a denominator in cases where it is known that the output value is of constrained precision. For example, monetary transactions must be executed in an integer number of the "smallest currency unit" of the transaction. In US Dollars, the smallest currency unit is the cent, and all monetary transactions must be done in units of cents. Therefore, any fractional cents in a computed price must be rounded away.

Most of the gnc_numeric arithmetic functions take two arguments in addition to their numeric args: DENOM, which is the denominator to use in the output gnc_numeric object, and HOW, which describes how the arithmetic result is to be converted to that denominator. This combination of output denominator and rounding policy allows the results of financial and other exact computations to be properly rounded to the appropriate units.

Valid values for DENOM are:

n (positive int)
     Use the number n as the denominator of the output value.

GNC_DENOM_RECIPROCAL (n)
     Use the value 1/n as the denominator of the output value.

GNC_DENOM_SIGFIGS (n)
     Use a value for the denominator that will keep at least n significant figures in the result.

GNC_DENOM_AUTO
     Compute an appropriate denominator automatically. Flags in the HOW argument will specify how to compute the denominator.

Valid values for HOW are bitwise combinations of zero or one "rounding instructions" with zero or one "denominator types".

Rounding instructions control how fractional parts in the specified denominator affect the result. For example, if a computed result is "3/4" but the specified denominator for the return value is 2, should the return value be "1/2" or "2/2"?

Possible rounding instructions are:

GNC_RND_FLOOR
     Round toward -infinity

GNC_RND_CEIL
     Round toward +infinity

GNC_RND_TRUNC
     Truncate fractions (round toward zero)

GNC_RND_PROMOTE
     Promote fractions (round away from zero)

GNC_RND_ROUND
     Use unbiased ("banker's") rounding. This rounds to the nearest integer, and to the nearest even integer when there are two equidistant nearest integers. This is generally the one you should use for financial quantities.

GNC_RND_ROUND_HALF_UP
     Round to the nearest integer, rounding away from zero when there are two equidistant nearest integers.

GNC_RND_ROUND_HALF_DOWN
     Round to the nearest integer, rounding toward zero when there are two equidistant nearest integers.

GNC_RND_NEVER
     Never round at all, and signal an error if there is a fractional result in a computation.

The denominator type specifies how to compute a denominator if GNC_DENOM_AUTO is specified as the DENOM. Valid denominator types are:

GNC_DENOM_EXACT
     Use any denominator which gives an exactly correct ratio of numerator to denominator. Use EXACT when you do not wish to lose any information in the result but also do not want to spend any time finding the "best" denominator.

GNC_DENOM_REDUCE
     Reduce the result value by common factor elimination, using the smallest possible value for the denominator that keeps the correct ratio. The numerator and denominator of the result are relatively prime. This can be computationally expensive for large fractions.

GNC_DENOM_LCD
     Find the least common multiple of the arguments' denominators and use that as the denominator of the result.

GNC_DENOM_FIXED
     All arguments are required to have the same denominator, that denominator is to be used in the output, and an error is to be signaled if any argument has a different denominator.

GNC_DENOM_SIGFIG
     Round to the number of significant figures given in the rounding instructions by the GNC_DENOM_SIGFIGS () macro.

To use traditional rational-number operational semantics (all results are exact and are reduced to relatively-prime fractions) pass the argument GNC_DENOM_AUTO as DENOM and GNC_DENOM_REDUCE | GNC_RND_NEVER as HOW.

To enforce strict financial semantics (such that all operands must have the same denominator as each other and as the result), use GNC_DENOM_AUTO as DENOM and GNC_DENOM_FIXED | GNC_RND_NEVER as HOW.

Creating Numeric Objects
------------------------

 -- Function: gnc_numeric gnc_numeric_create (int NUM, int DENOM)
     Create a gnc_numeric object with a value of "NUM / DENOM".

 -- Function: gnc_numeric gnc_numeric_zero ()
     Create a gnc_numeric object with a value of 0.

Basic Arithmetic Operations
---------------------------

See Standard Numeric Arguments for a description of the DENOM and HOW arguments to each arithmetic function.

 -- Function: gnc_numeric gnc_numeric_add (gnc_numeric A, gnc_numeric B, gint64 DENOM, gint HOW)
     Return the sum of A and B.

 -- Function: gnc_numeric gnc_numeric_sub (gnc_numeric A, gnc_numeric B, gint64 DENOM, gint HOW)
     Return "A - B".

 -- Function: gnc_numeric gnc_numeric_mul (gnc_numeric A, gnc_numeric B, gint64 DENOM, gint HOW)
     Return the product of A and B.

 -- Function: gnc_numeric gnc_numeric_div (gnc_numeric A, gnc_numeric B, gint64 DENOM, gint HOW)
     Return "A / B".

 -- Function: gnc_numeric gnc_numeric_neg (gnc_numeric A)
     Return "-A".

 -- Function: gnc_numeric gnc_numeric_abs (gnc_numeric A)
     Return the absolute value of A.

 -- Function: gnc_numeric gnc_numeric_add_fixed (gnc_numeric A, gnc_numeric B)
     Equivalent to gnc_numeric_add on A and B with GNC_DENOM_AUTO for DENOM and GNC_DENOM_FIXED | GNC_RND_NEVER for HOW.

 -- Function: gnc_numeric gnc_numeric_sub_fixed (gnc_numeric A, gnc_numeric B)
     Equivalent to gnc_numeric_sub on A and B with GNC_DENOM_AUTO for DENOM and GNC_DENOM_FIXED | GNC_RND_NEVER for HOW.

 -- Function: gnc_numeric gnc_numeric_add_with_error (gnc_numeric A, gnc_numeric B, gint64 DENOM, gint HOW, gnc_numeric * ERROR)
     The same as gnc_numeric_add, but uses ERROR for accumulating conversion roundoff error.

 -- Function: gnc_numeric gnc_numeric_sub_with_error (gnc_numeric A, gnc_numeric B, gint64 DENOM, gint HOW, gnc_numeric * ERROR)
     The same as gnc_numeric_sub, but uses ERROR for accumulating conversion roundoff error.

 -- Function: gnc_numeric gnc_numeric_mul_with_error (gnc_numeric A, gnc_numeric B, gint64 DENOM, gint HOW, gnc_numeric * ERROR)
     The same as gnc_numeric_mul, but uses ERROR for accumulating conversion roundoff error.

 -- Function: gnc_numeric gnc_numeric_div_with_error (gnc_numeric A, gnc_numeric B, gint64 DENOM, gint HOW, gnc_numeric * ERROR)
     The same as gnc_numeric_div, but uses ERROR for accumulating conversion roundoff error.

Numeric Comparisons and Predicates
----------------------------------

 -- Function: int gnc_numeric_zero_p (gnc_numeric A)
     Returns 1 if A == 0, otherwise returns 0.

 -- Function: int gnc_numeric_positive_p (gnc_numeric A)
     Returns 1 if A > 0, otherwise returns 0.

 -- Function: int gnc_numeric_negative_p (gnc_numeric A)
     Returns 1 if A < 0, otherwise returns 0.

 -- Function: int gnc_numeric_compare (gnc_numeric A, gnc_numeric B)
     Returns +1 if A > B, -1 if B > A, 0 if A == B.

 -- Function: int gnc_numeric_eq (gnc_numeric A, gnc_numeric B)
     Returns 1 if numerator(A) == numerator(B) and denominator(A) == denominator(B), otherwise returns 0.

 -- Function: int gnc_numeric_equal (gnc_numeric A, gnc_numeric B)
     Returns 1 if the fraction represented by A is equal to the fraction represented by B, otherwise returns 0.

 -- Function: int gnc_numeric_same (gnc_numeric A, gnc_numeric B, gint64 DENOM, gint HOW)
     Convert both A and B to DENOM (see Standard Numeric Arguments and compare numerators of the result.

            For example, if A == 7/16 and B == 3/4,
            gnc_numeric_same(A, B, 2, GNC_RND_TRUNC) == 1
            because both 7/16 and 3/4 round to 1/2 under truncation. However,
            gnc_numeric_same(A, B, 2, GNC_RND_ROUND) == 0
            because 7/16 rounds to 1/2 under unbiased rounding but 3/4 rounds
            to 2/2.

Numeric Denominator Conversion
------------------------------

 -- Function: gnc_numeric gnc_numeric_convert (gnc_numeric IN, gint64 DENOM, gint HOW)
     Convert IN to the specified denominator under standard arguments DENOM and HOW. See Standard Numeric Arguments.

 -- Function: gnc_numeric gnc_numeric_convert_with_error (gnc_numeric IN, gint64 DENOM, gint HOW, gnc_numeric * ERROR)
     Same as gnc_numeric_convert, but return a remainder value for accumulating conversion error.

 -- Function: gnc_numeric gnc_numeric_reduce (gnc_numeric IN)
     Return IN reduced by GCF reduction.

Numeric Floating Point Conversion
---------------------------------

 -- Function: gnc_numeric double_to_gnc_numeric (double ARG, gint64 DENOM, gint HOW)
     Convert a floating-point number to a gnc_numeric. Both DENOM and HOW are used as in arithmetic, but GNC_DENOM_AUTO is not recognized.

 -- Function: double gnc_numeric_to_double (gnc_numeric ARG)
     Convert ARG to a double value.

Numeric String Conversion
-------------------------

 -- Function: gchar * gnc_numeric_to_string (gnc_numeric N)
     Return a string representation of N. The string must be freed with g_free.

 -- Function: const gchar * string_to_gnc_numeric (const gchar * STR, gnc_numeric * N)
     Read a gnc_numeric from STR, skipping any leading whitespace, and returning a pointer to just past the last byte read. Return NULL on error.

Numeric Error Handling
----------------------

 -- Function: int gnc_numeric_check (gnc_numeric NUM)
     Check NUM for the possibility that it is an error signal rather than a proper value. Possible return codes are:

     GNC_ERROR_OK
          No error condition

     GNC_ERROR_ARG
          An improper argument was passed to a function

     GNC_ERROR_OVERFLOW
          An overflow occurred while calculating a result

     GNC_ERROR_DENOM_DIFF
          GNC_DENOM_FIXED was specified, but argument denominators differed.

     GNC_ERROR_REMAINDER
          GNC_RND_NEVER was specified, but the result could not be converted to the desired denominator without a remainder.

 -- Function: gnc_numeric gnc_numeric_error (int error_code)
     Create a gnc_numeric object that signals the error condition noted by ERROR_CODE rather than a number.

Numeric Example
---------------

The following program finds the best gnc_numeric approximation to the math.h constant M_PI given a maximum denominator. For large denominators, the gnc_numeric approximation is accurate to more decimal places than will generally be needed, but in some cases this may not be good enough. For example,

         M_PI                   = 3.14159265358979323846
         245850922 / 78256779   = 3.14159265358979311599  (16 sig figs)
         3126535 / 995207       = 3.14159265358865047446  (12 sig figs)
         355 / 113              = 3.14159292035398252096  (7 sig figs)

     #include <glib.h>
     #include "gnc-numeric.h"
     #include <math.h>

     int
     main(int argc, char ** argv)
     {
       gnc_numeric approx, best;
       double err, best_err=1.0;
       double m_pi = M_PI;
       gint64 denom;
       gint64 max;

       sscanf(argv[1], "%Ld", &max);

       for (denom = 1; denom < max; denom++)
       {
         approx = double_to_gnc_numeric (m_pi, denom, GNC_RND_ROUND);
         err    = m_pi - gnc_numeric_to_double (approx);
         if (fabs (err) < fabs (best_err))
         {
           best = approx;
           best_err = err;
           printf ("%Ld / %Ld = %.30f\n", gnc_numeric_num (best),
                   gnc_numeric_denom (best), gnc_numeric_to_double (best));
         }
       }
     }

Key-Value Pair Frames
=====================

The number and types of data items which are associated with the financial abstractions (Accounts, Transactions, and Splits) can vary widely. For example, an Account which represents a user's checking account might need to store the bank name, a telephone number, and a username for online banking purposes. Another Account representing the user's ownership of a stock might need to store information about retrieving price quotes online such as the ticker symbol and the exchange.

To meet this need for varying data storage, the GnuCash accounting entities use Key-Value Pair Frames (hereafter referred to as the datatype kvp_frame). A kvp_frame is a set of associations between character strings (keys) and kvp_value structures. A kvp_value is a union with possible types enumerated in the kvp_value_t enum which indicates the type of data stored in a kvp_value object.

Key-Value Policy
----------------

This section defines the policy that programmers should follow when using key-value pairs to store information. Because of the large amount of information which can potentially be stored using this mechanism, it is important to follow these guidelines so that order will be maintained.

The following rules should be followed for using key-value pairs:

  * The document src/engine/kvp_doc.txt should be used to document the use of keys and values. Please consult this document before planning any use of new keys.

  * Key strings should be in all lower case with the '-' character separating words. If possible, use only alphanumeric characters and '-'. Example: bank-info. Because the '/' character is useful for describing keys in sub-frames (bank-info/routing-number), do not use the '/' character in key names.

  * Favor longer, descriptive key strings over short ones. Example: online-banking-info is better than onln-bnk.

  * Make use of the fact that frames can be stored in frames. If a group of keys are used for a related purpose, consider storing them together in a sub-frame.

  * Values should generally not be accessed directly through keys, but should rather be accessed through specific API calls. The API calls do not necessarily need to part a part of the Engine API. For example, the GUI would probably define keys that the Engine does not need to know about.

  * The same key should not be used for different engine structures (Accounts, Transactions, Splits), unless the key's value has the same type and the same basic purpose.

kvp_frame
---------

A kvp_frame is the datatype used to associate key strings with kvp_value objects (see kvp_value).

 -- Function: kvp_frame* kvp_frame_new (void)
     Create and initialize a new kvp_frame object and return a pointer to it.

 -- Function: void kvp_frame_delete (kvp_frame * FRAME)
     Free all memory associated with FRAME.

 -- Function: kvp_frame* kvp_frame_copy (const kvp_frame * frame)
     Return a deep copy of FRAME.

 -- Function: void kvp_frame_set_slot (kvp_frame * FRAME, const char * KEY, const kvp_value * VALUE)
     Associate KEY with VALUE in FRAME.

 -- Function: void kvp_frame_set_slot_nc (kvp_frame * FRAME, const char * KEY, kvp_value * VALUE)
     Same as kvp_frame_set_slot, except that VALUE is used directly, instead of being copied. This call transfers 'ownership' of VALUE to FRAME.

 -- Function: kvp_value* kvp_frame_get_slot (kvp_frame * FRAME, const char * KEY)
     Return the kvp_value object associated with KEY in FRAME or return NULL if there is no association for KEY. The value returned is not a copy.

 -- Function: void kvp_frame_set_slot_path (kvp_frame * FRAME, const kvp_value * VALUE, const char * FIRST_KEY, ...)
     Associate VALUE with the ``key path'' specified by the variable argument list. Each key in the path except the last denotes a sub-frame which is associated with the given key. The variable list must be terminated with NULL.

 -- Function: void kvp_frame_set_slot_path_gslist (kvp_frame * FRAME, const kvp_value * VALUE, GSList * KEY_PATH)
     The same as kvp_frame_set_slot_path, except that the key path is specified using a GSList. All the keys in the list should be non-NULL.

 -- Function: kvp_value * kvp_frame_get_slot_path (kvp_frame * FRAME, const char * FIRST_KEY, ...)
     Return the value associated with the key path, or NULL if none. The path is specified as in kvp_frame_set_slot_path.

 -- Function: kvp_value * kvp_frame_get_slot_path_gslist (kvp_frame * FRAME, GSList * KEY_PATH)
     Return the value associated with the key path, or NULL if none. The path is specified as in kvp_frame_set_slot_path_gslist.

 -- Function: kvp_frame * kvp_frame_get_frame (kvp_frame * FRAME, ...)
     Works like kvp_frame_get_slot_path, but returns the last frame in the path. All the keys should refer to frames. If the frame path does not exist, it is created.

 -- Function: kvp_frame * kvp_frame_get_frame_gslist (kvp_frame * FRAME, GSList * KEY_PATH)
     Works like kvp_frame_get_slot_path_gslist, but returns the last frame in the path. All the keys should refer to frames. If the frame path does not exist, it is created.

 -- Function: kvp_frame * kvp_frame_get_frame_slash (kvp_frame * FRAME, const char * PATH)
     Works like kvp_frame_get_frame, but the frame path is specified as a single string where the keys are separated by slashes; thus, for example: /this/is/a/valid/path and ///so//is////this/. Multiple slashes are compresed and a leading slash is optional. The pointers . and .. are not followed/obeyed. (This is arguably a bug that needs fixing).

kvp_value
---------

The kvp_value object stores the 'value' part of a key-value association in a kvp_frame object.

 -- Function: void kvp_value_delete (kvp_value * VALUE)
     Free all of the memory associated with VALUE.

 -- Function: kvp_value* kvp_value_copy (const kvp_value * VALUE)
     Return a deep copy of VALUE.

 -- Function: kvp_value_t kvp_value_get_type (const kvp_value * VALUE)
     Return the type of value stored in VALUE.

A kvp_value_t enum must have one of the following values:

KVP_TYPE_NONE
     Indicates the abscence of a value in a kvp_frame.

KVP_TYPE_INT64
     A gint64 value.

KVP_TYPE_FLOAT64
     A double value.

KVP_TYPE_STRING
     A char * value of arbitrary length.

KVP_TYPE_GUID
     A GUID value. See Globally Unique Identifiers.

KVP_TYPE_BINARY
     Arbitrary binary data.

KVP_TYPE_LIST
     A kvp_list item which contains a list of kvp_value items.

KVP_TYPE_FRAME
     A kvp_frame object. Thus, frames may contain other frames in a recursive manner.

Value Constructors
..................

The following functions create and return kvp_value objects with particular values. In the case of pointer arguments, deep copies are performed.

 -- Function: kvp_value* kvp_value_new_int64 (gint64 VALUE)

 -- Function: kvp_value* kvp_value_new_float64 (double VALUE)

 -- Function: kvp_value* kvp_value_new_string (const char * VALUE)

 -- Function: kvp_value* kvp_value_new_guid (const GUID * GUID)

 -- Function: kvp_value* kvp_value_new_binary (const void * DATA, int DATASIZE)

 -- Function: kvp_value* kvp_value_new_list (const kvp_list * VALUE)

 -- Function: kvp_value* kvp_value_new_frame (const kvp_frame * VALUE);

Value Accessors
...............

The following functions access the value of a given kvp_value object. If the type of the object does not correspond to that named in the function, NULL, 0, or 0.0 is returned as appropriate.

 -- Function: gint64 kvp_value_get_int64 (const kvp_value * VALUE)

 -- Function: double kvp_value_get_float64 (const kvp_value * VALUE)

 -- Function: char* kvp_value_get_string (const kvp_value * VALUE)

 -- Function: GUID* kvp_value_get_guid (const kvp_value * VALUE)

 -- Function: void* kvp_value_get_binary (const kvp_value * VALUE, int * SIZE_RETURN)

 -- Function: kvp_list* kvp_value_get_list (const kvp_value * VALUE)

 -- Function: kvp_frame* kvp_value_get_frame (const kvp_value * VALUE)

kvp_list
--------

A kvp_list object abstract a list of kvp_value objects.

 -- Function: kvp_list* kvp_list_new ()
     Return a newly allocated kvp_list object.

 -- Function: void kvp_list_delete (kvp_list * LIST)
     Free all memory associated with LIST, including the kvp_value objects in LIST.

 -- Function: kvp_list* kvp_list_copy (const kvp_list * LIST)
     Return a deep copy of LIST.

 -- Function: gboolean kvp_list_null_p (const kvp_list * LIST)
     Return TRUE if LIST is the empty list.

 -- Function: kvp_value* kvp_list_car (kvp_list * LIST)
     If LIST is NULL or the empty list, return NULL. Otherwise, return the first kvp_value object in the list.

 -- Function: kvp_list* kvp_list_cdr (kvp_list * LIST)
     If LIST is NULL or the empty list, return NULL. Otherwise, return a kvp_list object consisting of LIST with the first value removed. NOTE: the returned list is not a copy!

 -- Function: kvp_list* kvp_list_cons (kvp_value * CAR, kvp_list * CDR)
     If either CAR or CDR is NULL, return NULL. Otherwise, return a kvp_list object consisting of the value of CAR followed by the values of CDR. This function uses 'hand-over' semantics, i.e., the arguments CAR and CDR are no longer the responsibility of the caller and should not be accessed after the function returns.

Events
======

The Engine supports the concept of Events which notify external code when engine entities are created, modified, or destroyed.

User code can register event handers which are invoked for each event, giving information about the specific engine entity generating the event and the nature of the event (creation, modification, or deletion).

Event API
---------

Engine events are classified using the GNCEngineEventType bitmask which has the following predefined values:

GNC_EVENT_NONE
     A null value.

GNC_EVENT_CREATE
     Indicates an entity has been created.

GNC_EVENT_MODIFY
     Indicates an entity has been changed in some way.

GNC_EVENT_DESTROY
     Indicates an entity is being destroyed.

GNC_EVENT_ALL
     The boolean OR of GNC_EVENT_CREATE, GNC_EVENT_MODIFY, and GNC_EVENT_DESTROY.

Event handlers are functions with the following type:

 -- Data type: GNCEngineEventHandler void (*) (GUID * ENTITY, GNCEngineEventType EVENT_TYPE, gpointer USER_DATA)
     A callback invoked when an engine event occurs. ENTITY is the GUID of the entity generating the event. EVENT_TYPE is one of GNC_EVENT_CREATE, GNC_EVENT_MODIFY, or GNC_EVENT_DESTROY. USER_DATA is the user data parameter supplied when the handler was registered.

 -- Function: gint gnc_engine_register_event_handler (GNCEngineEventHandler HANDLER, gpointer USER_DATA)
     Register a handler for engine events. The return value is an identifier used to specify this handler in other API calls.

 -- Function: void gnc_engine_unregister_event_handler (gint HANDLER_ID)
     Unregister the event handler specified by HANDLER_ID.

 -- Function: void gnc_engine_suspend_events (void)
     Suspend all engine events. This function may be called multiple times. To resume event generation, an equal number of calls to gnc_engine_resume_events must be made.

 -- Function: void gnc_engine_resume_events (void)
     Resume engine event generation.

Commodities
===========

A Commodity is the Engine abstraction of a tradable quantity, like a national currency or shares of a stock. A commodity object contains the following pieces of information:

A mnemonic name
     The `short' name for the commodity. For national currencies this is the 3-letter ISO4217 code (USD, AUD, etc.). For stocks this is generally the exchange symbol (RHAT, IBM, etc.).

A namespace
     A string identifying the context in which the mnemonic is meaninful.

A full name
     The `long' name for the commodity, such as "US Dollar" or "IBM Common Stock".

A printable name
     The name used to print out a string describing the commodity to a user. This name is generally long -- in some contexts it may be better to use the mnemonic instead. The printable name is determined by the namespace and mnemonic.

A unique name
     A canonical name for the commodity that cannot be identical to another commodity's unique name. The unique name is determined by the namespace and mnemonic.

An exchange code
     A code used to identify the commodity in its namespace context. For example, stocks have a unique code assigned to them by the exchange they are listed on.

A fraction
     An integer N which specifies that 1/N is generally the smallest fraction of the commodity which can be traded. For example, most currencies are tradable in 1/100ths, so the fraction would be 100.

General Commodity API
---------------------

 -- Function: gnc_commodity * gnc_commodity_new (const char * FULLNAME, const char * NAMESPACE, const char * MNEMONIC, const char * EXCHANGE_CODE, int FRACTION)
     Create and return a new commodity object with the given values, or NULL if any of the values are invalid.

 -- Function: void gnc_commodity_destroy (gnc_commodity * CM)
     Destroy the given commodity and free all associated memory.

 -- Function: gboolean gnc_commodity_equiv (const gnc_commodity * A, const gnc_commodity * B)
     Return true if the two given commodities are equivalent. Two commodities are equivalent when they have the same namespace and the same mnemonic.

Commodity Getters
-----------------

 -- Function: const char * gnc_commodity_get_mnemonic (const gnc_commodity * CM)
     Return the mnemonic of CM.

 -- Function: const char * gnc_commodity_get_namespace (const gnc_commodity * CM)
     Return the namespace of CM.

 -- Function: const char * gnc_commodity_get_fullname (const gnc_commodity * CM)
     Return the full name of CM.

 -- Function: const char * gnc_commodity_get_printname (const gnc_commodity * CM)
     Return the print name of CM.

 -- Function: const char * gnc_commodity_get_exchange_code (const gnc_commodity * CM)
     Return the exchange code of CM.

 -- Function: const char * gnc_commodity_get_unique_name (const gnc_commodity * CM)
     Return the unique name of CM.

 -- Function: int gnc_commodity_get_fraction (const gnc_commodity * CM)
     Return the smallest tradable fraction of CM.

Commodity Setters
-----------------

 -- Function: void gnc_commodity_set_mnemonic (gnc_commodity * CM, const char * MNEMONIC)
     Set the mnemonic of CM to MNEMONIC.

 -- Function: void gnc_commodity_set_namespace (gnc_commodity * CM, const char * NAMESPACE)
     Set the namespace of CM to NAMESPACE.

 -- Function: void gnc_commodity_set_fullname (gnc_commodity * CM, const char * FULLNAME)
     Set the fullname of CM to FULLNAME.

 -- Function: void gnc_commodity_set_exchange_code (gnc_commodity * CM, const char * EXCHANGE_CODE)
     Set the exchange code of CM to EXCHANGE_CODE.

 -- Function: void gnc_commodity_set_fraction (gnc_commodity * CM, int SMALLEST_FRACTION)
     Set the fraction of CM to FRACTION.

Commodity Tables
================

A Commodity Table holds a set of commodities and allows user code to add, remove, and access the commodities in the table.

There is a single, global Commodity Table used by the Engine.

General Commodity Table API
---------------------------

 -- Function: gnc_commodity_table * gnc_commodity_table_new (void)
     Allocate and initialize a gnc_commodity_table. The returned table must be destroyed with gnc_commodity_table_destroy.

 -- Function: void gnc_commodity_table_destroy (gnc_commodity_table * TABLE)
     Destroy TABLE and all associated resources, including all Commodity objects in the table.

 -- Function: gnc_commodity_table * gnc_engine_commodities (void)
     Return the global engine commodity table.

Commodity Table Access API
--------------------------

 -- Function: gnc_commodity * gnc_commodity_table_lookup (const gnc_commodity_table * TABLE, const char * NAMESPACE, const char * MNEMONIC)
     Look up a commodity in TABLE given the namespace and the mnemonic. If no such commodity exists, NULL is returned.

 -- Function: gnc_commodity * gnc_commodity_table_find_full (const gnc_commodity_table * TABLE, const char * NAMESPACE, const char * FULLNAMe)
     Look up a commodity in TABLE given the namespace and the full name. If no such commodity exists, NULL is returned.

 -- Function: int gnc_commodity_table_has_namespace (const gnc_commodity_table * TABLE, const char * NAMESPACE)
     Return true if TABLE has the namespace NAMESPACE.

 -- Function: guint gnc_commodity_table_get_size (gnc_commodity_table * TABLE)
     Return the total number of commodities stored in TABLE.

 -- Function: guint gnc_commodity_table_get_number_of_namespaces (gnc_commodity_table * TABLE)
     Return the number of distinct namespaces in TABLE.

 -- Function: GList * gnc_commodity_table_get_namespaces (const gnc_commodity_table * TABLE)
     Return a list of the distinct namespaces in TABLE. The list should be freed with g_list_free but the namespaces should not be freed or modified.

 -- Function: GList * gnc_commodity_table_get_commodities (const gnc_commodity_table * TABLE, const char * NAMESPACE)
     Return a list of the commodities under NAMESPACE in TABLE. The list should be freed with g_list_free but the commodities should not be freed.

Commodity Table Modification API
--------------------------------

 -- Function: gnc_commodity * gnc_commodity_table_insert (gnc_commodity_table * TABLE, gnc_commodity * COMM)
     Add commodity COMM to TABLE. If COMM's namespace is not in TABLE, the namespace will be added. This function has hand-over semantics, i.e., TABLE assumes responsibility for COMM.  COMM may even be destroyed by this call! The function returns the actual commodity added as a result of the call. It may not be the same object as COMM, but will be equivalent to COMM.

 -- Function: void gnc_commodity_table_remove (gnc_commodity_table * TABLE, gnc_commodity * COMM)
     Remove the given commodity from TABLE. COMM is not modified or destroyed.

 -- Function: void gnc_commodity_table_add_namespace (gnc_commodity_table * TABLE, const char * NAMESPACE)
     Add NAMESPACE to TABLE.

 -- Function: void gnc_commodity_table_delete_namespace (gnc_commodity_table * TABLE, const char * NAMESPACE)
     Delete NAMESPACE from TABLE including all associated commodities.

 -- Function: void gnc_commodity_table_remove_non_iso (gnc_commodity_table * TABLE)
     Remove and destroy all commodities in TABLE which are not in the ISO4217 namespace.

Prices
======

A Price is the Engine abstraction of an "instantaneous" price quote for a given commodity with respect to another commodity. For example, a given price might represent the value of LNUX in USD on 2001-02-03. A Price contains the following pieces of information:

A GUID
     A GUID uniquely identifying the GNCPrice.

A commodity
     The commodity being priced.

A currency
     The denomination of the value of the item being priced.

A value
     The value of the item being priced.

A time
     The time the price was valid.

A source
     A string describing the source of the quote. These strings will have a form like this: "Finance::Quote", "user:misc", "user:foo", etc. If the quote came from a user, as a matter of policy, you must prefix the string you give with "user:". For now, the only other reserved values are "Finance::Quote" and "old-file-import".

A type
     A string describing the type of quote -- types possible right now are "bid", "ask", "last", "nav", and "unknown".

Price Implementation Details
----------------------------

For the source and type fields, NULL and the empty string are considered the same, so if one of these is the empty string then it might be NULL after a file save/restore.

GNCPrices are reference counted. When you create a price or or clone one, the new price's reference count is set to 1. When you are finished with a price, call gnc_price_unref. If you hand the price pointer to some other code that needs to keep it, make sure it calls gnc_price_ref to indicate its interest in that price, and calls gnc_price_unref when it's finished with the price. For those unfamiliar with reference counting, basically each price stores an integer count which starts at 1 and is incremented every time someone calls gnc_price_ref. Conversely, the count is decremented every time someone calls gnc_price_unref. If the count ever reaches 0, the price is destroyed.

All of the getters return data that's internal to the GNCPrice, not copies, so don't free or modify these values.

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.

General Price API
-----------------

 -- Function: GNCPrice * gnc_price_create (void)
     Return a newly allocated and initialized price with a reference count of 1. The price should be dereferenced with gnc_price_unref when no longer needed, but the price should not be freed by user code.

 -- Function: GNCPrice * gnc_price_clone (GNCPrice * P)
     Return a newly allocated price that's a content-wise duplicate of P. The returned clone will have a reference count of 1.

 -- Function: void gnc_price_ref (GNCPrice * P)
     Increase the reference count of P by 1.

 -- Function: void gnc_price_unref (GNCPrice * P)
     Decrease the reference coutn of P by 1. If the resulting count is 0, P will be destroyed.

 -- Function: GNCPrice * gnc_price_lookup (const GUID * GUID)
     Lookup and return the price associated with GUID, or NULL if there is no such price.

Price Getters
-------------

 -- Function: const GUID * gnc_price_get_guid (GNCPrice * P)
     Return the GUID of P.

 -- Function: gnc_commodity * gnc_price_get_commodity (GNCPrice * P)
     Return the commodity of P.

 -- Function: gnc_commodity * gnc_price_get_currency (GNCPrice * P)
     Return the currency of P.

 -- Function: Timespec gnc_price_get_time (GNCPrice * P)
     Return the time of P.

 -- Function: const char * gnc_price_get_source (GNCPrice * P)
     Return the source of P.

 -- Function: const char * gnc_price_get_type (GNCPrice * P)
     Return the type of P.

 -- Function: gnc_numeric gnc_price_get_value (GNCPrice * P)
     Return the value of P.

 -- Function: gint32 gnc_price_get_version (GNCPrice * P)
     Return the version of P.

Price Setters
-------------

Invocations of the setters should be wrapped with calls to gnc_price_begin_edit and gnc_price_commit_edit. The begin/commit calls help ensure that the local price db is synchronized with the backend.

 -- Function: void gnc_price_begin_edit (GNCPrice * P)
     Begin a sequence of changes to P.

 -- Function: void gnc_price_commit_edit (GNCPrice * P)
     End a sequence of changes to P.

 -- Function: void gnc_price_set_commodity (GNCPrice * P, gnc_commodity * C)
     Set the commodity of P to C.

 -- Function: void gnc_price_set_currency (GNCPrice * P, gnc_commodity * C)
     Set the currency of P to C.

 -- Function: void gnc_price_set_time (GNCPrice * P, Timespec T)
     Set the time of P to T.

 -- Function: void gnc_price_set_source (GNCPrice * P, const char * SOURCE)
     Set the source of P to SOURCE.

 -- Function: void gnc_price_set_type (GNCPrice * P, const char * TYPE)
     Set the type of Pto TYPE.

 -- Function: void gnc_price_set_value (GNCPrice * P, gnc_numeric VALUE)
     Set the value of P to VALUE.

 -- Function: void gnc_price_set_version (GNCPrice * P, gint32 VERSN)
     Set the version of P to VERSN.

Price Databases
===============

A Price Database stores GNCPrices and allows prices to be looked up based on currency, commodity, and time.

Price Lists
-----------

Price Lists are used by Price Databases to organize prices for a given commodity and currency. A Price List is a list of prices with the same commodity and currency, sorted by decreasing time (earlier prices come later in the list).

 -- Function: gboolean gnc_price_list_insert (GList ** PRICES, GNCPrice * P)
     Insert price P into the list PRICES, calling GNC_PRICE_REF on P during the process.

 -- Function: gboolean gnc_price_list_remove (GList ** PRICES, GNCPrice * P)
     Remove price P from the list PRICES, calling gnc_price_unref on P during the process.

 -- Function: void gnc_price_list_destroy (GList * PRICES)
     Destroy the price list PRICES, calling gnc_price_unref on all the prices in the list.

General Price Database API
--------------------------

 -- Function: GNCPriceDB * gnc_pricedb_create (void)
     Create and return a new price database.

 -- Function: void gnc_pricedb_destroy (GNCPriceDB * DB)
     Destroy the price database DB and unreference all of the prices it contains. This may not deallocate all of those prices; other code may still be holding references to them.

 -- Function: gboolean gnc_pricedb_add_price (GNCPriceDB * DB, GNCPrice * P)
     Add the price P to DB. This will increase the reference count of P, so user code may safely drop its reference to the price (i.e. call gnc_price_unref) if the call succeeds (returns true).

 -- Function: gboolean gnc_pricedb_remove_price (GNCPriceDB * DB, GNCPrice * P)
     Removes the price P from the price database DB. Returns true if successful and false otherwise.

Splits
======

A Split is the Engine abstraction of an accounting entry in an Account Ledger. In accounting terms, a Split is a Ledger Entry. As such, it contains the following pieces of information:

A parent Account
     The Account of which it is an entry.

A parent Transaction.
     In accounting terms, this is the Journal Entry which this Ledger Entry is linked to.

A 'share quantity'
     This is the number of 'shares' which have been debited to the parent Account. This quantity may be negative, in which case the Split represents a 'credit'. Shares are given in units of the security of the Account, unless the security field is NULL, in which case shares are given in units of the Account currency. See Accounts.

A 'value'
     This represents the value of the shares in units of the currency of the Account. If the currency and the security are the same, or the security field is NULL, the value and share quantity must be equal.

A 'reconciled' flag
     This flag represents the reconciled status of the Split. Possible reconciliation states for a Split are:

     Not Reconciled
          The Split has not been reconciled or cleared.

     Cleared
          The Split has been cleared, but not reconciled.

     Reconciled
          The Split has been reconciled with a statement.

     Frozen
          The Split has been frozen into the accounting period.

In addition to the above, Splits contain a Memo field, an Action field, and a key-value pair frame. The Memo and Action fields are for arbitrary user input.  See src/engine/kvp_frame.txt for the names of keys that have already been reserved for use in the frame.

General Split API
-----------------

 -- Function: Split * xaccMallocSplit (void)
     Allocate, initialize, and return a new Split.

 -- Function: void xaccSplitDestroy (Split * SPLIT)
     Update SPLIT's parent Account and Transaction in a consistent manner, completely unlinking of SPLIT and freeing its memory. The goal of this routine is to perform the removal and destruction of the Split in an atomic fashion, with no chance of accidentally leaving the accounting structure out-of-balance or otherwise inconsistent.

     If the deletion of the Split leaves the Transaction with no Splits, then the Transaction will be marked for deletion, but will not be deleted until the xaccTransCommitEdit() routine is called.

 -- Function: const GUID * xaccSplitGetGUID (Split * SPLIT)
     Return the GUID of SPLIT.

 -- Function: Split * xaccSplitLookup (const GUID * GUID)
     Return the split associated with GUID, or NULL if there is no such split.

 -- Function: void xaccSplitMakeStockSplit (Split * SPLIT)
     Modify SPLIT to be an ``official'' stock-split split.  Among other things, this involves clearing the value of the split to 0.

Split Getters
-------------

 -- Function: Account * xaccSplitGetAccount (Split * SPLIT)
     Return the parent Account of SPLIT.

 -- Function: Transaction * xaccSplitGetParent (Split * SPLIT)
     Return the parent Transaction of SPLIT.

 -- Function: gnc_numeric xaccSplitGetShareAmount (Split * SPLIT)
     Return the 'share quantity' of SPLIT.

 -- Function: gnc_numeric xaccSplitGetSharePrice (Split * SPLIT)
     Return the 'share price' of SPLIT, which is the value divided by the share quantity.

 -- Function: gnc_numeric xaccSplitGetValue (Split * SPLIT)
     Return the value of SPLIT.

 -- Function: gnc_numeric xaccSplitGetBaseValue (Split * SPLIT, const char * BASE_CURRENCY)
     Return either the share quantity or the value of SPLIT, depending upon whether BASE_CURRENCY matches the security or currency of the parent Account, respectively. No other value for BASE_CURRENCY is legal.

 -- Function: char xaccSplitGetReconcile (Split * SPLIT)
     Return the value of the reconcile flag in SPLIT. Possible values for the flag are:

     NREC
          Not Reconciled

     CREC
          Cleared

     YREC
          Reconciled

     FREC
          Frozen

 -- Function: void xaccSplitGetDateReconciledTS (Split * SPLIT, Timespec * TS)
     Fill TS with the reconciled date of SPLIT.

 -- Function: const char * xaccSplitGetMemo (Split * SPLIT)
     Return the Memo field of SPLIT.

 -- Function: const char * xaccSplitGetAction (Split * SPLIT)
     Return the Action field of SPLIT.

 -- Function: gnc_numeric xaccSplitGetBalance (Split * SPLIT)
     Return the balance of SPLIT's parent Account up to and including SPLIT. See Accounts for details.

 -- Function: gnc_numeric xaccSplitGetClearedBalance (Split * split)
     Return the cleared balance of SPLIT's parent Account up to and including SPLIT. See Accounts for details.

 -- Function: gnc_numeric xaccSplitGetReconciledBalance (Split * split)
     Return the reconciled balance of SPLIT's parent Account up to and including SPLIT. See Accounts for details.

 -- Function: gnc_numeric xaccSplitGetShareBalance (Split * SPLIT)
     Return the share balance of SPLIT's parent Account up to and including SPLIT. See Accounts for details.

 -- Function: gnc_numeric xaccSplitGetShareClearedBalance (Split * split)
     Return the share cleared balance of SPLIT's parent Account up to and including SPLIT. See Accounts for details.

 -- Function: gnc_numeric xaccSplitGetShareReconciledBalance (Split * split)
     Return the share reconciled balance of SPLIT's parent Account up to and including SPLIT. See Accounts for details.

 -- Function: const char* xaccSplitGetType (Split * SPLIT)
     Return SPLIT's type as a string.  Currently, the possibilities are

     normal
          a normal split -- the default.

     stock-split
          a split representing a stock split.  The value should be 0 and the share amount should represent the number of shares added/subtracted from the account as a result of the forward/reverse stock split.

Split Setters
-------------

 -- Function: void xaccSplitSetMemo (Split * SPLIT, const char * MEMO)
     Set the memo field of SPLIT to MEMO.

 -- Function: void xaccSplitSetAction (Split * SPLIT, const char * ACTION)
     Set the action field of SPLIT to MEMO. The action field is an arbitrary string, but is intended to be conveniently limited to a menu of selections such as "Buy", "Sell", "Interest", etc.

 -- Function: void xaccSplitSetReconcile (Split * SPLIT, char RECONCILED_FLAG)
     Set the reconciled flag of SPLIT to RECONCILED_FLAG. For the possible values and meanings of RECONCILED_FLAG, see Split Getters.

 -- Function: void xaccSplitSetDateReconciledSecs (Split * SPLIT, time_t TIME)
     Set the reconciliation date of SPLIT to TIME.

 -- Function: void xaccSplitSetDateReconciledTS (Split * SPLIT, Timespec * TS)
     Set the reconciliation date of SPLIT to TS.

 -- Function: void xaccSplitSetShareAmount (Split * SPLIT, gnc_numeric amount)
     Set the share quantity of SPLIT to AMOUNT.

 -- Function: void xaccSplitSetSharePrice (Split * SPLIT, gnc_numeric PRICE)
     Set the share price of SPLIT to PRICE.

 -- Function: void xaccSplitSetSharePriceAndAmount (Split * SPLIT, gnc_numeric PRICE, gnc_numeric AMOUNT)
     Set both the share price and share quantity of SPLIT. This routine is more efficent than calling xaccSplitSetShareAmount and xaccSplitSetSharePrice in succesion.

 -- Function: void xaccSplitSetValue (Split * SPLIT, gnc_numeric VALUE)
     Adjust the share quantity of SPLIT so that SPLIT's value is equal to VALUE.

 -- Function: void xaccSplitSetBaseValue (Split * SPLIT, gnc_numeric VALUE, const char * BASE_CURRENCY)
     Set either the share quantity or value of SPLIT depending upon whether BASE_CURRENCY is the security or current of SPLIT's parent Account. See Accounts.

Transactions
============

A Transaction is the Engine abstraction of an accounting entry in a Journal. In accounting terms, a Transaction is a Journal Entry. As such, it contains the following pieces of information:

A list of Ledger Entries, or Splits
     The list of debits and credits which make up this Transaction. As in accounting, a Transaction is balanced when the sum of the debits equals the sum of the credits.

The entry date
     The date the transaction was entered into GnuCash.

The post date
     The date the transaction was posted. This is often the date the transaction was recorded by the bank, or the date the user initiated the transaction (i.e., wrote the check, made the ATM withdrawal).

A transaction number field
     This field is intended to hold a transaction number, such as a check number or an ID assigned by a bank to an electronic transfer.

A description
     A textual description of the transaction.

In addition to the above, Transactions contain a key-value pair frame.

The Transaction Edit Cycle
--------------------------

The Engine supports (and, in fact, requires) a 2-phase commit/rollback cycle for modifying Transactions and their constituent Splits. A Transaction must be opened for editing using xaccTransBeginEdit() before any of the following actions may be taken.

  * Modifying any field of a Transaction.

  * Modifying any Split belonging to the Transaction. That includes re-parenting a Split to a different Account or a different Transaction. In the case of re-parenting to a new Transaction, both Transactions must be opened for editing.

  * Deleting any Split belonging to the Transaction.

  * Adding a Split to the transaction.

  * Deleting the Transaction.

After the desired changes have been made, they must either be committed using xaccTransCommitEdit() or rolled back using xaccTransRollbackEdit(). Rolling back a transaction will undo any changes which have been made to it or to its Splits since it was opened for editing.

General Transaction API
-----------------------

 -- Function: Transaction * xaccMallocTransaction (void)
     Allocate, initialize, and return a new Transaction.

 -- Function: void xaccTransDestroy (Transaction * trans)
     Remove all of the Splits from each of their accounts and free the memory associated with them. This routine must be followed by either an xaccTransCommitEdit() in which case the transaction memory will be freed, or by xaccTransRollbackEdit(), in which case all the original Splits are put back into place.

 -- Function: void xaccTransAppendSplit (Transaction * TRANS, Split * SPLIT)
     Append SPLIT to the collection of Splits in TRANS. If the Split is already a part of another Transaction, it will be removed from that Transaction first.

 -- Function: void xaccTransBeginEdit (Transaction * TRANS)
     This method must be called before any changes are made to TRANS or any of its component Splits. If this is not done, errors will result.

 -- Function: void xaccTransCommitEdit (Transaction * TRANS)
     This method indicates that the changes to TRANS and its Splits are complete and should be made permanent. Note this routine may result in the deletion of the transaction, if the Transaction is "empty" (has no Splits) or if xaccTransDestroy() was called on the Transaction.

 -- Function: void xaccTransRollbackEdit (Transaction * TRANS)
     Rejects all changes made to TRANS and its Splits, and sets TRANS back to where it was before the xaccTransBeginEdit() call. 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.

 -- Function: gboolean xaccTransIsOpen (Transaction * TRANS)
     Return TRUE if TRANS is open for editing. Otherwise, it returns FALSE.

 -- Function: const GUID * xaccTransGetGUID (Transaction * TRANS)
     Return the GUID of TRANS.

 -- Function: Transaction * xaccTransLookup (const GUID * GUID)
     Return the Transaction associated with GUID, or NULL if there is no such Transaction.

 -- Function: kvp_value * xaccTransGetSlot (Transaction * TRANS, const char * KEY)
     Return the kvp_value associated with KEY in TRANS. If there is none, NULL is returned.

 -- Function: void xaccTransSetSlot (Split * TRANS, const char * KEY, const kvp_value * VALUE)
     Associate a copy of VALUE with KEY in TRANS.

Transaction Getters
-------------------

 -- Function: Split * xaccTransGetSplit (Transaction * TRANS, int I)
     Return the Ith Split of TRANS.

 -- Function: GList * xaccTransGetSplitList (Transaction * TRANS)
     Return a GList of the Splits in TRANS. This list is owned by TRANS and should not be modified in any way!

 -- Function: const char * xaccTransGetNum (Transaction * TRANS)
     Return the number field of TRANS.

 -- Function: const char * xaccTransGetDescription (Transaction * TRANS)
     Return the description field of TRANS.

 -- Function: time_t xaccTransGetDate (Transaction * TRANS)
     Return the post date of TRANS as a time_t value.

 -- Function: long long xaccTransGetDateL (Transaction * TRANS)
     Return the post date of TRANS as a long long value.

 -- Function: void xaccTransGetDateTS (Transaction * TRANS, Timespec * TS)
     Return the post date of TRANS in TS.

 -- Function: void xaccTransGetDateEnteredTS (Transaction * TRANS, Timespec * TS)
     Return the entry date of TRANS in TS.

 -- Function: char * xaccTransGetDateStr (Transaction * TRANS)
     Return a string representing the post date of TRANS, or NULL if TRANS is NULL. The string must be freed with free() after use.

 -- Function: int xaccTransCountSplits (Transaction * TRANS)
     Return the number of Splits in TRANS.

Transaction Setters
-------------------

Remember, before you modify a Transaction, you must open it for editing with xaccTransBeginEdit.

 -- Function: void xaccTransSetDate (Transaction * TRANS, int DAY, int MON, int YEAR)
     Set the post date of TRANS with DAY, MONTH, and YEAR.

 -- Function: void xaccTransSetDateSecs (Transaction * TRANS, time_t TIME)
     Set the post date of TRANS using a time_t value.

 -- Function: void xaccTransSetDateToday (Transaction * TRANS)
     Set the post date of TRANS to the current time.

 -- Function: void xaccTransSetDateTS (Transaction * TRANS, const Timespec * TS)
     Set the post date of TRANS from TS.

 -- Function: void xaccTransSetDateEnteredSecs (Transaction *trans, time_t time)
     Set the entry date of TRANS from a time_t value.

 -- Function: void xaccTransSetDateEnteredTS (Transaction * TRANS, const Timespec * TS)
     Set the entry date of TRANS from TS.

 -- Function: void xaccTransSetNum (Transaction * TRANS, const char * NUM)
     Set the number field of TRANS to NUM.

 -- Function: void xaccTransSetDescription (Transaction * TRANS, const char * DESC)
     Set the description field of TRANS to DESC.

Accounts
========

An Account is the Engine abstraction of an, well, an account. Accounts contain the following pieces of information:

A list of Ledger Entries, or Splits
     The list of debits and credits which apply to the Account. The sum of all debits and credits is the account balance.

A type
     An integer code identifying the type of account. The Account type determines whether the Account holds shares valued in a currency or not. It is also used by the GUI and reporting system to determine how debits & credits to the Account should be treated and displayed.

A name
     The name of the Account.

An account code
     A string that is intended to hold a unique user-selected identifier for the account. However, uniqueness of this field is not enforced.

A description
     A textual description of the Account.

A currency
     The commodity that Splits in the account are valued in, i.e., the denomination of the 'value' member of Splits in the account.

A curreny SCU
     The SCU is the smallest convertible unit that the currency is traded in. This value overrides the default SCU of the currency.

A security
     For Accounts which may contain shares (such as stock accounts), the denomination of the 'share quantity' member of Splits in the accounts. For accounts which do not contain shares, the security is blank, and the share quantities are denominated in the Account currency.

A security SCU
     Analogous to the currency SCU, but for the security.

A parent and child Account Group.
     The parent and child of an Account are Account Groups (see Account Groups). Account Groups are used to connect Accounts together into an Account hierarchy. If the parent Account Group is not present, the Account is at the top level of the hierarchy. If the child Account Group is not present, the Account has no children.

In addition to the above, Accounts contain a key-value pair frame.

Account Types
-------------

Account Types are defined by the GNCAccountType enumeration. Possible values are:

BAD_TYPE, NO_TYPE
     Both of these values indicate an illegal Account type.

BANK
     Denotes a savings or checking account held at a bank. Such an account is often interest bearing.

CASH
     Denotes a shoe-box or pillowcase stuffed with cash. In other words, actual currency held by the user.

CREDIT
     Denotes credit card accounts.

ASSET
     Denotes a generic asset account.

LIABILITY
     Denotes a generic liability account.

STOCK
     A stock account containing stock shares.

MUTUAL
     A mutual fund account containing fund shares.

CURRENCY
     Denotes a currency trading account. In many ways, a currency trading account is like a stock trading account, where both quantities and prices are set. However, generally both currency and security are national currencies.

INCOME
     Denotes an income account. The GnuCash financial model does not use 'categories'. Actual accounts are used instead.

EXPENSE
     Denotes an expense account.

EQUITY = 10,
     Denotes an equity account.

General Account API
-------------------

 -- Function: Account * xaccMallocAccount (void)
     Allocate and initialize an Account. The account must be destroyed by calling xaccAccountBeginEdit followed by xaccAccountDestroy.

 -- Function: void xaccAccountDestroy (Account * ACCOUNT)
     Destroys ACCOUNT and frees all memory associated with it. This routine will also destroy the Account's children. You must call xaccAccountBeginEdit before calling this function.

 -- Function: void xaccAccountBeginEdit (Account * ACCOUNT)
     This routine, together with xaccAccountCommitEdit, provide a two-phase-commit wrapper for account updates much in the same way as XACCTRANSBEGINEDIT and XACCTRANSCOMMITEDIT do for Transactions.

 -- Function: void xaccAccountCommitEdit (Account * ACCOUNT)
     The counterpart to XACCACCOUNTBEGINEDIT.

 -- Function: Account * xaccCloneAccountSimple (const Account * FROM)
     Return a 'copy' of FROM that is identical in the type, name, code, description, kvp data, and currency. All other fields are the same as an account returned by xaccMallocAccount.

 -- Function: const GUID * xaccAccountGetGUID (Account * ACCOUNT)
     Return the globally unique id associated with ACCOUNT.

 -- Function: Account * xaccAccountLookup (const GUID * GUID)
     Return the Account associated with GUID, or NULL if there is no such Account.

 -- Function: kvp_frame * xaccAccountGetSlots (Account * ACCOUNT)
     Return the kvp_frame associated with ACCOUNT. User code may modify this kvp_frame, but must not destroy it.

 -- Function: void xaccAccountSetSlots_nc (Account * ACCOUNT, kvp_frame * FRAME)
     Set the kvp_frame associated wih ACCOUNT. After the call, FRAME is owned by ACCOUNT, so don't destroy it.

Account Type API
----------------

 -- Function: const char * xaccAccountGetTypeStr (GNCAccountType TYPE)
     Return a string corresponding to the given Account type suitable for display by a GUI. The string is translated with gettext according to the current locale.

 -- Function: char * xaccAccountTypeEnumAsString (GNCAccountType TYPE)
     Return a string corresponding to the given Account type. The string is not translated and is independent of the current locale.

 -- Function: gboolean xaccAccountStringToType (const char * STR, GNCAccountType * TYPE)
     Converts a string of the form returned by xaccAccountTypeEnumAsString to a type, return in TYPE. Returns true if the string corresponds to an actual type.

 -- Function: GNCAccountType xaccAccountStringToEnum (const char * STR)
     Similar to xaccAccountStringToEnum, but returns the type. If STR does not correspond to any valid type, BAD_TYPE is returned.

 -- Function: gboolean xaccAccountTypesCompatible (GNCAccountType PARENT_TYPE, GNCAccountType CHILD_TYPE)
     Returns TRUE if accounts of type PARENT_TYPE can have child accounts of type CHILD_TYPE. This compatibility is not enforced by the engine, but one day it may be!

Account Getters
---------------

 -- Function: GNCAccountType xaccAccountGetType (Account * ACCOUNT)
     Return the type of ACCOUNT.

 -- Function: const char * xaccAccountGetName (Account * ACCOUNT)
     Return the name of ACCOUNT.

 -- Function: const char * xaccAccountGetCode (Account * ACCOUNT)
     Return the code of ACCOUNT.

 -- Function: const char * xaccAccountGetDescription (Account * ACCOUNT)
     Return the description of ACCOUNT.

 -- Function: const char * xaccAccountGetNotes (Account * ACCOUNT)
     Return the notes of ACCOUNT.

 -- Function: gnc_commodity * xaccAccountGetCurrency (Account * ACCOUNT)
     Return the currency of ACCOUNT.

 -- Function: int xaccAccountGetCurrencySCU (Account * ACCOUNT)
     Return the SCU (smallest convertible unit) of ACCOUNT's currency.

 -- Function: gnc_commodity * xaccAccountGetSecurity (Account * ACCOUNT)
     Return the security of ACCOUNT. For accounts without shares, this field will be NULL.

 -- Function: int xaccAccountGetSecuritySCU (Account * ACCOUNT)
     Return the SCU (smallest convertible unit) of ACCOUNT's security.

 -- Function: gnc_commodity * xaccAccountGetEffectiveSecurity (Account * ACCOUNT)
     Get the `effective' security of the account. If the account has a non-NULL security field, that field will be returned. Otherwise, the currency will be returned.

 -- Function: AccountGroup * xaccAccountGetChildren (Account * ACCOUNT)
     Return the child group of ACCOUNT. The child group may be NULL, indicating ACCOUNT has no children.

 -- Function: AccountGroup * xaccAccountGetParent (Account * ACCOUNT)
     Return the parent Group of ACCOUNT. The parent may be NULL, indicating ACCOUNT is a top-level Account. However, even if the parent is not NULL, the account may still be top-level if the parent Group has no parent Account.

 -- Function: Account * xaccAccountGetParentAccount (Account * ACCOUNT)
     Similar to xaccAccountGetParent, but returns the parent Account of the parent Group if the parent Group exists. Otherwise, returns NULL.

 -- Function: gnc_numeric xaccAccountGetBalance (Account * ACCOUNT)
     Return the balance of ACCOUNT, which is also the balance of the last Split in ACCOUNT. If there are no Splits, the balance is zero. The balance is denominated in the Account currency.

 -- Function: gnc_numeric xaccAccountGetClearedBalance (Account * ACCOUNT)
     Return the cleared balance of ACCOUNT. The cleared balance is the balance of all Splits in ACCOUNT which are either cleared or reconciled or frozen. The cleared balance is denominated in the Account currency.

 -- Function: gnc_numeric xaccAccountGetReconciledBalance (Account * ACCOUNT)
     Return the reconciled balance of ACCOUNT. The reconciled balance is the balance of all Splits in ACCOUNT which are reconciled or frozen.  The reconciled balance is denominated in the Account currency.

 -- Function: gnc_numeric xaccAccountGetShareBalance (Account *account)
     Return the share balance of ACCOUNT, which is also the share balance of the last Split in ACCOUNT. If there are no Splits, the balance is zero. The balance is denominated in the Account security, if the Account security exits; otherwise the share balance is denominated in the Account currency.

 -- Function: gnc_numeric xaccAccountGetShareClearedBalance (Account * ACCOUNT)
     Return the cleared share balance of ACCOUNT. The cleared share balance is the share balance of all Splits in ACCOUNT which are either cleared or reconciled or frozen. The cleared share balance is denominated as the share balance.

 -- Function: gnc_numeric xaccAccountGetShareReconciledBalance (Account * ACCOUNT)
     Return the reconciled share balance of ACCOUNT. The reconciled share balance is the share balance of all Splits in ACCOUNT which are reconciled or frozen. The reconciled sharea balance is denominated as the share balance.

 -- Function: gnc_numeric xaccAccountGetBalanceAsOfDate (Account * ACCOUNT, time_t DATE)
     Return the balance of ACCOUNT including all Splits whose parent Transactions have posted dates on or before DATE.

 -- Function: gnc_numeric xaccAccountGetShareBalanceAsOfDate (Account * ACCOUNT, time_t DATE)
     Return the share balance of ACCOUNT including all Splits whose parent Transactions have posted dates on or before DATE.

 -- Function: Split * xaccAccountGetSplit (Account * ACCOUNT, int I)
     Return the Ith Split in ACCOUNT. If I < 0 or I >= number of splits in ACCOUNT, then NULL is returned. This function is O(number of splits in account).

 -- Function: int xaccAccountGetNumSplits (Account * ACCOUNT)
     Return the number of Splits in ACCOUNT. This function is O(number of splits in account).

 -- Function: GList * xaccAccountGetSplitList (Account * ACCOUNT)
     Return a GList of the Splits in ACCOUNT. This list must not be modified in any way.

 -- Function: char * xaccAccountGetFullName (Account * ACCOUNT, const char SEPARATOR)
     Returns the fully qualified name of ACCOUNT using the given separator character. The name must be g_freed after use. The fully qualified name of an account is the concatenation of the names of the account and all its ancestor accounts starting with the topmost account and ending with the given account. Each name is separated by the given character.

Account Tax API
---------------

This set of API calls is related to tax information. All accounts have a tax-related boolean flag that can be set or unset. There is an additional set of API calls related to United States taxes that have `US' in the function call names. Future API calls that are specific to other countries should include the appropriate 2-letter country code in the function names.

 -- Function: gboolean xaccAccountGetTaxRelated (Account * ACCOUNT)
     Return the tax-related flag of ACCOUNT.

 -- Function: void xaccAccountSetTaxRelated (Account * ACCOUNT, gboolean TAX_RELATED)
     Set the tax-related flag of ACCOUNT.

 -- Function: const char * xaccAccountGetTaxUSCode (Account * ACCOUNT)
     Get the US-specific tax code associated with ACCOUNT, or NULL if there is none. These codes are internal to GnuCash and currently defined in src/scm/report/txf-export.scm.

 -- Function: void xaccAccountSetTaxUSCode (Account * ACCOUNT, const char * CODE)
     Set the US-specific tax code associated with ACCOUNT.

 -- Function: const char * xaccAccountGetTaxUSPayerNameSource (Account * ACCOUNT)
     Get the payer name source associated with ACCOUNT. See src/scm/repot/taxtxf.scm for details.

 -- Function: void xaccAccountSetTaxUSPayerNameSource (Account * ACCOUNT, const char * SOURCE)
     Set the payer name source associated with ACCOUNT.

Account Groups
==============

Account Groups are used by the Engine to connect Accounts together into an Account hierarchy. Account Groups do not correspond to any accounting concept -- they are specific to the GnuCash engine. Account Groups contain the following pieces of information:

A list of Accounts
     The list Accounts in the Group.

A not-saved flag
     Indicates whether any information in the hierarchy rooted at the Group needs to be saved. That includes Accounts, Splits, and Transactions.

Account Groups do not have key-value frames or GUIDs.

General Account Group API
-------------------------

 -- Function: AccountGroup * xaccMallocAccountGroup (void)
     Return a newly-allocated & initialized Account Group. The Group must be freed with xaccFreeAccountGroup.

 -- Function: void xaccFreeAccountGroup (AccountGroup * ACCOUNT_GROUP)
     Free the given Group and all its resources, including the Accounts.

 -- Function: void xaccAccountGroupCommitEdit (AccountGroup * GRP)
     Recursively call xaccAccountCommitEdit on all child accounts and their children.

 -- Function: void xaccGroupConcatGroup (AccountGroup * TO, AccountGroup * FROM)
     Move all accounts in FROM to TO. After this function returns, FROM will have been destroyed.

 -- Function: void xaccGroupMergeAccounts (AccountGroup * GRP)
     Merge all accounts in GRP that have the same name and description. The semantics of this function are rather complex. Consult the implementation before use!

 -- Function: gboolean xaccGroupNotSaved (AccountGroup * GRP)
     Return true if GRP has changes which have not been saved.

 -- Function: void xaccGroupMarkSaved (AccountGroup * GRP)
     Mark GRP and all its children as saved.

 -- Function: void xaccGroupMarkNotSaved (AccountGroup * GRP)
     Mark GRP as not saved.

 -- Function: void xaccGroupMarkDoFree (AccountGroup * GRP)
     Mark all accounts in GRP as slated for destruction. This will improve the efficiency of destroying a large account hierarchy.

Account Group Account API
-------------------------

 -- Function: void xaccGroupRemoveAccount (AccountGroup * GRP, Account * ACCOUNT)
     Remove ACCOUNT from GRP. If ACCOUNT is not in GRP, the function will return without performing any action. In no case will ACCOUNT be destroyed or modified.

 -- Function: void xaccAccountRemoveGroup (Account * ACC)
     Remove ACC's child group. The child group is not otherwise modified or destroyed.

 -- Function: void xaccGroupInsertAccount (AccountGroup * GRP, Account * ACC)
     Add ACC to GRP. If ACC is in another Group, it will be removed first.

 -- Function: void xaccAccountInsertSubAccount (Account * PARENT, Account * CHILD)
     Like xaccGroupInsertAccount, but uses a parent Account instead of a parent group. If PARENT does not have a child Group, one will be created.

 -- Function: int xaccGroupGetNumSubAccounts (AccountGroup * GRP)
     Return the total number of Accounts in the hierarchy rooted at GRP.

 -- Function: int xaccGroupGetNumAccounts (AccountGroup * GRP)
     Return the number of accounts in GRP. This count does not include Accounts lower in the hierarchy.

 -- Function: int xaccGroupGetDepth (AccountGroup * GRP)
     Returns the length of the longest tree branch in the hierarchy rooted at GRP. Each link between an Account and its (non-null) children counts as one unit of length.

 -- Function: Account * xaccGroupGetAccount (AccountGroup * GROUP, int INDEX)
     Return the INDEXth Account in GROUP, starting at zero. If INDEX is out of range, NULL is returned.

 -- Function: GList * xaccGroupGetSubAccounts (AccountGroup * GRP)
     Return a list of the Accounts, including sub-Accounts, in GRP. The returned list should be freed with g_list_free when no longer needed.

 -- Function: GList * xaccGroupGetAccountList (AccountGroup * GRP)
     Return a list of the immediate children of GRP. The returned list should not be freed or modified in any way.

GNCBooks
========

The GNCBook interface encapsulates all the information about a GnuCash dataset, including the methods used to read and write the dataset to datastores.  This class provides several important services:

  * Prevents multiple users from editing the same file at the same time, thus avoiding lost data due to race conditions. Thus an 'open book' implies that the associated file is locked.

  * Provides a search path for the file to be edited. This should simplify install & maintenance problems for users who may not have a good grasp of what a file system is, or where they want to keep their data files.

The current implementation assumes the use of files and file locks; however, the API was designed to be general enough to allow the use of generic URL's, and/or implementation on top of SQL or other database/persistant object technology.

GNCBook API
-----------

 -- Function: GNCBook * gnc_book_new (void)
     Allocate, initialize, and return a new GNCBook. The new book will contain a newly allocated AccountGroup.

 -- Function: void gnc_book_destroy (GNCBook * BOOK)
     End any editing session associated with BOOK, and free all memory associated with it.

 -- Function: gboolean gnc_book_begin (GNCBook * BOOK, const char * BOOK_ID, gboolean ignore_lock, gboolean create_if_nonexistent)
     Begins a new book editing sesssion. It takes as an argument the book id. The book id must be a string in the form of a URI/URL.  In the current implementation, only one type of URI is supported, and that is the file URI: anything of the form file:/home/somewhere/somedir/file.xac The path part must be a valid path.  The file-part must be a valid GnuCash data file. Paths may be relative or absolute. If the path is relative; that is, if the argument is file:somefile.xac then a sequence of search paths are checked for a file of this name.

     The 'ignore_lock' argument, if set to TRUE, will cause this routine to ignore any file locks that it finds.  If set to FALSE, then file locks will be tested and obeyed.

     If the file exists, can be opened and read, and a lock can be obtained then a lock will be obtained and the function returns TRUE.

     If the file/database doesn't exist, and the create_if_nonexistent flag is set to TRUE, then the database is created.

     Otherwise the function returns FALSE.

 -- Function: gboolean gnc_book_load (GNCBook * BOOK)
     Load the data associated with the book. The function returns TRUE on success.

 -- Function: GNCBackendError gnc_book_get_error (GNCBook * BOOK)
     Obtain the reason for a failure. Standard errno values are used. Calling this routine resets the error value. This routine allows an implementation of multiple error values, e.g. in a stack, where this routine pops the top value. The current implementation has a stack that is one-deep.

     Some important error values:

     EINVAL
          bad argument

     ETXTBSY
          book id is in use; it's locked by someone else

     ENOSYS
          unsupported URI type

     ERANGE
          file path too long

     ENOLCK
          book not open when gnc_book_save() was called.

 -- Function: const char * gnc_book_get_error_message (GNCBook * BOOK)
     Return a string describing the reason for the current error. Calling this routine resets the error value.

 -- Function: GNCBackendError gnc_book_pop_error (GNCBook * BOOK)
     Same as gnc_book_get_error, but the error value is reset in BOOK.

 -- Function: AccountGroup * gnc_book_get_group (GNCBook * BOOK)
     Return the current top-level account group.

 -- Function: void gnc_book_set_group (GNCBook * BOOK, AccountGroup * TOPGROUP)
     Set the topgroup to a new value.

 -- Function: const char * gnc_book_get_file_path (GNCBook * BOOK)
     Return the fully-qualified file path for the book. That is, if a relative or partial filename was for the book, then it had to have been fully resolved to open the book. This routine returns the result of this resolution.

 -- Function: gboolean gnc_book_save_may_clobber_data (GNCBook * BOOK)
     Return TRUE if saving the book would overwrite other information.

 -- Function: void gnc_book_save (GNCBook * BOOK)
     Commit all changes that have been made to the book.

 -- Function: void gnc_book_end (GNCBook * BOOK)
     Release the session lock. It will not save the account group to a file. Thus, this method acts as an "abort" or "rollback" primitive.

Scrub
=====