This is gnucash-design.info, produced by makeinfo version 4.1 from
gnucash-design.texinfo.


INFO-DIR-SECTION Programming

START-INFO-DIR-ENTRY
* gnucash: (gnucash-design).       Design of the GnuCash program
END-INFO-DIR-ENTRY


   This file documents the design of the GnuCash program.

   Copyright 2000 Gnumatic Incorporated

   This is Edition 1.8.4, last updated 13 August 2001, of the `GnuCash
Design Document', version 1.8.4.

   Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
any later version published by the Free Software Foundation; with the
Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts
being LIST, and with the Back-Cover Texts being LIST.  A copy of the
license is included in the section entitled "GNU Free Documentation
License".


File: gnucash-design.info,  Node: Standard Numeric Arguments,  Next: Creating Numeric Objects,  Prev: Numeric Library,  Up: Numeric Library

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.


File: gnucash-design.info,  Node: Creating Numeric Objects,  Next: Basic Arithmetic Operations,  Prev: Standard Numeric Arguments,  Up: Numeric Library

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.


File: gnucash-design.info,  Node: Basic Arithmetic Operations,  Next: Numeric Comparisons and Predicates,  Prev: Creating Numeric Objects,  Up: Numeric Library

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

   See *Note 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.


File: gnucash-design.info,  Node: Numeric Comparisons and Predicates,  Next: Numeric Denominator Conversion,  Prev: Basic Arithmetic Operations,  Up: Numeric Library

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 (*note 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.


File: gnucash-design.info,  Node: Numeric Denominator Conversion,  Next: Numeric Floating Point Conversion,  Prev: Numeric Comparisons and Predicates,  Up: Numeric Library

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. *Note 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.


File: gnucash-design.info,  Node: Numeric Floating Point Conversion,  Next: Numeric String Conversion,  Prev: Numeric Denominator Conversion,  Up: Numeric Library

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.


File: gnucash-design.info,  Node: Numeric String Conversion,  Next: Numeric Error Handling,  Prev: Numeric Floating Point Conversion,  Up: Numeric Library

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.


File: gnucash-design.info,  Node: Numeric Error Handling,  Next: Numeric Example,  Prev: Numeric String Conversion,  Up: Numeric Library

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.


File: gnucash-design.info,  Node: Numeric Example,  Prev: Numeric Error Handling,  Up: Numeric Library

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));
         }
       }
     }


File: gnucash-design.info,  Node: Key-Value Pair Frames,  Next: Events,  Prev: Numeric Library,  Up: Engine

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.

* Menu:

* Key-Value Policy::
* kvp_frame::
* kvp_value::
* kvp_list::


File: gnucash-design.info,  Node: Key-Value Policy,  Next: kvp_frame,  Prev: Key-Value Pair Frames,  Up: Key-Value Pair Frames

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.



File: gnucash-design.info,  Node: kvp_frame,  Next: kvp_value,  Prev: Key-Value Policy,  Up: Key-Value Pair Frames

kvp_frame
---------

   A `kvp_frame' is the datatype used to associate key strings with
`kvp_value' objects (*note 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).


File: gnucash-design.info,  Node: kvp_value,  Next: kvp_list,  Prev: kvp_frame,  Up: Key-Value Pair Frames

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. *Note 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)


File: gnucash-design.info,  Node: kvp_list,  Prev: kvp_value,  Up: Key-Value Pair Frames

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.


File: gnucash-design.info,  Node: Events,  Next: Commodities,  Prev: Key-Value Pair Frames,  Up: Engine

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).

* Menu:

* Event API::


File: gnucash-design.info,  Node: Event API,  Prev: Events,  Up: Events

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.


File: gnucash-design.info,  Node: Commodities,  Next: Commodity Tables,  Prev: Events,  Up: Engine

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.

* Menu:

* General Commodity API::
* Commodity Getters::
* Commodity Setters::


File: gnucash-design.info,  Node: General Commodity API,  Next: Commodity Getters,  Prev: Commodities,  Up: Commodities

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.


File: gnucash-design.info,  Node: Commodity Getters,  Next: Commodity Setters,  Prev: General Commodity API,  Up: Commodities

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.


File: gnucash-design.info,  Node: Commodity Setters,  Prev: Commodity Getters,  Up: Commodities

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.


File: gnucash-design.info,  Node: Commodity Tables,  Next: Prices,  Prev: Commodities,  Up: Engine

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.

* Menu:

* General Commodity Table API::
* Commodity Table Access API::
* Commodity Table Modification API::


File: gnucash-design.info,  Node: General Commodity Table API,  Next: Commodity Table Access API,  Prev: Commodity Tables,  Up: Commodity Tables

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.


File: gnucash-design.info,  Node: Commodity Table Access API,  Next: Commodity Table Modification API,  Prev: General Commodity Table API,  Up: Commodity Tables

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.


File: gnucash-design.info,  Node: Commodity Table Modification API,  Prev: Commodity Table Access API,  Up: Commodity Tables

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.


File: gnucash-design.info,  Node: Prices,  Next: Price Databases,  Prev: Commodity Tables,  Up: Engine

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".

* Menu:

* Price Implementation Details::
* General Price API::
* Price Getters::
* Price Setters::


File: gnucash-design.info,  Node: Price Implementation Details,  Next: General Price API,  Prev: Prices,  Up: Prices

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.


File: gnucash-design.info,  Node: General Price API,  Next: Price Getters,  Prev: Price Implementation Details,  Up: Prices

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.


File: gnucash-design.info,  Node: Price Getters,  Next: Price Setters,  Prev: General Price API,  Up: Prices

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.


File: gnucash-design.info,  Node: Price Setters,  Prev: Price Getters,  Up: Prices

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.


File: gnucash-design.info,  Node: Price Databases,  Next: Splits,  Prev: Prices,  Up: Engine

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

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

* Menu:

* Price Lists::
* General Price Database API::


File: gnucash-design.info,  Node: Price Lists,  Next: General Price Database API,  Prev: Price Databases,  Up: Price Databases

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.


File: gnucash-design.info,  Node: General Price Database API,  Prev: Price Lists,  Up: Price Databases

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.


File: gnucash-design.info,  Node: Splits,  Next: Transactions,  Prev: Price Databases,  Up: Engine

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.
     *Note 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.

* Menu:

* General Split API::
* Split Getters::
* Split Setters::


File: gnucash-design.info,  Node: General Split API,  Next: Split Getters,  Prev: Splits,  Up: Splits

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.


File: gnucash-design.info,  Node: Split Getters,  Next: Split Setters,  Prev: General Split API,  Up: Splits

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 *Note Accounts:: for details.

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

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

 - Function: gnc_numeric xaccSplitGetShareBalance (Split * SPLIT)
     Return the share balance of SPLIT's parent Account up to and
     including SPLIT. See *Note 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 *Note 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 *Note 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.

