                                 DRAFT

                     GEDCOM Library, Version .077
                           December 18, 1991


 
This document describes a library of public domain C functions that take much of the work out
of programming with GEDCOM-format data.  Readers should have a basic understanding of
GEDCOM plus programming experience in C. 

WARNING: this release is experimental --  future versions may not be compatible with your
code written using this release.  It is released for the brave, to gain the experience necessary to
verify whether the approach is right.  With that experience, hopefully by the next release, we
will release a production 1.0 version.  Programs using 1.0 and later releases can count on a
reasonable degree of upward compatibility.
 
Feedback, suggestions, and additions are needed to enable this library to fulfill its purpose. 
Please contact: 
 
     Bill Harten 
     GEDCOM Developers Group 
     50 East North Temple Street 
     Salt Lake City, UT 84150 
 
     Phone (801) 240-5225 


LIBRARY MAINTENANCE 
 
Users of this GEDCOM library are encouraged to add to the library to suit their requirements. 
Extensions should be general enough to be usable by others, and their design and
documentation should be consistent with that of the other functions in the library. Additions
and changes will be approved by the custodian of the GEDCOM library.  Changes that impact
existing users must first be approved by existing users, as represented in the GEDCOM User's
Group. 


Portability

This code is intended to be portable and has had some testing performed on IBM PC's
compiled with Microsoft C 6.0, Borland C++ 2.0, and the CYBER 992 under NOS/VE.  In
order to compile on a CYBER, the include file in each .c file must be changed to be gedcom_h
instead of gedcom.h and CYBER must be defined.  If you have a compiler which does not
support the ANSI standard, define NON_ANSI when compiling.

Table Of Contents




Library Organization. . . . . . . . . . . . . . . . . . . . . . .  1-1
     Basic GEDCOM System. . . . . . . . . . . . . . . . . . . . .  1-1
     GEDCOM Processing System . . . . . . . . . . . . . . . . . .  1-5
     GEDHASH System . . . . . . . . . . . . . . . . . . . . . . .  1-6

Basic GEDCOM System . . . . . . . . . . . . . . . . . . . . . . .  2-1
          BACKGROUND. . . . . . . . . . . . . . . . . . . . . . .  2-1
          DESIGN OBJECTIVES . . . . . . . . . . . . . . . . . . .  2-1
     Basic GEDCOM Functions . . . . . . . . . . . . . . . . . . .  2-4

The GEDCOM Processor. . . . . . . . . . . . . . . . . . . . . . .  3-1
          Features of the GEDCOM processor. . . . . . . . . . . .  3-1
          Overview. . . . . . . . . . . . . . . . . . . . . . . .  3-1
     The GEDCOM Processor Functions . . . . . . . . . . . . . . .  3-3

GEDHASH System. . . . . . . . . . . . . . . . . . . . . . . . . .  4-1
          Purpose of GEDHASH. . . . . . . . . . . . . . . . . . .  4-1
          Memory Management . . . . . . . . . . . . . . . . . . .  4-1
     The GEDHASH Functions. . . . . . . . . . . . . . . . . . . .  4-2

Library Organization

The GEDCOM library is organized into three basic systems and their various categories of
functions.  A glance at the library structure can be of assistance:

Basic GEDCOM System:     Error Handling
                         Memory Management Functions
                         Accessor Functions
                         Tag Searching and Remote Process Communication
Functions

GEDCOM Processor System: Processor Interface Functions
                         Utility Functions or Hooks.

GEDHASH System:               Basic Setup and Interface Functions

Following is an index of the functions available in the GEDCOM library, organized within their
respective categories:

Basic GEDCOM System

Error Handling

void   ged_set_error_handler( int (*error_handler)(int, NODE *); (Page 2-53)
       Set the static global ged_error_handler to point to a user-defined error handler.

Memory Management

char   * GED_ALLOC_POOL(unsigned long size); (Page 2-4)
       Macro.  Allocates size bytes from the current pool.

POOL   * ged_create_pool(unsigned size, unsigned nodeSize); (Page 2-19)
       Creates a pool with size bytes, and nodeSize as the default node size.

void   GED_DESTROY_POOL(); (Page 2-20)
       Releases the memory in the current pool, then releases the pool itself.  Pool may not
       be reused.  See also ged_reset_pool.

POOL   * ged_get_pool(); (Page 2-26)
       Returns a pointer to the current pool.
POOL  * GED_RESET_POOL(); (Page 2-51)
       Resets the memory in the memory pool currently in use.  Pool may be reused.  See
       also ged_destroy_pool.

POOL   * ged_set_pool(POOL *pool); (Page 2-57)
       Causes subsequent memory allocations to be drawn from pool.


Create/Update Internal Form

NODE   * ged_ask(NODE *obj, NODE *msg, int *nth); (Page 2-6)
       Return the nth occurrence of node in obj at the end of path msg, with its children.

NODE   * ged_ask_string(NODE *obj, char *msg, int *nth); (Page 2-8)
       Create path msg, then return the nth occurrence of node in obj at msg, with its
       children.

NODE   * ged_ask_xref(NODE *obj, char *xref); (Page 2-10)
       Find and return the node in obj with cross reference identifier xref.

NODE   * ged_get_child(NODE *node); (Page 2-21)
       Get a pointer to the first child of node.

NODE   * ged_get_last_sibling(NODE *node); (Page 2-22)
       Get a pointer to the last sibling of node.

char   * ged_get_line(NODE *node); (Page 2-23)
       Get the line (xref, tag and value) from node.

NODE   * ged_get_next_node(NODE *node); (Page 2-24)
       Get the next node in the tree in a preorder traversal.

NODE   * ged_get_parent(NODE *node); (Page 2-25)
       Get a pointer to the parent of node.

NODE   * ged_get_previous_node(NODE *node); (Page 2-27)
       Get a pointer to the previous node in a preorder traversal of the tree.

NODE   * ged_get_previous_sibling(NODE *node); (Page 2-28)
       Get a pointer to the node directly before the current node in the sibling list.

NODE   * ged_get_sibling(NODE *node); (Page 2-29)
       Get a pointer to the sibling of node.

char   * ged_get_tag(NODE *node); (Page 2-30)
       Get the tag from node.
char   * ged_get_value(NODE *node); (Page 2-31)
       Get the value from node.


char   * ged_get_xref(NODE *node); (Page 2-32)
       Get the xref from node.

int    ged_inherits(NODE *node1, NODE *node2); (Page 2-33)
       Does the tag in node1 inherit from that tag in node2.  Currently only checks to see if
       the tags are the same, but in the future will check to see if the tags are related, for
       example, marriage and banns.


int    ged_match(char *line1, char *line2); (Page 2-36)
       Compare the first words on line1 and line2.

int    ged_match_tags(NODE *node1, NODE *node2); (Page 2-37)
       Compare the tags in node1 and node2.


Manipulate Internal Form

void   ged_clip_word(char *wordPtr); (Page 2-11)
       Takes out all trailing spaces from a word by adding NULL to the end of the
       word.

NODE   * ged_clone_node(char *line, NODE *child, NODE *sibling); (Page 2-12)
       Makes a node with contents line, and connects it to child and sibling.  Does
       not copy line. See also ged_copy_tree.

NODE   * ged_clone_tree(NODE *tree); (Page 2-13)
       Makes a copy of the input tree. Does not make a copy of the data, but points at the
       data in the input tree.

NODE   * ged_connect_child(NODE *parent, NODE *child, int pos); (Page 2-14)
       Connect child to parent at position pos in the child sibling list.

NODE   * ged_connect_sibling(NODE *sibiling1, NODE *sibling2, int pos); (Page 2-15)
       Connect sibling2 to sibling1 at position pos in the sibling list.

NODE   * ged_copy_node(char *line, NODE *child, NODE *sibling); (Page 2-16)
       Makes a node and connects it to child and sibling. Uses it's own copy of line. 
       Used for convenience in creating an internal tree from within a program.

NODE   * ged_copy_tree(NODE *tree); (Page 2-18)
       Makes a copy of the input tree. Makes its own copy of the data from the input tree also.
NODE   * ged_make_path(char *path); (Page 2-34) 
       Makes a path of child nodes from the string path.  Used for convenience in creating a
       request tree path for the ged_ask function.

void   ged_promote(NODE *node); (Page 2-41 )
       Moves node and its siblings to the parents position.

NODE   * ged_prune_tree(NODE *root);  (Page 2-42)
       Remove all the nodes in the tree with no value, and no children.

void   ged_remove_node(NODE *node);  (Page 2-47)
       Remove node and move all its children up a level in the tree.

NODE   * ged_remove_subtree(NODE *node);  (Page 2-49)
       Remove node and all its children from the tree.

char   * ged_set_line(NODE *node, char *line);  (Page 2-52)
       Set the line in node to be line.

char   * ged_set_tag(NODE *node, char *tag);  (Page 2-58)
       Set the tag in node to be tag.

char   * ged_set_value(NODE *node, char *value);  (Page 2-59)
       Set the value in node to be value.

char   * ged_set_xref(NODE *node, char *xref);  (Page 2-60)
       Set the xref in node to be xref.

char   * ged_skip_word(char *wordPtr);  (Page 2-61)
       Skips the word that wordPtr is pointing to and returns the address of the
       next word.


Internal/External Conversion and File I/O

void   ged_print_indented(NODE *tree, FILE *stream);  (Page 2-39)
       Does a preorder traversal of the input tree and prints it indenting each level.

void   ged_print_levels(NODE *tree, FILE *stream);  (Page 2-40)
       Does a preorder traversal of the input tree and prints it with level numbers.

char   * ged_read_rec(FILE *fp, char *gedBuf, unsigned limit, int *status);  (Page 2-43)
       Reads a GEDCOM record (bounded by next level equal or less than the
       start level) from the file pointed to by fp and puts it in gedBuf.

NODE   * ged_read_tree(FILE *fp, char *gedBuf, unsigned limit, int *status);  (Page 2-45)
       Reads the file pointed to by fp and returns a corresponding tree.

NODE   * ged_to_tree(char **gedBuf, int *status);  (Page 2-62)
       Takes the GEDCOM data in gedBuf and returns the corresponding tree.

char   * ged_tree_to_ged(NODE *tree, char *gedBuf, unsigned limit, unsigned level);
       (Page 2-66)
       Converts tree to external form and puts it in gedBuf.

void   ged_tree_to_file(NODE *tree, FILE *fp, unsigned level);  (Page 2-64)
       Converts the tree to external form and saves it to the file pointed to by fp starting
       with level.


GEDCOM Processing System

Processor Interface Functions

int    ged_define_semantic(byte *funcName,  int (*funcPointer)(NODE *, byte *)); (Page
3-7)
       Registers the functions hooks.

int    ged_process(FILE *fg, FILE *ft); (Page 3-3)
       Loads the grammar file and a data tree into memory, and then processes it.

int    ged_traverse(NODE *dataCtxt, NODE *grammarCtxt); (Page 3-5)
       Traverses the nodes of the grammar and data trees, calling any associated hooks.

NODE   * ged_load_grammar(FILE *fg); (Page 3-4)
       Loads a GEDCOM grammar into memory.
GEDHASH System


Basic Setup and Interface Functions

char   * gedhash_get_drive(void); (Page 2-55)
       Returns drive of the GEDCOM file opened by gedhash_fopen() or
       gedhash_get_rec_xref().  When working with multiple-disk GEDCOM files, this
       function is called by the user-defined error-handler to prompt the user into which
       drive to insert the next floppy disk.

char   * gedhash_get_file(void); (Page 2-55)
       Returns file name of the GEDCOM file opened by gedhash_fopen() or
       gedhash_get_rec_xref().  See gedhash_get_drive().  The returned file name includes
       the correct extension, i.e., ".GED," ".G00," ".G01," etc.

int    gedhash_close_table(HASH_TAB *htab); (Page 4-6)
       Closes a hash table.

int    gedhash_copy(HASH_TAB *htab_dest, HASH_TAB *htab_source);
       Copies contents from htab_source to htab_dest. (Page 4-3) 


HASH_TAB  * gedhash_create_table(HASH_TAB *htab, char * perm_file,
          HSIZ hash_size, MEMSIZ max_memory);
       Creates a hash table. (Page 4-4)
       
long   GEDHASH_COUNT(HASH_TAB *htab);  (Page 4-4)
       This macro returns the number of keys currently held in the table.

int    gedhash_delete(HASH_TAB *htab, char * key, KSIZ keyLen); (Page 4-9)
       Finds the key in the hash table and deletes its cell. 

int    gedhash_destroy_table(HASH_TAB *htab);  (Page 4-10)
       Destroys the hash table, releasing its memory and deleting the hash file, if any.

FILE   * gedhash_fopen(HASH_TAB *htab, char *gedcom_path, char *mode);
       Opens the gedcom file that is associated with htab and copies gedcom_path to
       htab->gedfn.   htab->ged_ext is initialized to -1.

int    gedhash_insert(HASH_TAB *htab, void *key, KSIZ keyLen, void *val, LEN valLen);
       (Page 4-13)
       Adds new key/value pair to the hash table, overwriting any existing pair of the same
key.

int    gedhash_iterate(HASH_TAB *htab, void *key, KSIZ *keyLen, void *val,
          LEN *valLen);  (Page 4-14)
       Successively returns every key/value pair in the hash table.

void   gedhash_iterate_reset(HASH_TAB *htab); (Page 4-15)
       Resets internal hash-tab state so that successive calls to gedhash_iterate() will return
       every key/value pair in the table.

void   * gedhash_lookup(HASH_TAB *htab, void *key, KSIZ keyLen, void *val,
          LEN *valLen, int *status); (Page 4-16)
       Finds key in the table and returns a pointer to the value, val, that is associated with it.



Commonly Used GEDCOM File Searching Functions


HASH_TAB  gedhash_create_xref(char *ged_filename, char *hash_filename, HSIZ h_size);
          (Page 4-6)
          Creates a hash table and stores all xref's found in ged_filename.

NODE      * gedhash_find_xref(HASH_TAB *htab, NODE *dataCtxt); (Page 4-11)
          Returns the record referenced by the pointer in the value field of dataCtxt.


NODE      * gedhash_get_rec_xref(HASH_TAB *htab, char *value); (Page 4-12)
          Returns the record referenced by the pointer in value.
Basic GEDCOM System

BACKGROUND 
 
The GEDCOM data format is a convenient way to represent structured data in sequential
media for exchange between computer systems. However, this external form of GEDCOM is
not efficient for many kinds of processing once inside a program, because searching for specific
lines and updating records can require examining or moving each character in the buffer, one at
a time.  
 
Instead, GEDCOM programmers are encouraged to use a more efficient internal
representation, such as a tree or list made from pointer-linked nodes. Individual lines may be
located, modified, or updated by pointer manipulation, without handling unrelated lines. The
functions in this library provide a general-purpose, tree-oriented internal representation for
GEDCOM data. Functions are included for memory management, conversion between internal
and external forms of GEDCOM, and manipulation of the internal representation.


DESIGN OBJECTIVES 
 
Memory Management - GEDCOM processing requires dynamically allocating many small
chunks of memory.  Using the C language malloc function in this manner is inefficient.  This
library avoids use of malloc functions, except to obtain large pools of memory, from which many
small allocations can be made more efficiently. Allocation is accomplished by incrementing a
pointer into the pool. Pools with insufficient space are automatically lengthened as needed via
malloc.  Memory for all objects in a pool is released in one operation by resetting the pointer
to the beginning of the pool. 
 
This form of memory management is efficient in transaction-oriented systems where
memory-resident structures are discarded at the end of the transaction.  Unfortunately, some
data may need to remain when other data can be released.  This is accommodated by creating
different pools, each of which can grow and then be released independently, as a unit.  Each
type of data with a different life cycle should be created in a different pool.  The application
controls which pool is used for a series of allocations by calling the setPool function.  Be careful
to avoid pointing at released data structures. 
 
Accessor Functions - The data structures used in these functions should not be accessed directly
in any way, whether for reading, writing, or searching for tags. Accessor functions are provided
to manipulate each component of these data structures. By using only the accessor functions,
the internal representation and the functions that manipulate it can be modified or extended
without affecting the application, in most cases. If necessary, function call overhead may be
eliminated in future versions by replacing accessor function calls with inline macro expansions
using identical syntax. 
 
Tag Searching and Remote Process Communication - This library will eventually provide a
general-purpose and transparent way to extract information from any GEDCOM resource,
whether the information is in the same machine or a remote one, or whether it is simple data
or the result of a runtime calculation.   
 
The function ged_ask(resource, request, pos) makes the remote/local communication mechanism
and the tag-hunting mechanism transparent. The ged_ask function uses another accessor
function called ged_match_tags(node, node) to compare tags.  These two functions provide a
general way to obtain an answer, hiding the mechanism(s) used from the application.  This
allows for substantial future flexibility in finding and/or calculating answers without impacting
the application. 
 
In ged_ask(), both the request and the resource containing the answer are represented in
GEDCOM internal form.  The request may consist of an automated resource transaction with
parameters, or it may be a list of subordinate tags forming a path to a particular node of a
GEDCOM tree.  

If the resource is a data record, ged_ask() will traverse the record tree following the request
path into the desired node. 

If the resource is an automated system, ged_ask() will pass the request transaction to the
resource for further processing. If the resource is in the same memory space, ged_ask() will
simply pass the request pointer to the resource through a function call. If the resource is in a
remote machine or process, ged_ask() will automatically convert the request to GEDCOM
external form, route it through the communication system, wait for the response, and convert
the response back into GEDCOM internal form. The response is returned in tree form as the
result of the ged_ask() function.
 
Eventually, ged_ask(), ged_match_tags(), or similar functions may be used to access tag
classification hierarchies so that non-identical but similar tags, such as birth and christening,
may be treated similarly.  These functions may also be used to automatically compute a value
where none is provided explicitly, as in calculating the year of birth from the age at the time of
some other event, for example. 
 
Application programs will be able to modify the generic version of ged_ask() and
ged_match_tags() to meet their routing, logic and performance requirements. 


The following examples illustrate how these functions work together.  The first program shows
reading a GEDCOM file and extracting a specific value determined by a path specification.


#include "gedcom.h" 
#include <io.h>
 
main() 
    { 
    NODE *root, 
         *path; 
    FILE *fp; 
    char *gedBuf; 
    int limit, status; 
    POOL *pool;

        pool = ged_set_pool(ged_create_pool(5000, sizeof(NODE))); 
        if ((fp = fopen("ged.dat", "r")) == NULL) 
            { 
            printf("Couldn't open ged.dat for reading\n"); 
            exit(0); 
            } 
        limit = filelength(fileno(fp)) + 1; 
        gedBuf = GED_ALLOC_POOL(limit); 
        root = ged_read_tree(fp, gedBuf, limit, &status); 
        printf("The birth date is %s\n", 
        ged_get_value(ged_ask_string(root, "BIRT DATE", 1))); 
        GED_DESTROY_POOL(); 
    } 


The second program shows creating a GEDCOM internal tree inside a program, and writing
the tree in external GEDCOM form to a disk file.

#include "gedcom.h" 
 
main() 
    { 
    NODE *tree; 
    POOL *pool;
    FILE *fp; 

        if ((pool=ged_set_pool(ged_create_pool(5000,sizeof(NODE))))
            == NULL) 
            exit(0);     /* create failed */ 
        if ((fp = fopen("ged.dat", "w")) == NULL) 
            exit(0);     /* fopen failed */ 
        tree = ged_copy_node("INDI", 
                  ged_copy_node("BIRT", 
                     ged_copy_node("DATE 1901", NULL, 
                     ged_copy_node("PLAC Utah", NULL, NULL)), 
                  ged_copy_node("MARR", 
                     ged_copy_node("DATE 1917", NULL, NULL), 
                  NULL)),   /* end of MARR and BIRT */ 
               NULL);       /* end of INDI */ 
        ged_tree_to_file(tree,fp,0); /* write the tree to the file */  
      fclose(fp); 
        GED_DESTROY_POOL(); 
    }Basic GEDCOM Functions

ged_alloc_pool                                              - gedmem.c


Summary

#include <gedcom.h>

char *ged_alloc_pool(size);

unsigned size;

Description

The ged_alloc_pool function is accessed through the ged_alloc_pool element of the POOL
structure and allocates size bytes from the pool in use. If the requested size is larger than what
is available in the pool, more memory will be allocated to the pool. This amount will be the
larger of the size found in the pool slot size, which will initially be set to the size the pool was
when created, or the amount requested in ged_alloc_pool.  There is also a
GED_ALLOC_POOL macro which does not need to be accessed through the POOL structure

Return Value

The ged_alloc_pool function returns a char pointer to the allocated space. For a pointer to a
different type, type cast the return value. A NULL pointer is returned upon failure.

See Also

ged_create_pool, ged_destroy_pool, ged_get_pool, ged_reset_pool, ged_set_pool

ged_alloc_pool                                             - gedmem.c


Example

#include <gedcom.h>

main()
    {
    int *intArray;
    POOL *pool;

        /* Create a memory Pool */
        if ((pool = ged_set_pool(ged_create_pool(6000, sizeof(NODE))))
            == NULL)
            exit(0);     /* create failed */

        /* Allocate memory */
        intArray = (int *)GED_ALLOC_POOL(20*sizeof(int));
        if (intArray == NULL)
            printf("allocPool failed\n");
        else
            printf("Memory space allocated for 20 integers\n");
        GED_DESTROY_POOL();
    }
This program uses ged_alloc_pool to allocate space for 20 integers from a memory pool created
with ged_create_pool.ged_ask                                  - ask.c


Summary

#include <gedcom.h>

NODE *ged_ask(obj, msg, nth);

NODE *obj;
NODE *msg;
int   nth;

Description

The ged_ask function returns the nth occurrence of the node in the tree obj at the end of the
path msg.  Eventually, ged_ask will interact with a routing system to convert the trees obj and
msg to external GEDCOM text form, route the message, and convert the results back into
internal GEDCOM format.

Return Value

The ged_ask function returns a pointer to the NODE structure in the obj tree containing the
requested information.  ged_ask will return NULL if the requested object does not exist.  If a
number less than one is given for the nth argument the first occurrence will be returned.  If a
value greater than the number of occurrences is given, NULL will be returned.

See Also

ged_ask_string, ged_ask_xref, ged_make_path
ged_ask                                                       - ask.c


Example

#include <gedcom.h>

main()
    {
    NODE *tree,
    NODE *msg;
    POOL *pool;

        if ((pool = ged_set_pool(ged_create_pool(5000, sizeof(NODE))))
            == NULL)
            exit(0);            /* create failed */
        tree = ged_copy_node("INDI",  /* make a tree */
                   ged_copy_node("BIRT", /* child of INDI */
                       /* child of BIRT */
                       ged_copy_node("DATE 1901", NULL,
                       /* DATE sib*/
                       ged_copy_node("PLAC Utah", NULL, NULL)),
                   /* sibling of BIRT */
                   ged_copy_node("MARR", 
                       /* MARR child */
                       ged_copy_node("DATE 1917", NULL, NULL), 
                       NULL)), /* end of MARR and BIRT */
                   NULL);       /* end of INDI */
        msg = ged_make_path("MARR DATE");

        /* returns the node with "DATE 1917" */
        ged_ask(tree, msg, 1);
        GED_DESTROY_POOL();
   }

This program makes a tree, a path to the marriage date in the tree, and then retrieves the
marriage date using ged_ask.ged_ask_string                    - ask.c


Summary

#include <gedcom.h>

NODE *ged_ask_string(obj, msg, nth);

NODE *obj;
char *msg;
int    nth;

Description

The ged_ask_string function returns the nth occurrence of the node in tree obj at the end of
the path msg. Eventually, ged_ask_string will interact with a routing system to convert the trees
obj and msg to external GEDCOM text form, route the message, and convert the results back
into internal GEDCOM format.  Care must be taken when calling this function as memory is
allocated for the path each time the function is called.

Return Value

The ged_ask_string function returns a pointer to the NODE structure in the obj tree containing
the requested information.  ged_ask_string will return NULL if the requested object does not
exist.  If a number less than one is given for the nth argument the first occurrence will be
returned.  If a value greater than the number of occurrences is given, NULL will be returned.

See Also

ged_ask, ged_ask_xref
ged_ask_string                                                - ask.c


Example

#include <gedcom.h>

main()
    {
    NODE *tree;
    POOL *pool;

        if ((pool = ged_set_pool(ged_create_pool(5000,sizeof(NODE))))
            == NULL)
            exit(0);            /* create failed */
        tree = ged_copy_node("INDI",
                   ged_copy_node("BIRT", /* child of INDI */

                       /* child of BIRT */
                       ged_copy_node("DATE 1901", NULL, 

                       /* DATE sib*/
                       ged_copy_node("PLAC Utah", NULL, NULL)), 
                   ged_copy_node("MARR", /* sibling of BIRT */

                       /* MARR child */
                       ged_copy_node("DATE 1917", NULL, NULL),
                       NULL)), /* end of MARR and BIRT */
                   NULL);       /* end of INDI */

        /* returns node "DATE 1917"*/
        ged_ask_string(tree, "MARR DATE", 1);
        GED_DESTROY_POOL();
   }

This program makes a tree, and then retrieves the marriage date in the tree using
ged_ask_string.ged_ask_xref                                   - ask.c


Summary

#include <gedcom.h>

NODE *ged_ask_xref(obj, xref);

NODE *obj;
char *xref;

Description

The ged_ask_xref function finds the node in the tree obj which has cross reference xref.

Return Value

The ged_ask_xref function returns a pointer to the NODE structure in the obj tree containing
the cross reference requested. ged_ask_xref will return NULL if the requested node does not
exist.

See Also

ged_ask, ged_ask_string

Example

#include <gedcom.h>

main()
    {
    NODE *tree;
    POOL *pool;

      if (pool = ged_set_pool(ged_create_pool(5000,sizeof(NODE)))
                         == NULL)
            exit(0);            /* create failed */
            tree = ged_copy_node("INDI",
                ged_copy_node("BIRT", /* child of INDI */
                 ged_copy_node("DATE 1901", NULL, /*child of BIRT*/
                  ged_copy_node("PLAC Utah", NULL, NULL)),/*DATE sib*/
                ged_copy_node("@M1@ MARR", /* sibling of BIRT */
                 ged_copy_node("DATE 1917", NULL, NULL),/*MARR child*/
                NULL)), /* end of MARR and BIRT */
               NULL);      /* end of INDI */
            ged_ask_xref(tree, "@M1@"); /* returns node "@M1@ MARR"
*/
            GED_DESTROY_POOL();
   }

This program makes a tree, and then retrieves the marriage using ged_ask_xref.ged_clip_word- misc.c


Summary

#include <gedcom.h>

void ged_clip_word(ptr);

char *ptr;

Description

The ged_clip_word function takes out all trailing spaces from a word by adding NULL to the
end of the word ptr is pointing to.

Return Value

None.

Example

#include <gedcom.h>

main()
       {
       char line[] = "one two three four";
          
          ged_clip_word(line);     /* point to the word two */
          printf("line is now: %s", line); 
       }

This example allocates a string, and then calls ged_clip_word to remove what is after the first
word.
ged_clone_node                                               - copy.c


Summary

#include <gedcom.h>

NODE * ged_clone_node(line, child, sibling);

char *line;
NODE *child;
NODE *sibling;

Description

The ged_clone_node function creates a new node attached to line and sibling. It does not make
a new copy of line, but points to the copy passed in.

Return Value

ged_clone_node returns a pointer to the new node, or NULL if no memory is available for the
new node.

See Also

ged_copy_node, ged_clone_node, ged_clone_tree

Example

#include <gedcom.h>

NODE *tree;
POOL *pool;

main()
    {
        if ((pool=ged_set_pool(ged_create_pool(5000,sizeof(NODE))))
             == NULL)
            exit(0);            /* create failed */
        tree = ged_clone_node("INDI", 
                   ged_clone_node("NAME Jane", NULL, NULL),
                   NULL);
        GED_DESTROY_POOL();
    }

This program creates a pool with ged_create_pool sets it to be the current pool with
ged_set_pool, and then makes a tree with ged_clone_node.ged_clone_tree- copy.c


Summary

#include <gedcom.h>

NODE * ged_clone_tree(tree);

NODE *tree;

Description

ged_clone_tree makes a copy of the input tree. It does not make a copy of the data, but causes
the new tree to point at the data in the input tree.

Return Value

ged_clone_tree returns a pointer to the root node of the new tree, or NULL when no memory is
available.

See Also

ged_copy_tree, ged_clone_node, ged_copy_node

Example

#include <gedcom.h>

NODE *tree;
NODE *newTree;
POOL *pool;

main()
    {
        if ((pool = ged_set_pool(ged_create_pool(5000,sizeof(NODE))))
            == NULL)
            exit(0);            /* create failed */

        tree = ged_copy_node("INDI", 
                   ged_copy_node("NAME Jane", NULL, NULL)
                   NULL);
        newTree = ged_clone_tree(tree);
        GED_DESTROY_POOL();
    }

This program creates a pool with ged_create_pool sets it to be the current pool with
ged_set_pool, then makes a tree with ged_clone_node, and uses ged_clone_tree to make another
copy of it.ged_connect_child                                 - node.c


Summary

#include <gedcom.h>

NODE *ged_connect_child(parent, child, pos);

NODE *parent;
NODE *child;
int   pos;

Description

The ged_connect_child function connects child to parent in position pos in the sibling list of
parents children. If a negative number is assigned to pos then child will be assigned to be the
last sibling int the child sibling list.

Return Value

The ged_connect_child function returns a pointer to child, or NULL if error.

See Also

ged_connect_sibling

Example

#include <gedcom.h>

main()
    NODE *tree;
    POOL *pool;
    {
        if ((pool=ged_set_pool(ged_create_pool(5000,sizeof(NODE))))
            == NULL)
            exit(0);            /* create failed */
        tree = ged_connect_child(ged_copy_node("INDI", NULL, NULL),
                        ged_copy_node("NAME Jane", NULL, NULL), -1);
        GED_DESTROY_POOL();
    }

This program creates a pool with ged_create_pool and sets it to be the current pool with
ged_set_pool, and then makes two nodes with ged_copy_node, and connects one as a child to
the other with ged_connect_child.ged_connect_sibling         - node.c


Summary

#include <gedcom.h>

NODE *ged_connect_sibling(sibling1, sibling2, pos);

NODE *sibling1;
NODE *sibling2;
int   pos;

Description

The ged_connect_sibling function connects sibling2 to sibling1 in position pos in the sibling list
of siblings. If a negative number is assigned to pos then sibling2 will be assigned to be the last
sibling int the child sibling list.

Return Value

The ged_connect_sibling function returns a pointer to sibling2.

See Also

ged_connect_sibling

Example

#include <gedcom.h>

main()
    NODE *list;
    POOL *pool;
    {
        if ((pool=ged_set_pool(ged_create_pool(5000,sizeof(NODE))))
            == NULL)
            exit(0);            /* create failed */
        list = ged_connect_sibling(ged_copy_node("BIRT", NULL, NULL),
                                   ged_copy_node("MARR", NULL, NULL),  
                                 -1);
        GED_DESTROY_POOL();
    }

This program creates a pool with ged_create_pool and sets it to be the current pool with
ged_set_pool, and then makes two nodes with ged_copy_node, and connects one as the others
sibling with ged_connect_sibling.ged_copy_node               - copy.c


Summary

#include <gedcom.h>

NODE *ged_copy_node(line, child, sibling);

char *line;
NODE *child;
NODE *sibling;

Description

The ged_copy_node function creates a node with contents line, child child, and with sibling as its
sibling. Memory for the line and the node are drawn from the memory pool most recently
specified by ged_set_pool. The value nodeSize from the pool is used to determine the size of the
node. ged_copy_node makes the connections between child and sibling also. If the node to be
created does not have a child or sibling, enter NULL for that parameter.

Return Value

The ged_copy_node function returns a pointer to the NODE structure which was just made, or
NULL if memory was not available for a new node.

See Also

ged_clone_node, ged_copy_tree, ged_clone_tree
ged_copy_node                                                - copy.c


Example

#include <gedcom.h>

main()
    {
    NODE *tree;
    POOL *pool;

        if ((pool = ged_set_pool(ged_create_pool(5000,sizeof(NODE))))
            == NULL)
           exit(0);        /* create failed */

        /* use ged_copy_node to make a tree */
        tree = ged_copy_node("INDI",
                   ged_copy_node("NAME Jane", NULL,
                      ged_copy_node("BIRT",
                           ged_copy_node("DATE 1901", NULL,
                           ged_copy_node("PLAC Utah", NULL, NULL)),
                      ged_copy_node("MARR",
                           ged_copy_node("DATE 1917", NULL, NULL),
                           NULL))), /* end of marr, birt and name */
                      NULL);    /* end of indi */
        GED_DESTROY_POOL();
    }

This program creates a pool with ged_create_pool and sets it to be the current pool with
ged_set_pool, and then makes a tree with ged_copy_node.ged_copy_tree- copy.c


Summary

#include <gedcom.h>

NODE * ged_copy_tree(tree);

NODE * tree;

Description

ged_copy_tree makes a copy of the input tree. It also makes a copy of the data in the input tree.

Return Value

ged_copy_tree returns a pointer to the root node of the new tree, or NULL when no memory is
available.

See Also

ged_clone_tree, ged_copy_node, ged_clone_node

Example

#include <gedcom.h>

NODE *tree;
NODE *newTree;
POOL *pool;

main()
    {
        if ((pool = ged_set_pool(ged_create_pool(5000,sizeof(NODE))))
            == NULL)
            exit(0);            /* create failed */

        tree = ged_copy_node("INDI", 
                   ged_copy_node("NAME Jane", NULL, NULL)
                   NULL);
        newTree = ged_copy_tree(tree);
        GED_DESTROY_POOL();
    }

This program creates a pool with ged_create_pool sets it to be the current pool with
ged_set_pool, then makes a tree with ged_copy_node, and uses ged_copy_tree to make another
copy of it.
ged_create_pool                                            - gedmem.c


Summary

#include <gedcom.h>

POOL *ged_create_pool(size, nodeSize);

unsigned size;
unsigned nodeSize;

Description

The ged_create_pool function creates a memory pool with size bytes available in it. If more
memory is requested from the pool through ged_alloc_pool than was initially specified, more
will be allocated with either size bytes or what was requested, whichever is the larger amount.
The size slot of the POOL struct can be changed if a different amount is required for
subsequent allocations. nodeSize is the default node size when making nodes, this value may be
changed if a different node size is required. The ged_alloc_pool, ged_reset_pool, and
ged_destroy_pool functions are all accessed through the POOL structure created with
ged_create_pool.

Return Value

The ged_create_pool function returns a pointer to a POOL structure through which the
allocated memory can be accessed. If ged_create_pool fails, NULL will be returned.

See Also

ged_alloc_pool, ged_destroy_pool, ged_get_pool, ged_reset_pool, ged_set_pool

Example

#include <gedcom.h>

POOL *memPool;

main()
    {
        memPool = ged_create_pool(1000, sizeof(NODE));
        if (memPool == NULL)
            printf("Create failed\n");
        else
            printf("Create succeeded with 1000 bytes\n");
        GED_DESTROY_POOL();
    }

This program uses ged_create_pool to make a pool with 1000 bytes.ged_destroy_pool- gedmem.c


Summary

#include <gedcom.h>

void ged_destroy_pool();

Description

The ged_destroy_pool function is accessed through the ged_destroy_pool element of the POOL
structure. It deallocates the memory in the current pool as well as the structure used to hold it.
ged_destroy_pool is also available through the GED_DESTROY_POOL macro.

Return Value

There is no return value.

See Also

ged_alloc_pool, ged_create_pool, ged_get_pool, ged_reset_pool, ged_set_pool

Example

#include <gedcom.h>

POOL *memPool;

main()
    {

        /* Create a memory pool */
        if ((memPool = ged_create_pool(1000, sizeof(NODE))) == NULL)
            exit(0);    /* create failed */

        ged_set_pool(memPool);

        /* deallocate the memory pool */
        GED_DESTROY_POOL();
    }

This program uses ged_create_pool to create a memory pool, and then uses ged_destroy_pool to
deallocate the memory pool.
ged_get_child                                                 - get.c


Summary

#include <gedcom.h>

NODE *ged_get_child(node);

NODE *node;

Description

The ged_get_child function gets a pointer to the first child of node.

Return Value

The ged_get_child function returns a pointer to the first child in node, or NULL if none.

See Also

ged_get_parent, ged_get_sibling

Example

#include <gedcom.h>

POOL *pool;
NODE *tree;
NODE *child;

main()
    {
        if ((pool=(ged_set_pool(ged_create_pool(5000, sizeof(NODE)))))
            == NULL)
            exit(0);  /* Create failed */
        tree = ged_make_path("ROOT CHILD GRANDCHILD");
        child = ged_get_child(node);

        /* deallocate the memory pool */
        GED_DESTROY_POOL();
    }

This program uses ged_make_path to create a tree, and then uses ged_get_child to retrieve the
child of the root node. A pointer to the child is assigned to child.
ged_get_last_sibling                                          - get.c


Summary

#include <gedcom.h>

NODE *ged_get_last_sibling(node);

NODE *node;

Description

The ged_get_last_sibling function gets a pointer to the last sibling of node.

Return Value

The ged_get_last_sibling function returns a pointer to the last sibling of node.

See Also

Get_get_sibling, ged_get_child, ged_get_parent

Example

#include <gedcom.h>

main()
    {
    POOL *pool;
    NODE *tree;
    NODE *sibling;
    NODE *child;

        if ((pool=(ged_set_pool(ged_create_pool(5000, sizeof(NODE)))))
            == NULL)
            exit(0);  /* Create failed */
        tree = ged_make_path("ROOT CHILD GRANDCHILD");
        child = ged_get_child(tree);
        ged_connect_sibling(child, 
             ged_make_path("SIBLING1 SIBLING1CHILD"), -1);
        ged_connect_sibling(child, 
             ged_make_path("SIBLING2 SIBLING2CHILD"), -1);
        sibling = ged_get_last_sibling(child);

       /* deallocate the memory pool */
       GED_DESTROY_POOL();
    }

This program creates a tree, and then uses ged_get_child to retrieve the child of the root node,
and then ged_get_last_sibling to get the childs last sibling. ged_get_line- get.c


Summary

#include <gedcom.h>

char *ged_get_line(node);

NODE *node;


Description

The ged_get_line function gets a pointer to the line element of the node structure.

Return Value

The ged_get_line function returns a pointer to the line in the node structure.

See Also

ged_get_tag, ged_get_value, ged_get_xref, ged_set_line, ged_set_tag, ged_set_value, ged_set_xref

Example

#include <gedcom.h>

NODE *node;
char *line;
POOL *pool;

main()
    {
        if ((pool=(ged_set_pool(ged_create_pool(5000, sizeof(NODE)))))
            == NULL)
            exit(0);  /* Create failed */
        node = ged_copy_node("TAG VALUE", NULL, NULL);
        line = ged_get_line(node);

        /* deallocate the memory pool */
        GED_DESTROY_POOL();
    }

This program uses ged_copy_node to create a node, and then uses ged_get_line to retrieve the
line in the node. A pointer to this value is assigned to line.ged_get_next_node- get.c


Summary

#include <gedcom.h>

NODE *ged_get_next_node(node);

NODE *node;

Description

The ged_get_next_node function gets a pointer to the next node in the tree in a preorder
traversal.

Return Value

The ged_get_next_node function returns a pointer to the next node in the tree in a preorder
traversal, or NULL if none.

See Also

ged_get_previous_node

Example

#include <gedcom.h>

NODE *node;
NODE *next;
POOL *pool;

main()
    {
        if ((pool=(ged_set_pool(ged_create_pool(5000, sizeof(NODE)))))
            == NULL)
            exit(0);  /* Create failed */
        node = ged_make_path("TAG1 TAG2 TAG3");
        next = ged_next_node(node);

        /* deallocate the memory pool */
        GED_DESTROY_POOL();
    }

This program uses ged_make_path to create a node, and then uses ged_get_next_node to
retrieve the a pointer to the next node to be traversed.ged_get_parent- get.c


Summary

#include <gedcom.h>

NODE *ged_get_parent(node);

NODE *node;

Description

The ged_get_parent function gets a pointer to the parent of node.

Return Value

The ged_get_parent function returns a pointer to the parent of node, or NULL if the node does
not have a parent.

See Also

ged_get_child, ged_get_sibling

Example

#include <gedcom.h>

POOL *pool;
NODE *tree;
NODE *child;
NODE *parent;

main()
    {
        if ((pool=(ged_set_pool(ged_create_pool(5000, sizeof(NODE)))))
            == NULL)
            exit(0);  /* Create failed */
        tree = ged_make_path("ROOT CHILD GRANDCHILD");
        child = ged_get_child(node);
        parent = ged_get_parent(child);

        /* deallocate the memory pool */
        GED_DESTROY_POOL();
    }

This program uses ged_make_path to create a tree, and then uses ged_get_child to retrieve the
child of the root node, and then ged_get_parent to get back to the root node. ged_get_pool- gedmem.c


Summary

#include <gedcom.h>

POOL *ged_get_pool();

Description

The ged_get_pool function gets a pointer to the memory pool which is currently being used. The
pool which is currently being used, is the last one for which ged_set_pool was called. If there is
no current pool, one will be created of size 1000.

Return Value

The ged_get_pool function returns a pointer to the POOL structure.

See Also

ged_alloc_pool, ged_create_pool, ged_destroy_pool, ged_reset_pool, ged_set_pool

Example

#include <gedcom.h>

POOL *memPool;

main()
    {
        if ((ged_set_pool(ged_create_pool(5000, sizeof(NODE)))) 
            == NULL)
            exit(0);  /* Create failed */
        memPool = ged_get_pool();

        /* deallocate the memory pool */
        GED_DESTROY_POOL();
    }

This program uses ged_create_pool to create a memory pool, and uses ged_set_pool. Then
memPool is assigned to the pool which was just created using ged_get_pool. The memory pool
in then deallocated using ged_destroy_pool.
ged_get_previous_node                                         - get.c


Summary

#include <gedcom.h>

NODE *ged_get_previous_node(node);

NODE *node;

Description

The ged_get_previous_node function gets a pointer to the previous node of the tree in a
preorder traversal.

Return Value

The ged_get_previous_node function returns a pointer to the previous node in the tree in a
preorder traversal, or NULL if none.

See Also

ged_get_next_node

Example

#include <gedcom.h>

NODE *node;
NODE *next;
NODE *prev;
POOL *pool;

main()
    {
        if ((pool=(ged_set_pool(ged_create_pool(5000, sizeof(NODE)))))
             == NULL)
            exit(0);  /* Create failed */
        node = ged_make_path("TAG1 TAG2 TAG3");
        next = ged_next_node(node);
        prev = ged_previous_node(node);

        /* deallocate the memory pool */
        GED_DESTROY_POOL();
    }

This program uses ged_make_path to create a node, and then uses ged_get_next_node and
ged_get_previous_node to go forward and back in the tree.ged_get_previous_sibling- get.c


Summary

#include <gedcom.h>

NODE *ged_get_previous_sibling(node);

NODE *node;

Description

The ged_get_previous_sibling function gets a pointer to the node immediately before node in
it's sibling list.

Return Value

The ged_get_previous_sibling function returns a pointer to the previous node in the nodes
sibling list, or NULL if none.

See Also

ged_get_last_sibling

Example

#include <gedcom.h>

main()
    {
    NODE *child, *node, *prev;
    POOL *pool;

        if ((pool=(ged_set_pool(ged_create_pool(5000, sizeof(NODE)))))
             == NULL)
            exit(0);  /* Create failed */
        tree = ged_make_path("ROOT CHILD GRANDCHILD");
        child = ged_get_child(node);
        ged_connect_sibling(child,
            ged_make_path("SIBLING1 SIBLINGCHILD"), -1);
        ged_connect_sibling(child,
            ged_make_path("SIBLING2 SIBLINGCHILD"), -1);
        child = ged_get_sibling(child);
        prev = get_previous_sibling(child);
        GED_DESTROY_POOL();    /* deallocate the memory pool */
    }

This program uses creates a tree, and then uses ged_get_sibling and ged_get_previous_sibling to
go move forward and back in the sibling list.ged_get_sibling  - get.c


Summary

#include <gedcom.h>

NODE *ged_get_sibling(node);

NODE *node;

Description

The ged_get_sibling function gets a pointer to the sibling of node.

Return Value

The ged_get_sibling function returns a pointer to the sibling of node, or NULL if there is no
sibling.

See Also

ged_get_child, ged_get_parent, ged_get_last_sibling

Example

#include <gedcom.h>

main()
    {
    NODE *tree;
    NODE *sibling;
    NODE *child;
    POOL *pool;

          if ((pool=(ged_set_pool(ged_create_pool(5000,
sizeof(NODE)))))
              == NULL)
              exit(0);  /* Create failed */
          tree = ged_make_path("ROOT CHILD GRANDCHILD");
          child = ged_get_child(node);
          ged_connect_sibling(child,
                  ged_make_path("SIBLING1 SIBLINGCHILD"), -1);
          sibling = getsibling(child);

          /* deallocate the memory pool */
          GED_DESTROY_POOL();
    }

This program creates a tree, and then uses ged_get_child to retrieve the child of the root node,
and then ged_get_sibling to get the childs sibling. ged_get_tag- get.c


Summary

#include <gedcom.h>

char *ged_get_tag(node);

NODE *node;

Description

The ged_get_tag function gets a pointer to the tag part of the line element of node.


Return Value

The ged_get_tag function returns a pointer to the tag in node, bypassing the cross reference if
there.

See Also

ged_get_line, ged_get_value, ged_get_xref, ged_set_line, ged_set_tag, ged_set_value, ged_set_xref

Example

#include <gedcom.h>

NODE *node;
char *tag;
POOL *pool;

main()
    {
        if ((pool=(ged_set_pool(ged_create_pool(5000, sizeof(NODE)))))
            == NULL)
            exit(0);  /* Create failed */
        node = ged_copy_node("@I1@ TAG VALUE", NULL, NULL);

        /* assigns to tag a pointer to 'T' in "@I1@ TAG VALUE" */
        tag = ged_get_tag(node);

        /* deallocate the memory pool */
        GED_DESTROY_POOL();
    }

This program uses ged_copy_node to create a node, and then uses ged_get_tag to retrieve the
tag from the node.
ged_get_value                                                 - get.c


Summary

#include <gedcom.h>

char *ged_get_value(node);

NODE *node;

Description

The ged_get_value function gets a pointer to the value part of the line element in node.

Return Value

The ged_get_value function returns a pointer to the value in node.

See Also

ged_get_line, ged_get_tag, ged_get_xref, ged_set_line, ged_set_tag, ged_set_value, ged_set_xref

Example

#include <gedcom.h>

NODE *node;
POOL *pool;
char *value;

main()
    {
        if ((pool=(ged_set_pool(ged_create_pool(5000, sizeof(NODE)))))
            == NULL)
            exit(0);  /* Create failed */
        node = ged_copy_node("TAG VALUE", NULL, NULL);

        /* assigns to value a pointer to 'V' in "TAG VALUE" */
        value = ged_get_value(node);

        /* deallocate the memory pool */
        GED_DESTROY_POOL();
    }

This program uses ged_copy_node to create a node, and then uses ged_get_value to retrieve the
value of the node. A pointer to the value is assigned to value.
ged_get_xref                                                  - get.c


Summary

#include <gedcom.h>

char *ged_get_xref(node);

NODE *node;

Description

The ged_get_xref function gets a pointer to the cross reference part of the line element of node.

Return Value

The ged_get_tag function returns a pointer to the cross reference in node, or NULL if there is
no cross reference identifier.

See Also

ged_get_line, ged_get_value, ged_set_line, ged_set_tag, ged_set_value, ged_set_xref

Example

#include <gedcom.h>

NODE *node;
POOL *pool;
char *xref;

main()
    {
          if ((pool=(ged_set_pool(ged_create_pool(5000,
sizeof(NODE))))
              == NULL)
              exit(0);  /* Create failed */
          node = ged_copy_node("@1@ TAG VALUE", NULL, NULL);

          /* assigns to tag a pointer to 'T' in "  TAG VALUE" */
          xref = ged_get_xref(node);

          /* deallocate the memory pool */
          GED_DESTROY_POOL();
    }

This program uses ged_copy_node to create a node, and then uses ged_get_xref to retrieve the
xref from the node.ged_inherits                               - ask.c


Summary

#include <gedcom.h>

NODE *ged_inherits(node1, node2);

NODE *node1;
NODE *node2;

Description

The ged_inherits function determines if the tag in node1 is equivalent to the tag in node2.  In
the future ged_inherits will check to see if the tags are related, for example, marriage and
banns.

Return Value

The ged_inherits function returns an integer.  Zero is returned if false, one is returned if true.

See Also

ged_match, ged_match_tags

Example

#include <gedcom.h>

main()
    {
    NODE *node1;
    NODE *node2;
    POOL *pool;

        if ((pool = ged_set_pool(ged_create_pool(5000,sizeof(NODE))))
            == NULL)
            exit(0);            /* create failed */
        node1 = ged_copy_node("@I1@ INDI", NULL, NULL);
        node2 = ged_copy_node("INDI", NULL, NULL);
        if (ged_inherits(node1, node2))
            printf("node1 ged_inherits from node2\n");
        GED_DESTROY_POOL();
   }

This program makes a two nodes with ged_copy_node and compares them with ged_inherits.ged_make_path- ask.c


Summary

#include <gedcom.h>

NODE *ged_make_path(path);

char *path;

Description

The ged_make_path function, given a NULL terminated input string containing tags separated
by white space, will create a path consisting of the tags in the input string.


Return Value

The ged_make_path function returns a pointer to the root node of the path which is created, or
NULL if it fails.

See Also

ged_copy_node
ged_make_path                                                - copy.c


Example

#include <gedcom.h>

main()
    {
    NODE *tree;
    NODE *msg;
    POOL *pool;

        if ((pool = ged_set_pool(ged_create_pool(5000,sizeof(NODE))))
            == NULL)
            exit(0);            /* create failed */

        /* use ged_copy_node to make a tree */
        tree = ged_copy_node("INDI",
                   ged_copy_node("BIRT",
                       ged_copy_node("DATE 1901", NULL,
                       ged_copy_node("PLAC Utah", NULL, NULL)),
                   ged_copy_node("MARR",
                       ged_copy_node("DATE 1917", NULL, NULL),
                       NULL)), /* end of MARR and BIRT */
                   NULL);       /* end of INDI */
        msg = ged_make_path("MARR DATE");
        ged_ask(tree, msg, 1);  /* returns the node "DATE 1917" */
        GED_DESTROY_POOL();
   }

This program makes a tree with ged_copy_node, and a path to the marriage date in the tree,
and then retrieve it.ged_match                                - ask.c


Summary

#include <gedcom.h>

int ged_match(line1, line2);

char *line1;
char *line2;

Description

The ged_match function, given two strings will do a case sensitive comparison of the first word
in the strings.  If the tags are equivalent then 0 is returned, if they are not equivalent 1 will be
returned.

Return Value

The ged_match function returns an integer value as described above.

See Also

ged_match_tags, ged_inherits

Example

#include <gedcom.h>

main()
    {

        /* compare the first word on two lines */
        if (!ged_match("This is string one", "This is string two"))
            printf("They match!\n");
    }

This program compares the first word of two strings with the ged_match function and prints a
message if they are equivalent.
ged_match_tags                                                - ask.c


Summary

#include <gedcom.h>

int ged_match_tags(node1, node2);

NODE *node1;
NODE *node2;

Description

The ged_match_tags function, given two nodes will do a case sensitive comparison of the tags
on the lines of node1 and node2.  If the tags are equivalent then 0 is returned, if they are not
equivalent 1 will be returned.


Return Value

The ged_match_tags function returns an integer value as described above.

See Also

ged_match, ged_inherits
ged_match_tags                                                - ask.c


Example

#include <gedcom.h>

main()
    {
    NODE *node1;
    NODE *node2;
    POOL *pool;

        if ((pool = ged_set_pool(ged_create_pool(5000,sizeof(NODE))))
            == NULL)
            exit(0);            /* create failed */

        /* use ged_copy_node to make two nodes */
        node1 = ged_copy_node("DATE 1901", NULL, NULL);
        node2 = ged_copy_node("DATE 1917", NULL, NULL),

        /* compare the tags in node1 and node2 */
        if (!ged_match_tags(node1, node2))
            printf("The tags in node1 and node2 match\n");

        GED_DESTROY_POOL();
    }

This program makes a two nodes with ged_copy_node, and then compares the tags with the
ged_match_tags function and prints a message if the two tags are equivalent.ged_print_indented- print.c


Summary

#include <gedcom.h>

void ged_print_indented(tree, stream);

NODE *tree;
FILE  *stream;

Description

The ged_print_indented function prints the input tree indenting each level. The tree is printed
as it is traversed in a preorder traversal.

Return Value

None

See Also

ged_print_levels

Example

#include <gedcom.h>

NODE *tree;
POOL *pool;

main()
    {
        if ((pool = ged_set_pool(ged_create_pool(5000,sizeof(NODE))))
            == NULL)
            exit(0);            /* create failed */
        tree = ged_copy_node("INDI",
                  ged_copy_node("BIRT",
                     ged_copy_node("DATE 1901", NULL,
                     ged_copy_node("PLAC Utah", NULL, NULL)),
                  ged_copy_node("MARR",
                     ged_copy_node("DATE 1917", NULL, NULL),
                  NULL)), /* end of MARR and BIRT */
               NULL);      /* end of INDI */
        ged_print_indented(tree, stdout);
        GED_DESTROY_POOL();
   }

This program makes a tree with ged_copy_node and then used ged_print_indented to display
the tree.ged_print_levels                                   - print.c


Summary

#include <gedcom.h>

void ged_print_levels(tree, stream);

NODE *tree;
FILE  *stream;

Description

The ged_print_levels function prints the input tree with a level number for each line. The tree
is printed as it is traversed in a preorder traversal.

Return Value

None.

See Also

ged_print_levels

Example

#include <gedcom.h>

NODE *tree;
POOL *pool;

main()
    {
        if ((pool = ged_set_pool(ged_create_pool(5000,sizeof(NODE))))
            == NULL)
            exit(0);            /* create failed */
        tree = ged_copy_node("INDI",
                  ged_copy_node("BIRT",
                     ged_copy_node("DATE 1901", NULL,
                     ged_copy_node("PLAC Utah", NULL, NULL)),
                  ged_copy_node("MARR",
                     ged_copy_node("DATE 1917", NULL, NULL),
                  NULL)), /* end of MARR and BIRT */
               NULL);      /* end of INDI */
        ged_print_levels(tree, stdout);
        GED_DESTROY_POOL();
   }

This program makes a tree with ged_copy_node and then uses ged_print_levels to display the
tree.ged_promote                                             - node.c


Summary

#include <gedcom.h>

void ged_promote(node)

NODE *node;

Description

The ged_promote function moves node and all of its siblings up to nodes parents position,
replacing parent. If node has no parent nothing is done.

Return Value

None

Example

#include <gedcom.h>

NODE *tree;
NODE *node;
POOL *pool;

main()
    {
        if ((pool=ged_set_pool(ged_create_pool(5000,sizeof(NODE))))
            == NULL)
            exit(0);            /* create failed */
        tree = ged_copy_node("INDI",
                  ged_copy_node("BIRT",
                     ged_copy_node("DATE 1901", NULL,
                     ged_copy_node("PLAC Utah", NULL, NULL)),
                  ged_copy_node("MARR",
                     ged_copy_node("DATE 1917", NULL, NULL),
                  NULL)), /* end of MARR and BIRT */
                NULL);     /* end of INDI */
        node = tree->child->sibling;

        /* replace BIRT with DATE and PLAC   */
        ged_promote(node);
        GED_DESTROY_POOL();
   }

This program makes a tree with ged_copy_node. ged_promote is then used to move the
marriage date up in the tree.ged_prune_tree                  - node.c


Summary

#include <gedcom.h>

NODE *ged_prune_tree(root);

NODE *root;

Description

The ged_prune_tree function removes all nodes from the tree with root root which have no
value, and also have no children.

Return Value

The ged_prune_tree function returns the root node of the pruned tree.

See Also

ged_to_tree, ged_read_rec, ged_read_tree, ged_tree_to_ged, ged_tree_to_file

Example

#include <gedcom.h>

main()
    {
    NODE *tree;
    POOL *pool;

        if ((pool = ged_set_pool(ged_create_pool(5000,sizeof(NODE))))
            == NULL)
            exit(0);     /* create failed */
        tree = ged_copy_node("INDI",
                  ged_copy_node("BIRT",
                     ged_copy_node("DATE 1901", NULL,
                     ged_copy_node("PLAC Utah", NULL, NULL)),
                  ged_copy_node("MARR",
                     ged_copy_node("DATE", NULL, NULL),
                  NULL)),     /* end of MARR and BIRT */
               NULL);         /* end of INDI */

        /* prune the tree (will remove MARR and DATE nodes) */
        ged_prune_tree(tree);    
        GED_DESTROY_POOL();
   }

This program makes a tree and then prunes the unused node from it.ged_read_rec- file.c


Summary

#include <gedcom.h>

char *ged_read_rec(fp, gedBuf, limit, status);

FILE   *fp;
char    *gedBuf;
unsigned limit;
int      *status;

Description

The ged_read_rec function reads a GEDCOM record and puts it in gedBuf. It stops reading
when it reaches a new record, or runs out of space in the buffer to put the record. status returns
one of four values. It returns END_OF_fILE if EOF is encountered before anything can be
read, MORE_RECORDS if there are more records in the file, LAST_RECORD if it is the last
in the file, and REC_TOO_lONG if there is not enough space in gedBuf. 

Return Value

ged_read_rec returns a pointer to the end of the record read in the buffer.

See Also

ged_read_tree, ged_to_tree

ged_read_rec (continued)                                     - file.c


Example

#include <gedcom.h>

POOL *pool;
char *buf;
int   status
FILE *fp;

main()
    {
        if ((pool=ged_set_pool(ged_create_pool(5000, sizeof(NODE))))
            == NULL)
            exit(0);     /* create failed    */
        if ((buf = GED_ALLOC_POOL(20000)) == NULL)
            exit(0);     /* allocPool failed */
        if ((fp = fopen("ged.dat", "r")) == NULL)
            exit(0);     /* fopen failed     */
        ged_read_rec(fp, buf, 20000, status); /* read the file */
        GED_DESTROY_POOL();
    }

This program uses ged_read_rec to put a GEDCOM record in buf.ged_read_tree- file.c


Summary

#include <gedcom.h>

NODE *ged_read_tree(fp, gedBuf, limit, status);

FILE   *fp;
char    *gedBuf;
unsigned limit;
int      *status;

Description

The ged_read_tree function reads the next GEDCOM record in fp and returns the resultant
tree. The file is read into gedBuf. limit tells how much space is available in gedBuf, and status
returns one of four values. It returns END_OF_FILE if EOF is encountered before anything
can be read, MORE_RECORDS if there are more records in the file, LAST_RECORD if it is
the last in the file, and REC_tOO_LONG if there is not enough space in gedBuf. ged_read_tree
uses the functions ged_read_rec and ged_to_tree.  END_OF_FILE is 0, REC_TOO_LONG is 1,
MORE_RECORDS is 2, LAST_RECORD is 3.

Return Value

The ged_read_tree function returns a pointer to the root node of the resultant tree, or NULL if
unsuccessful.

See Also

ged_to_tree, ged_read_rec, ged_tree_to_ged, ged_tree_to_file
ged_read_tree (Continued)                                    - file.c


Example

#include <gedcom.h>

main()
    {
    POOL *pool;
    NODE *tree;
    char *buf;
    int   status;
    FILE *fp;

        if ((pool = ged_set_pool(ged_create_pool(5000, sizeof(NODE))))
            == NULL)
            exit(0);     /* create failed    */
        buf = GED_ALLOC_POOL(20000);
        if ((fp = fopen("ged.dat", "r")) == NULL)
            exit(0);     /* fopen failed     */
        tree = ged_read_tree(fp, buf, 20000, &status);
        fclose(fp);
        GED_DESTROY_POOL();
    }

This uses ged_read_tree to get the tree representation of ged.datged_remove_node- node.c


Summary

#include <gedcom.h>

void *ged_remove_node(node)

NODE *node;

Description

The ged_remove_node function removes node from the tree, and moves all of the nodes
children up to the level the deleted node previously occupied in the tree.

Return Value

none.

See Also

ged_remove_subtree
ged_remove_node                                              - node.c


Example

#include <gedcom.h>

main()
    {
    NODE *tree;
    NODE *node;
    POOL *pool;

        if ((pool = ged_set_pool(ged_create_pool(5000,sizeof(NODE))))
            == NULL)
            exit(0);            /* create failed */
        tree = ged_copy_node("INDI",
                  ged_copy_node("BIRT",
                     ged_copy_node("DATE 1901", NULL,
                     ged_copy_node("PLAC Utah", NULL, NULL)),
                  ged_copy_node("MARR",
                     ged_copy_node("DATE 1917", NULL, NULL),
                  NULL)), /* end of MARR and BIRT */
               NULL);      /* end of INDI */
        node = tree->child->sibling;

        /* delete marriage date from the tree     */
        ged_remove_node(node);
        GED_DESTROY_POOL();
   }

This program makes a tree with ged_copy_node. ged_remove_node is then used to delete the
marriage date from the tree.ged_remove_subtree               - node.c


Summary

#include <gedcom.h>

NODE *ged_remove_subtree(node);

NODE *node;

Description

The ged_remove_subtree function deletes node and all its children from the tree, and connects
the sibling of the node to the parent as a child.

Return Value

The ged_remove_subtree function returns the root node of the modified tree, or NULL if error.

See Also

ged_copy_node, ged_remove_node.

ged_remove_subtree                                           - node.c


Example

#include <gedcom.h>

main()
    {
    NODE *tree;
    NODE *node;
    POOL *pool;
        if ((pool = ged_set_pool(ged_create_pool(5000,sizeof(NODE))))
            == NULL)
            exit(0);            /* create failed */
        tree = ged_copy_node("INDI",
                  ged_copy_node("BIRT",
                     ged_copy_node("DATE 1901", NULL,
                     ged_copy_node("PLAC Utah", NULL, NULL)),
                  ged_copy_node("MARR",
                     ged_copy_node("DATE 1917", NULL, NULL),
                  NULL)), /* end of MARR and BIRT */
               NULL);      /* end of INDI */
        node = tree->child->sibling;

        /* delete marriage date from the tree     */
        ged_remove_subtree(node);
        GED_DESTROY_POOL();
   }

This program makes a tree with ged_copy_node. ged_remove_subtree is then used to delete the
marriage date from the tree.ged_reset_pool                 - gedmem.c

Summary

#include <gedcom.h>

void ged_reset_pool();

Description

The ged_reset_pool function is accessed through the ged_reset_pool element of the POOL
structure. It releases the memory in the pool of memory currently in use, so that it can be used
again. Only the memory allocated to the pool when it was created will be retained in the pool
after a call to ged_reset_pool. Any memory allocated later will be released to the system.
ged_reset_pool is also available directly through the macro GED_RESET_POOL;

Return Value

There is no return value.

See Also

ged_alloc_pool, ged_create_pool, ged_get_pool, ged_destroy_pool, ged_set_pool

Example

#include <gedcom.h>

POOL *memPool;
int *intArray;

main()
    {
        /* Create a memory Pool */
        if ((memPool = ged_create_pool(5000, sizeof(NODE))) == NULL)
            exit(0);    /* create failed */
        ged_set_pool(memPool);

        /* allocate memory for 20 integers */
        intArray = (int *) GED_ALLOC_POOL(20*sizeof(int));
        if (intArray == NULL)
            exit(10);    /* allocPool failed */

        /* Release the memory so it can be used again later */
        GED_RESET_POOL();
    }

This program uses ged_create_pool to create a memory pool then uses ged_alloc_pool to
allocate some memory from the pool. It then uses ged_reset_pool to release the memory which
was just allocated.ged_set_line                               - set.c


Summary

#include <gedcom.h>

char *ged_set_line(node, line);

NODE *node;
ch1x *line;

Description

The ged_set_line function sets the line element of node to be line.  ged_set_line makes it's own
copy of the line allocating new memory for the line from the current pool.

Return Value

The ged_set_line function returns a pointer to the line in the node structure.

See Also

ged_get_line, ged_get_tag, ged_get_value, ged_set_tag, ged_set_value

Example

#include <gedcom.h>

NODE *node;
POOL *pool;
char *line;

main()
    {
        if ((pool=(ged_set_pool(ged_create_pool(5000, sizeof(NODE)))))
            == NULL)
            exit(0);  /* Create failed */
        line = GED_ALLOC_POOL(10);
        strcpy(line, "NAME John");
        node = ged_copy_node("TAG VALUE", NULL, NULL);
        ged_set_line(node, line);

        /* deallocate the memory pool */
        GED_DESTROY_POOL();
    }

This program makes a node with ged_copy_node and then changes it's line with the ged_set_line
command.ged_set_error_handler                            - gederror.c


Summary

#include <gedcom.h>

void   ged_set_error_handler( int (*error_handler)(int, NODE *);


Description

Set the static global ged_error_handler to point to a user-defined error handler.

Whenever an internal error occurs within the GEDCOM library, an error code is sent to a
function called ged_error().  If the error was associated with a NODE structure, a pointer to
that structure is passed to ged_error() as well.  If ged_set_error_handler() is called, ged_error()
passes these arguments to the user-defined error_handler() function, else a default error handler
function is called.

       Gedcom Memory Errors

       1   - Memory error.  Overwrote chunk header.
       2   - Couldn't create pool.  Not enough memory available.
       3   - Couldn't allocate more memory to pool.  Not enough memory
       available.
       4   - GEDPROC error.
       5   - GEDHASH error.

       Gedcom IO Errors

       100 - ftell returned bad status.
       101 - Couldn't read next level Number.
       102 - fgetc readerror.
       103 - fgetc readerror.
       104 - fgetc readerror.
       105 - fgetc readerror.
       106 - fgetc readerror.
       107 - fgetc readerror.
       108 - fgetc readerror.
       109 - fflush failed.

ged_set_error_handler (continued)                        - gederror.c


       Gedcom Bad Gedcom Errors

       201 - Invalid character found before level number.
       202 - Cross reference longer than max length.
       203 - Invalid character in tag.
       204 - Tag longer than max length.
       205 - No ending '@' in Cross Reference.
       206 - Invalid character found before level number.

       GEDPROC errors

       301 - Tag not found in ged_traverse()
       302 - Tag not found in traverse_grammar()
       303 - Hook function not registered
       304 - Cannot read GEDCOM tree from file.
       
       GEDHASH errors
           
       401 - fseek() error.
       402 - read() error.
       403 - Unidentified record type in hash table. Hash table is corrupted.
       404 - Error while creating hash table.
       405 - Xref greater than MAX_XREF_ID_LENGTH constant.
       406 - Insert error. Could not insert xref into hash table.
       407 - GEDCOM file missing TRLR tag.
       408 - write() error.
       409 - open() error.
       410 - fopen() error.
       411 - BLKLEN contant error.  BLKLEN value is too small for size
           of records being written to disk-based hash table.
       412 - Prompts the user to change a floppy disk that is associated with
           multiple-disk GEDCOM files.  See gedhash_get_drive() and
           gedhash_get_file() on page 1-6.
       413 - Could not find an xref in hash table.
       414 - Could not insert value into disk-based hash table in static diskSetup()
       415 - Error in remove()
       416 - Error with close()
       417 - Error in gedhash_fopen()
 
See Also

gedhash_get_file, gedhash_get_drive, page 1-6.

ged_set_error_handler (continued)                        - gederror.c


Example

#include "gedcom.h"

int my_ged_error(int err_no, NODE *dataCtxt);

void main(argc, argv)
   int argc;
   char *argv[]; 
 {
  ged_set_error_handler(my_ged_error);
 if (argc < 3)
    ged_error(505, NULL); /* 505 is a user-defined error code */
 ged_process(argv[1], argv[2]);
  }

int my_ged_error(int err_no, NODE *dataCtxt)
  {
 if (err_no < 100)
    {
    fprintf(stderr, "GEDCOM ERROR:  Memory Error Number %d has occurred\n", err_no);
    if (ged_get_line(dataCtxt))
      fprintf(stderr, "LINE: %s\n", ged_get_line(dataCtxt));
    }
 else if (err_no < 200)
   {
    fprintf(stderr, "GEDCOM ERROR:  IO Error Number %d has  occurred\n", err_no);
    if (ged_get_line(dataCtxt))
      fprintf(stderr, "LINE: %s\n", ged_get_line(dataCtxt));
    }
 else if (err_no < 300)
    {
    fprintf(stderr, 
    "GEDCOM ERROR:  Bad GEDCOM Error Number %d has occurred\n", err_no);
    if (ged_get_line(dataCtxt))
      fprintf(stderr, "LINE: %s\n", ged_get_line(dataCtxt));
    }
  else if (err_no == 301)
    {
    return 1; /* don't worry about tag not found */  
    }
  else if (err_no < 400)
    {
   fprintf(stderr, 
    "GEDCOM ERROR:  GEDPROC Error Number %d has  occurred\n", err_no);
   if (ged_get_line(dataCtxt))
    fprintf(stderr, "LINE: %s\n", ged_get_line(dataCtxt));
   }
 else if (err_no == 412) /* Used when changing multiple-disk GEDCOM file */
   {
   fprintf(stderr, 
    "Please insert a disk containing %s in drive %s. Press any key when ready.\n",
       gedhash_get_file(),  gedhash_get_drive();
   return 1;
   }
 else if (err_no == 413) /* Used when changing multiple-disk GEDCOM file */
   {
   fprintf(stderr, "Xref Not Found.\n");
   if (ged_get_line(dataCtxt))
    fprintf(stderr, "LINE: %s\n", ged_get_line(dataCtxt));
   return 1;
   }ged_set_error_handler (continued)                    - gederror.c


 else if (err_no < 500)
   {
   fprintf(stderr, 
    "GEDCOM ERROR:  GEDHASH Error Number %d has occurred\n", err_no);
   if (dataCtxt)
    {
    error_path(dataCtxt); /* print a path from node to root */
    printf("\n\n");
    }
   }
 exit(-1);
 return(-1);
  }

This program initializes ged_error() to call my_ged_error().ged_set_pool- gedmem.c


Summary

#include <gedcom.h>

POOL *ged_set_pool(pool);

POOL *pool;


Description

The ged_set_pool function causes subsequent memory allocations to be drawn from pool pool.
The current pool is stored in a private static variable which should be accessed only by
ged_set_pool and ged_get_pool. The pool should be created by ged_create_pool before calling
ged_set_pool.

Return Value

The ged_set_pool function returns a pointer to pool.

See Also

ged_alloc_pool, ged_create_pool, ged_destroy_pool, ged_get_pool, ged_reset_pool

Example

#include <gedcom.h>

main()
    {
    POOL *pool;

        if ((pool = ged_set_pool(ged_create_pool(5000, sizeof(NODE))))
            == NULL)
            exit(0);     /* create failed */

        /* deallocate the memory pool */
        GED_DESTROY_POOL();
    }

This program uses ged_create_pool to create a memory pool and uses ged_set_pool to denote
that this is the pool which is to be used in subsequent memory transactions. The pool is then
released using ged_destroy_pool.
ged_set_tag                                                   - set.c


Summary

#include <gedcom.h>

char *ged_set_tag(node, tag);

NODE *node;
char *tag;


Description

The ged_set_tag function allocates new memory for the line element in the node structure from
the current pool, and gives it the new tag passed in and the old value.

Return Value

The ged_set_tag function returns a pointer to the line in the node structure.

See Also

ged_get_tag, ged_get_line, ged_get_value, ged_set_line, ged_set_value

Example

#include <gedcom.h>

NODE *node;
POOL *pool;
char *tag;

main()
    {
        if ((pool=(ged_set_pool(ged_create_pool(5000, sizeof(NODE)))))
            == NULL)
            exit(0);  /* Create failed */
        node = ged_copy_node("TAG VALUE", NULL, NULL);
        ged_set_tag(node, "BIRTH");

        /* deallocate the memory pool */
        GED_DESTROY_POOL();
    }

This program uses ged_copy_node to create a node, and then uses ged_set_tag to change the tag
in the node.
ged_set_value                                                 - set.c


Summary

#include <gedcom.h>

char *ged_set_value(node, value);

NODE *node;
char *value;

Description

The ged_set_value function allocates new memory for line from the current pool, and sets the
value part of the line to be value. It keeps the old tag and cross reference if any.

Return Value

The ged_set_value function returns a pointer to the value in the node structure.

See Also

ged_get_line, ged_get_tag, ged_get_value, ged_set_line, ged_set_tag

Example

#include <gedcom.h>

NODE *node;
POOL *pool;
char *value;

main()
    {
        if ((pool=(ged_set_pool(ged_create_pool(5000, sizeof(NODE)))))
            == NULL)
            exit(0);  /* Create failed */
        node = ged_copy_node("TAG VALUE", NULL, NULL);
        ged_set_value(node, value);

        /* deallocate the memory pool */
        GED_DESTROY_POOL();
    }

This program uses ged_set_value to change the value part of the line in node.
ged_set_xref                                                  - set.c


Summary

#include <gedcom.h>

char *ged_set_xref(node, xref);

NODE *node;
char *xref;

Description

The ged_set_xref function allocates new memory for the line element in the node structure from
the current pool, and sets the cross reference to be the new cross reference passed, and copies
the tag and value from the old line.

Return Value

The ged_set_xref function returns a pointer to the line in the node structure.

See Also

ged_get_tag, ged_get_line, ged_get_value, ged_get_xref, ged_set_line, ged_set_value

Example

#include <gedcom.h>

NODE *node;
POOL *pool;
char *xref;

main()
    {
        if ((pool=(ged_set_pool(ged_create_pool(5000, sizeof(NODE)))))
            == NULL)
            exit(0);  /* Create failed */
        node = ged_copy_node("TAG VALUE", NULL, NULL);
        ged_set_xref(node, "@1@");

        /* deallocate the memory pool */
        GED_DESTROY_POOL();
    }

This program uses ged_copy_node to create a node, and then uses ged_set_xref to change the
cross reference in the node.ged_skip_word                    - misc.c


Summary

#include <gedcom.h>

char *ged_skip_word(ptr);

char *ptr;

Description

The ged_skip_word function skips the word that ptr is pointing to, and returns the address of
the next word.

Return Value

ged_skip_word returns a pointer to the next word.

Example

#include <gedcom.h>

main()
 {
 char line[] = "one two three four";
 char *next;
   
   next = ged_skip_word(line);     /* point to the word two */
   printf("second word is %s", next); 
 }

This example allocates a string, and then calls ged_skip_word to get a pointer to the second
word.
ged_to_tree                                                  - file.c


Summary

#include <gedcom.h>

NODE *ged_to_tree(gedBuf, status);

char **gedBuf;
int   *status;

Description

The ged_to_tree function takes the GEDCOM data contained in gedBuf and returns the root
node of the tree corresponding to the data. The tree points to the data in gedBuf for the
contents of the line element of the NODE structure. This results in some wasted memory as the
space used by the level numbers cannot be reclaimed, however this method is faster. The
function can be changed such that it uses ged_copy_node instead of ged_clone_node to create
the node. If ged_copy_node is used, new memory will be allocated for the contents of the tree,
and gedBuf can then be reclaimed. This method is slower, but does not waste any memory. 
status will be set to MORE if there are more records in gedBuf and LAST if the one read was
the last.  The constant MORE is 1, and the constant LAST is 2.

Return Value

The ged_to_tree function returns a pointer to the root node of the resultant tree, or NULL if
error.

See Also

ged_copy_node, ged_read_tree, ged_tree_to_ged, ged_tree_to_file
ged_to_tree                                                  - file.c


Example

#include <gedcom.h>

main()
    {
    POOL *pool;
    FILE *fp;
    NODE *tree;
    char *buf;
    int   status;
        if ((pool = ged_set_pool(ged_create_pool(5000, sizeof(NODE))))
            == NULL)
            exit(0);     /* create failed    */
        if ((buf = GED_ALLOC_POOL(20000)) == NULL)
            exit(0);
        if ((fp = fopen("ged.dat", "r")) == NULL)
            exit(0);     /* fopen failed     */
        ged_read_rec(fp, buf, 20000, &status);    
        tree = ged_to_tree(&buf, &status);  /* get the tree in buf */
        GED_DESTROY_POOL();
    }

This program uses ged_to_tree to make a tree from the record.ged_tree_to_file- file.c


Summary

#include <gedcom.h>

void ged_tree_to_file(tree, fp, level):

NODE *tree;
FILE *fp;
unsigned level;

Description

The ged_tree_to_file function takes tree, flattens it, adds level numbers and writes it to the file
fp points to. fp must be opened for writing. level is the level to start writing.

Return Value  

None.

See Also

ged_to_tree, ged_tree_to_ged
ged_tree_to_file                                             - file.c


Example

#include <gedcom.h>

main()
    {
    POOL *pool;
    NODE *tree;
    FILE *fp;

        if ((pool = ged_set_pool(ged_create_pool(5000,sizeof(NODE))))
            == NULL)
            exit(0);     /* create failed */
        if ((fp = fopen("ged.dat", "w") == NULL)
            exit(0);     /* fopen failed */
        tree = ged_copy_node("INDI",
                   ged_copy_node("BIRT",
                      ged_copy_node("DATE 1901", NULL,
                      ged_copy_node("PLAC Utah", NULL, NULL)),
                   ged_copy_node("MARR",
                      ged_copy_node("DATE 1917", NULL, NULL),
                   NULL)),   /* end of MARR and BIRT */
               NULL);       /* end of INDI */
        ged_tree_to_file(tree, fp); /* write the tree to the file */
        fclose(fp);
        GED_DESTROY_POOL();
   }

This program makes a tree with ged_copy_node, then flattens it and writes it to ged.dat.ged_tree_to_ged- file.c


Summary

#include <gedcom.h>

char * ged_tree_to_ged(tree, gedBuf, limit, level);

NODE    *tree;
char      *gedBuf;
unsigned  limit;
unsigned  level;

Description

The ged_tree_to_ged function takes tree and converts it to GEDCOM format and puts it in
gedBuf. limit is the length of gedBuf. level is the level to start writing.

Return Value  

ged_tree_to_ged returns a pointer to the end of the record written to the buffer.

See Also

ged_to_tree, ged_tree_to_fileged_tree_to_ged                 - file.c


Example

#include <gedcom.h>

main()
    {
    POOL *pool;
    NODE *tree;
    char *buf;

        if ((pool = ged_set_pool(ged_create_pool(5000,sizeof(NODE))))
            == NULL)
            exit(0);     /* create failed */
        if ((buf = GED_ALLOC_POOL(200)) == NULL)
            exit(0);     /* allocPool failed */
        tree = ged_copy_node("INDI",
                  ged_copy_node("BIRT",
                     ged_copy_node("DATE 1901", NULL,
                     ged_copy_node("PLAC Utah", NULL, NULL)),
                  ged_copy_node("MARR",
                     ged_copy_node("DATE 1917", NULL, NULL),
                  NULL)),     /* end of MARR and BIRT */
               NULL);         /* end of INDI */

        /* flatten the tree into GEDCOM representation */
        ged_tree_to_ged(tree, buf, 200);        
        printf("%s\n", buf);  /* print the GEDCOM */
        GED_DESTROY_POOL();
   }
The GEDCOM Processor


Features of the GEDCOM processor

 Checks for invalid tags, including tags that are not in the right context.

 As a GEDCOM file is read, the GEDCOM processor will call user routines, called hooks, to
  process the data.  These hooks can easily be changed by changing a grammar file.  This can
  eliminate recompilation when changing tags.

Overview

The purpose of the GEDCOM processor is to visit each record and line in a GEDCOM data
file, matching tags in a context-sensitive fashion and calling corresponding user-defined
functions to process the information.

Input tags are matched with tags in a grammar file.  The grammar file is a GEDCOM file
containing a specialized GEDCOM grammar record for each type of input record that is to be
processed.  The GEDCOM grammar record is fully populated with all expected tags, all placed
in their proper context as they would appear in the data, as shown below in the example
grammar.

  Example Grammar File - Two Types of Records (indentation added).

  0 INDI
    1 - preFunc
    1 + postFunc 1 3
    1 NAME
    1 BIRT
      2 DATE Comments are allowed in the value field.
            3 + func2
            3 - func1
            3 + func3
    1 DEAT
      2 DATE
      2 PLAC  
  0 FAM
    1 HUSB
    1 WIFE
    1 CHIL

The above grammar instructs gedproc to call two user-defined functions, called "hooks," each
time the tag "INDI" is scanned in the GEDCOM data. The two instruction lines that call these
hooks must be positioned immediately following the "INDI" tag and must be one level lower. 
Notice the tag and value fields of these two  instruction lines.  The value field corresponds to
the name of the function that is called. The plus (+) and minus (-) signs in the tag field
determine when the function is called. The minus sign instructs gedproc to call a function
immediately after scanning "INDI."  The plus sign tells gedproc not to call the function until
after all the children of "INDI" have been scanned. This pre and post processing ability is
provided to allow initialization before processing subordinate lines and analysis after.

Two arguments are passed to a hook, one of which is user-defined.  This is illustrated in the
second instruction line.  Here, a byte pointer to the beginning of the line, "postFunc 1 3," is
passed to the user-defined function.  The function may then parse out the line as required. The
other parameter, a NODE pointer, points to the INDI tag in the data tree.  For the instruction
lines under the DATE tag, shown above, the NODE pointer points to the DATE tag in the
data tree.

Hooks must be registered using ged_define_semantic() before they can be used.  See page 3-7
for more details.

Context sensitivity means that tags must match within the context of the superior tag under
which they occur, all the way out to the root (level zero) of the record.  In this hypothetical
example, a data record containing 

  0 INDI
    .
    .
    1 BIRT
      .
      .
      2 PLAC

(path INDI BIRT PLAC) would not match this grammar, because PLAC is not a valid tag in
the INDI BIRT context of the grammar.  The path INDI DEAT PLAC would match.  The
occurrence of an unexpected tag is not necessarily an error, but it is a condition to be detected
and reported.

Each tag combination appears only once in a grammar record.  For example, the combination, 
FAM CHIL, appears only once in the grammar, though multiple children may appear in the
data.  By contrast, the same tag may appear more than once in different contexts, such as INDI
BIRT DATE and INDI DEAT DATE.  These are different kinds of DATEs, and need to be
processed differently.

The processing approach is as follows.  At initialization, the grammar and data files are opened.
The grammar records are then read into memory using ged_read_tree and combined into a
single grammar tree in internal form.  Then, in the outermost processing loop, the
ged_read_tree function is used to read and convert each data record (beginning at level zero)
into an internal tree.  The system then traverses the data tree, one node (line) at a time.  It
traverses in parallel the grammar tree, matching the tag in the data to the tag in the grammar
within the corresponding context.

As each tag is matched, a user-defined segment of code, called a hook, is called that is
identified by the instruction lines immediately following the tag, as explained in the above
example.

Errors are reported to another user-defined function that must be named
int ged_error(char *error_msg, NODE *data_context, size_t status).

Notes:

    An attempt to modify the GEDCOM data tree will result in unpredictable behavior.
    Copy the data tree with ged_copy_tree and modify the copy.

    Some GEDCOM library routines use the memory pool that was last opened by
    GED_ALLOC_POOL.  To avoid loss of data, user-defined functions called from
    ged_process should use ged_get_pool to save the pointer to the pool that is used by
    ged_process. ged_set_pool should then be called to cause subsequent memory
    allocations to be drawn from the user's pool.


                    The GEDCOM Processor Functions



ged_process                                                - gedproc.c


Summary

#include "gedproc.h"

int ged_process(FILE *fg, FILE *ft);


Description

The ged_process function accepts two parameters, a pointer to the grammar file and a pointer
to the GEDCOM data file.  ged_process loads the grammar file and a data tree into memory,
and then calls the ged_traverse function to process it.

Return Value

If the functions that are called by the grammar return an integer from 100 through 199,
ged_process immediately stops processing the current tree and  begins processing the next data
tree. If an integer greater than 199 is returned, ged_process immediately stops processing and
returns the value of that integer.  If a value less than 100 is returned, END_OF_FILE is
returned as described under ged_read_tree in the GEDCOM library documentation.  If -1 is
returned, execution immediately terminates.
ged_load_grammar                                          - gedproc.c


Summary

#include "gedcom.h"

NODE *ged_load_grammar(FILE *fg);

Description

The ged_load_grammar function accepts as a parameter a pointer to your grammar file.  You
can load as many grammars into memory as you wish.  ged_load_grammar is normally accessed
through the ged_process function.

Return Value

The ged_load_grammar function returns a NODE pointer to the root of the grammar tree.  A
dummy node is always tacked on to the root of this tree and contains the tag, "grammar."  This
extra tag is used by the ged_traverse function but is transparent to you. If an error occurs while
loading the grammar then error status, 304, is sent to ged_error.

Example  See page 3-6.

ged_traverse                                              - gedproc.c


Summary

#include "gedcom.h"

int ged_traverse(NODE *dataCtxt, NODE *grammarCtxt);

Description

The ged_traverse function traverses the grammar and data trees, checking for valid tags and
calling their respective functions.
 
Return Value

If the user-defined functions (including ged_error) return an integer greater than 99,
ged_process immediately stops processing and returns that value. If -1 is returned, execution of
the program is immediately terminated, else END_OF_FILE is returned as described under
ged_read_tree on page 2-45. 
ged_traverse (continued)                                  - gedproc.c


Example

int my_ged_process(FILE *fg, FILE *ft)
 {
 POOL *dataPool, *grammarPool;
 NODE *grammar, *data;
 short status;
 int errStat= DFLT_ERR; /* Equals 99 */

 if((grammarPool = ged_set_pool(ged_create_pool(2500,
   sizeof(NODE))))==(POOL *)NULL)
   ged_error(506, NULL);
 grammar = ged_load_grammar(fg);/* you may load more than one grammar*/

 /* Create a new pool for the GEDCOM data */
 if((dataPool = ged_set_pool(ged_create_pool(60000, sizeof(NODE))))
   == (POOL *)NULL)
    ged_error(507, NULL);
 while((status !=LAST_RECORD) && ((data = load_tree(ft, &status, 60000))
   !=(NODE *)NULL) && (status != END_OF_FILE))
   {
   if((errStat = ged_traverse(data, grammar)) >=200)
    break;
   GED_RESET_POOL();
   }
 GED_DESTROY_POOL();
 ged_set_pool(grammarPool); /* destroy the grammar pool */
 GED_DESTROY_POOL();
 return((errStat >99) ? (int)status : errStat);
 }

/******* Allocates space and loads a tree ********/
NODE *load_tree(FILE *fg, short *status, unsigned long limit) 
 {
 static char *dataBuf;
 static NODE *node;

 if ((!(dataBuf = GED_ALLOC_POOL(limit))) 
   || ((node = ged_read_tree(fg, dataBuf, limit, status))==(NODE *)NULL) 
   || (*status == REC_TOO_LONG))
   {
   ged_error(508, NULL); /* User-defined error code */
   return((NODE *)NULL);
   }
 return(node);
 } 

This function duplicates the ged_process function.  It loads the grammar, loads in a tree from
the GEDCOM data, and then calls ged_traverse.  If ged_process is not flexible enough, the
above code can be customized to fit your needs.ged_define_semantic- gedproc.c


Summary

#include "gedcom.h"

int ged_define_semantic(byte *dataCtxt, int (*funcPointer)(NODE *, byte *));
   
Description

This will register the semantic functions, or hooks, defined by the user.
 
Return Value

Returns zero if successful.  Returns two if the function name is greater than
FUNC_NAME_SIZ.  Returns three if the number of functions that have been registered is
greater than MAX_FUNCS.  FUNC_NAME_SIZ and MAX_FUNCS are defined in gedhash.h.

Example

void setupFunc(void)
 {
 ged_set_error_handler(my_ged_error);

 If (ged_define_semantic("famc_check",famc_check)
      ||  ged_define_semantic("fams_check",fams_check) )
   printf("Error.  Could not register hooks.\n");
 }
GEDHASH System


Purpose of GEDHASH

The purpose of the hash package, called gedhash, is to provide a general-purpose hash-based
table look-up facility that can store a value to be later retrieved by key.  Both key and value are
variable length and may contain binary (non-ASCII) information.

A principal use of the package is to support pointer / cross reference resolution in processing a
GEDCOM transmission.  

This package is optimized for broad usability and ease of understanding and maintaining the
package itself.  Performance and space efficiency are good, but not as highly specialized or
complicated as other approaches could provide.

Memory Management

All tables create and maintain their own POOL structure from the GEDCOM library.

A memory-resident hash table expands by allocating from its own pool until a maximum
memory usage threshold is reached, at which time it is copied to a disk-resident hash table and
all memory is released.  To change this threshold, define the MAX_MEMORY constant in
gedhash.h.

The current memory pool maintained via ged_set_pool() is saved by these routines and restored
before returning.
                        The GEDHASH Functions


gedhash_close_table                                        - gedhash.c

                                   
Summary

#include "gedcom.h"

int gedhash_close_table(HASH_TAB *htab)


Description

For permanent hash table files, gedhash_close_table closes the hash table that is associated with
htab, saving in the hash file all information required to use the table next time.  The current
iterative positions of the hash table are also saved, so that a call to gedhash_iterate would begin
at the next iterative position in the hash table.

For temporary hash table files, delete the temporary file that may have been created in
connection with a memory-based hash table.


Return Value

Returns zero upon success.  Returns -1 if no hash table file exists.  Returns 1 if the temporary
file cannot be deleted or closed.

Example

#include "gedcom.h"

void main( int argc, char *argv[])
  {
  HASH_TAB ht, *htab;
  char *hash_filename = ( argc > 1 ) ? argv[1] : (char *)NULL;

  /* Create hash table: */
  htab = gedhash_create_table(&ht, hash_filename, 31L, (MEMSIZ)5000);
  if (htab == (HASH_TAB *)NULL)
   printf("\aCould not create a hash table!!\n");
  
  /* Perform processing here */

  gedhash_close_table(htab); /* Close the hash table */
  }int gedhash_copy                                       - gedhash.c


Summary

#include "gedcom.h"

int gedhash_copy(HASH_TAB *htab_dest, HASH_TAB *htab_source);

Description 

Copies contents from htab_source to htab_dest. htab_dest does not need to be empty.  Both
must have been previously created using gedhash_create_table().  Neither their respective sizes
nor their being on disk or in memory affects the operation.

Return Value

Returns zero if unsuccessful, one otherwise.

Example

#include "gedcom.h"

void main( int argc, char *argv[])
  {
  HASH_TAB hash_table, *htab, copy_table, *copy_tab;
  char hash_filename[] = "source.hsh";
  char key [400], val[400];

  htab = gedhash_create_table(&hash_table, hash_filename, 31L, (MEMSIZ)5000);
  if (!htab)
    printf("\aCould not create a hash table!!\n");
  copy_tab = gedhash_create_table(&copy_table, "copy.hsh", 11L, (MEMSIZ)5000);
  if (!copy_tab)
    printf("\aCould not create a hash table!!\n");
  gedhash_copy(copy_tab, htab); /* Copy values from htab to copy_tab */
  gedhash_close(copy_tab);
  gedhash_close(htab);
  }long GEDHASH_COUNT                                     - gedhash.h


Summary

#include "gedcom.h"

long GEDHASH_COUNT(HASH_TAB *htab);

Description 

This macro returns the number of keys currently held in the table associated with htab.

Return Value

See above.

Example

#include "gedcom.h"

void main( int argc, char *argv[])
  {
  HASH_TAB hash_table, *htab;
  char *hash_filename = (argc >1 ) ? argv[1] : (char *)NULL;

  htab = gedhash_create_table(&hash_table, hash_filename, 31L, (MEMSIZ)5000);
  if (!htab)
   printf("\aCould not create a hash table!!\n");
  printf("Number of cells in hash table: %ld\n", GEDHASH_COUNT(htab));
  gedhash_close(htab);
  }gedhash_create_table                                   - gedhash.c

                                   
Summary

#include "gedcom.h"

HASH_TAB * 
gedhash_create_table(HASH_TAB *htab, char *perm_file, HSIZ hash_size, MEMSIZ
max_memory);


Description

htab points to a HASH_TAB struct, which must be allocated before gedhash_create_table is
called.

If perm_file is null, a memory-based hash table is created which, if needed, will automatically
be copied over into a larger temporary disk-based hash table when allocated memory would
exceed max_memory.

If perm_file references a name string, an existing hash table file of that name will be opened
and used, or a new one will be created if none exists.  The file will be permanently saved when
gedhash_close is called.  Subsequent user operations on the hash table remain the same,
whether the table is in memory or on disk.

hash_size defines the number of rows in the hash table.  For optimal performance,  this
argument should be the prime number closest to the approximate number of potential
key/values stored. If this argument is not a prime number, it will be automatically adjusted to
one.

Return Value

Returns a pointer to the modified hash table structure or NULL if failure.

Example

#include "gedcom.h"

void cdecl main( int argc, char *argv[] )
  {
  HASH_TAB hash_table, *htab;
  char *hash_filename = (argc > 1) ? argv[1] : (char *)NULL;

  /* Create hash table: */
  htab = gedhash_create_table(&hash_table, hash_filename, 31L, (MEMSIZ)5000);
  if (!htab)
   printf("\aCould not create a hash table!!\n");
  gedhash_close(htab);
  }gedhash_create_xref                                   - gedpoint.c

                                   
Summary

#include "gedcom.h"

HASH_TAB  gedhash_create_xref(char *ged_filename, char *hash_filename, HSIZ h_size);
          

Description

Creates a hash table then makes one pass over ged_filename, storing the lseek position of each
record which contains an xref id. Spans Multiple disks until a TRLR record is found. If
hash_filename is null, a memory-based hash table is created which, if needed, will automatically
be copied over into a larger temporary disk-based hash table when allocated memory would
exceed max_memory.  When this happens, h_size is optimally re-sized, not to exceed
MAX_FILE_H, which is defined in gedhash.h.

If hash_filename references a name string, an existing hash table file of that name path and will
be opened and used.  If hash_filename  does not yet exist on the disk, a new hash table file,
called hash_filename, will be created and opened.  The file will be permanently saved when
gedhash_close is called.  Subsequent user operations on the hash table remain the same,
whether the table is in memory or on disk.

hash_size defines the number of rows in the hash table.  For optimal performance,  this
argument must be the prime number closest to the approximate number of potential key/values
stored. If this argument is not a prime number, it will be automatically adjusted to one.


Return Value

Returns the newly created hash table struct.  Returns NULL if unsuccessful.

Example

#include "gedcom.h"

void main(int argc,  char *argv[])
  {
  HASH_TAB hash_table;
  FILE *fg, *ft;
  HSIZ table_size;  /* Used in gedhash_create_xref. Optionally passed in by user. */
  char *load_hash;  /* permanent hash table.  Really only used for debugging */
  
  ged_set_error_handler(my_ged_error);
  if (argc < 2)
    {
    printf("Correct format: program.exe gedcomfile <hash file name>\n\n");
    exit(-1);
    }
  load_hash = (argc > 2) ? argv[2] : NULL;gedhash_create_xref (continued)- gedpoint.c


  table_size = (HSIZ)101;

  /* create hash table and insert xref's */
  hash_table = gedhash_create_xref(argv[1], load_hash, table_size);
  setupFunc(); /* register hooks */
  fg = ged_efopen("point.grm", "rb"); /* Open grammar file, check I/O errors */
  ft = ged_efopen(argv[1], "rb");     /* Open gedcom file */
  ged_process(fg, ft);
  gedhash_destroy_table(&hash_table); /* Deletes the hash table */
  fcloseall();
  }gedhash_delete                                         - gedhash.c

                                   
Summary

#include "gedcom.h"

int gedhash_delete(HASH_TAB *htab, char * key, KSIZ keyLen);

Description

Finds the key in the hash table and deletes its cell. htab is a pointer to the HASH_TAB struct.  
If the keyLen argument is zero, then it is assumed that key is NULL-terminated, else keyLen is
the length in bytes of key.  Upon success, htab->key_count is decremented.

Return Value

Zero if key is not found, else one.

Example

.
.
.
if (gedhash_delete(htab, "F1", 0) == 0)
       printf("Could not delete 'F1' from the hash table.\n");
.
.
.gedhash_destroy_table                                    - gedhash.c

                                   
Summary

#include "gedcom.h"

int gedhash_destroy_table(HASH_TAB *htab);

Description

Destroys the hash table that is associated with htab.  It releases all memory used by it, and
deletes the hash file on disk, if any.

Return Value

Returns 0 if unsuccessful, else 1.

Example

#include "gedcom.h"

void main( int argc, char *argv[])
  {
  HASH_TAB hash_table, *htab;
  char *hash_filename = (argc >1 ) ? argv[1] : (char *)NULL;

  /* Create hash table: */
  htab = gedhash_create_table(&hash_table, hash_filename, 31L, (MEMSIZ)5000);
  if (!htab)
    printf("\aCould not create a hash table!!\n");
  
  /* Perform processing here */

  gedhash_destroy_table(htab); /* Close the hash table */
  }gedhash_find_xref                                      - gedhash.c


Summary

#include "gedcom.h"

NODE  * gedhash_find_xref(HASH_TAB *htab, NODE *dataCtxt);

Description

Returns a NODE pointer to the record referenced by the xref pointer in the value field of
dataCtxt.  The hash table associated with htab, which must have been created by
gedhash_create_xref(), is used to lookup the location of the record.

Return Value

If successful, returns a NODE pointer to the record, else NULL.

Example

HASH_TAB *HTAB; /* Global hash table struct */

int child_check(NODE *dataCtxt, byte *line)
  {
  NODE *node;
  
  if (!(node = gedhash_find_xref(HTAB, dataCtxt)))
    printf("CHIL is not pointed to by a FAMC\n");
  return 1;
  } 

This function is designed as a hook.  It will check to see if the pointer in a CHIL node has an
INDI record containing a matching xref.gedhash_get_rec_xref- gedhash.c


Summary

#include "gedcom.h"

NODE  * gedhash_get_rec_xref(HASH_TAB *htab, char *value);


Description

Returns a NODE pointer to the record referenced by the xref in value.  The hash table
associated with htab is used to lookup the location of the record.


Return Value

If successful, returns a NODE pointer to the record, else NULL.


Example

NODE *find_pointer(HASH_TAB *htab, NODE *dataCtxt)
  {
  NODE *node;
    
  if (node = gedhash_get_rec_xref(htab, ged_get_value(dataCtxt)))
    return(node);
  else
    {  
    ged_error(PTR_ERR, dataCtxt); /* Pointer error.  Could not find pointer. */
    return((NODE *)NULL);
    }
  }

This function returns the record being pointed to by the xref in the
value field of dataCtxt.gedhash_insert                    - gedhash.c

                                   
Summary

#include "gedcom.h"

int gedhash_insert(HASH_TAB *htab, void *key, KSIZ keyLen, void *val, MEMSIZ valLen);

Description

Adds a new key/value pair to the hash table associated with htab.  A subsequent call to
gedhash_lookup will use key to look up and return the value pointed to by val.   Will modify
the record if given a pair with the same key. It is not necessary for key or val to be null-
terminated.

keyLen and valLen are also stored in the hash table.  They contain the length of bytes in key
and val, respectively.  If the value of keyLen or valLen is zero, it is assumed that their
counterpart, key or val is NULL-terminated.

Return Value

Returns zero if unsuccessful, or if a duplicate key is found, the return value is 2, otherwise 1 is
returned.

Example

#include "gedcom.h"

void main(int argc, char *argv[])
  {
  HASH_TAB hash_table, *htab;
  char val[400], key[400];
  char *hash_filename = ( argc > 1 ) ? argv[1] : (char *)NULL;
  int c;

  /* Create hash table for htab */
  htab = gedhash_create_table(&hash_table, hash_filename, 31L, (MEMSIZ)5000);
  if (!htab)
   printf("\aCould not create a hash table!!\n");
  for ( c = 1; c < 20; c++)/* Insert integers into htab */
   {
   if (gedhash_insert(htab, &c, (KSIZ)sizeof(int), &c, (LEN)sizeof(int)) 
    == SUCCESS)
    printf("Inserted: %d\n", c);
   else printf("Could not insert a value into the hash table.\n");
   }
  gedhash_close(htab);
  }int gedhash_iterate                                    - gedhash.c

                                   
Summary

#include "gedcom.h"

int gedhash_iterate(HASH_TAB *htab, void *key, KSIZ *keyLen, void *val, LEN *valLen);

Description 

Successively returns every key/val pair in the hash table that is associated with htab.  The order
of returning pairs is undefined.  gedhash_iterate_reset() must be called before calling this
function.  The function is called repeatedly in a loop until it returns zero, indicating that all
pairs have been returned.  keyLen and valLen  contain the length of bytes in key and val,
respectively.  If the value of keyLen or valLen is zero, it is assumed that their counterpart, key
or val is NULL-terminated.


Return Value

Non-zero if a key/val pair is returned, else zero, indicating that  all key/val pairs have been
returned.

Example

#include "gedcom.h"

void main( int argc, char *argv[])
  {
  HASH_TAB hash_table, *htab;
  char *hash_filename = (argc >1 ) ? argv[1] : (char *)NULL;
  char val[40], key[40];
   LEN valLen;
   KSIZ keyLen;
  long c;

  htab = gedhash_create_table(&hash_table, hash_filename, 31L, (MEMSIZ)5000); 
  if (!htab)
   printf("\aCould not create a hash table!!\n");
  gedhash_iterate_reset(htab);
  for ( c = 0L; c < GEDHASH_COUNT(htab); c++)
   {
   if (gedhash_iterate(htab, key, &keyLen, val, &valLen) == 0)
    break;
   printf("key: %d keyLen: %d  val: %d valLen: %ld\n",
       *(int *)key, keyLen, *(int *)val, valLen);
   }
  gedhash_close(htab);
  }gedhash_iterate_reset                                  - gedhash.c


Summary

#include "gedcom.h"

void gedhash_iterate_reset(HASH_TAB *htab);

Description 

Resets internal hash-tab state so that successive calls to gedhash_iterate() will return every
key/value pair in the table that is associated with htab.

Return Value

Returns nothing.

Example

#include "gedcom.h"

void cdecl main( int argc, char *argv[])
  {
  HASH_TAB hash_table, *htab;
  char *hash_filename = (argc >1 ) ? argv[1] : (char *)NULL;

  htab = gedhash_create_table(&hash_table, hash_filename, 31L, (MEMSIZ)5000);
  if (!htab)
    printf("\aCould not create a hash table!!\n");
  gedhash_iterate_reset(htab);
  gedhash_close(htab);
  }gedhash_lookup                                         - gedhash.c


Summary

#include "gedcom.h"

void * 
gedhash_lookup(HASH_TAB *htab, void *key, KSIZ keyLen, void *val, LEN *valLen, int
*status);


Description

gedhash_lookup finds key in the table associated with htab and returns a pointer to the value,
val that is associated with it.  valLen gets the length of val.  If successful, status is assigned one,
else zero.

keyLen and valLen  contain the length of bytes in key and val, respectively.  If the value of
keyLen or valLen is zero, it is assumed that their counterpart, key or val is NULL-terminated.

Return Value

gedhash_lookup() returns a void pointer to val.  If successful, status is assigned 1, else if key
was not found status is assigned KEY_NOT_FOUND.  If htab was not found, status is assigned
HTAB_NOT_FOUND.

Example

#include "gedcom.h"
void main(int argc, char *argv[])
  {
  HASH_TAB hash_table, *htab;
  char val[400], key[400];
  LEN valLen;
  KSIZ keyLen;
  char *hash_filename = (argc >1 ) ? argv[1] : (char *)NULL;
  int c = 21, status, lookup_val;

  htab = gedhash_create_table(&hash_table, hash_filename, 31L, (MEMSIZ)5000) );
  if (!htab)
    printf("\aCould not create a hash table!!\n");
  lookup_val = 
    *(int *)gedhash_lookup(htab, &c, (KSIZ)sizeof(int), val, &valLen, &status);
  if (status==SUCCESS) /* If successful lookup */
    printf(" Search found: %d\n", lookup_val);
  }Index of Function Definitions


ged_alloc_pool. . . . . . . . 2-4
ged_ask . . . . . . . . . . . 2-6
ged_ask_string. . . . . . . . 2-8
ged_ask_xref. . . . . . . . .2-10
ged_clip_word . . . . . . . .2-11
ged_clone_node. . . . . . . .2-12
ged_clone_tree. . . . . . . .2-13
ged_connect_child . . . . . .2-14
ged_connect_sibling . . . . .2-15
ged_copy_node . . . . . . . .2-16
ged_copy_tree . . . . . . . .2-18
ged_create_pool . . . . . . .2-19
Ged_define_semantic . . . . . 3-7
ged_destroy_pool. . . . . . .2-20
ged_get_child . . . . . . . .2-21
ged_get_last_sibling. . . . .2-22
ged_get_line. . . . . . . . .2-23
ged_get_next_node . . . . . .2-24
ged_get_parent. . . . . . . .2-25
ged_get_pool. . . . . . . . .2-26
ged_get_previous_node . . . .2-27
ged_get_previous_sibling. . .2-28
ged_get_sibling . . . . . . .2-29
ged_get_tag . . . . . . . . .2-30
ged_get_value . . . . . . . .2-31
ged_get_xref. . . . . . . . .2-32
ged_inherits. . . . . . . . .2-33
ged_load_grammar. . . . . . . 3-4
ged_make_path . . . . . . . .2-34
ged_match . . . . . . . . . .2-36
ged_match_tags. . . . . . . .2-37
ged_print_indented. . . . . .2-39
Ged_print_levels. . . . . . .2-40
Ged_process . . . . . . . . . 3-3
Ged_promote . . . . . . . . .2-41
Ged_prune_tree. . . . . . . .2-42
Ged_read_rec. . . . . . . . .2-43
Ged_read_tree . . . . . . . .2-45
Ged_remove_node . . . . . . .2-47
Ged_remove_subtree. . . . . .2-49
Ged_reset_pool. . . . . . . .2-51
ged_set_error_handler . . . .2-53
Ged_set_line. . . . . . . . .2-52
                                      Ged_set_pool. . . . . . . . 2-57
                                      Ged_set_tag . . . . . . . . 2-58
                                      Ged_set_value . . . . . . . 2-59
                                      Ged_set_xref. . . . . . . . 2-60
                                      Ged_skip_word . . . . . . . 2-61
                                      Ged_to_tree . . . . . . . . 2-62
                                      ged_traverse. . . . . . . . .3-5
                                      Ged_tree_to_file. . . . . . 2-64
                                      Ged_tree_to_ged . . . . . . 2-66
                                      Gedhash_close . . . . . . . .4-2
                                      Gedhash_copy. . . . . . . . .4-3
                                      GEDHASH_COUNT . . . . . . . .4-4
                                      Gedhash_create_table. . . . .4-5
                                      gedhash_create_xref . . . . .4-6
                                      gedhash_delete. . . . . . . .4-9
                                      gedhash_destroy_table . . . 4-10
                                      gedhash_find_xref . . . . . 4-11
                                      gedhash_fopen . . . . . . . .1-6
                                      gedhash_get_drive . . . . . .1-6
                                      gedhash_get_file. . . . . . .1-6
                                      gedhash_get_rec_xref. . . . 4-12
                                      Gedhash_insert. . . . . . . 4-13
                                      Gedhash_iterate . . . . . . 4-14
                                      Gedhash_iterate_reset . . . 4-15
                                      Gedhash_lookup. . . . . . . 4-16
