-
- <h3><a name="Start_and_end_callbacks"></a>Start and end callbacks</h3>
-
- <h4><i>Callbacks for records</i> <br>
- </h4>
- As a simple example, we will get some information from the header of a
-GEDCOM file. First, have a look at the following piece of code:<br>
-
- <blockquote><code>Gedcom_ctxt <b>my_header_start_cb</b> (int level,
- Gedcom_val xref, char *tag, int parsed_tag)<br>
- {<br>
- printf("The header starts\n");<br>
- return (Gedcom_ctxt)1;<br>
- }<br>
- <br>
- void <b>my_header_end_cb</b> (Gedcom_ctxt self)<br>
- {<br>
- printf("The header ends, context is %d\n", self); /* context
- will print as "1" */<br>
- }<br>
- <br>
- ...<br>
- <b>gedcom_subscribe_to_record</b>(REC_HEAD, my_header_start_cb,
- my_header_end_cb);<br>
- ...<br>
- result = <b>gedcom_parse_file</b>("myfamily.ged");</code><br>
- </blockquote>
- Using the <code>gedcom_subscribe_to_record</code> function, the application
- requests to use the specified callbacks as start and end callback. The end
- callback is optional: you can pass <code>NULL</code> if you are not interested
- in the end callback. The identifiers to use as first argument to the
- function (here <code>REC_HEAD</code>) are described in the <a href="interface.html#Record_identifiers">
- interface details</a>.<br>
- <br>
- From the name of the function it becomes clear that this function is specific
- to complete records. For the separate elements in records there is
-another function, which we'll see shortly. Again, the callbacks need
-to have the signatures as shown in the example.<br>
- <br>
- The <code>Gedcom_ctxt</code> type that is used as a result of the start
- callback and as an argument to the end callback is vital for passing context
- necessary for the application. This type is meant to be opaque; in
-fact, it's a void pointer, so you can pass anything via it. The important
- thing to know is that the context that the application returns in the start
- callback will be passed in the end callback as an argument, and as we will
- see shortly, also to all the directly subordinate elements of the record.<br>
- <br>
-The <code>tag</code> is the GEDCOM tag in string format, the <code>parsed_tag</code>
- is an integer, for which symbolic values are defined as <code>TAG_HEAD,</code>
- <code>TAG_SOUR,</code> <code>TAG_DATA,</code> ... and <code>USERTAG </code><code></code>
-for the application-specific tags. These values are defined in the
-header <code>gedcom-tags.h</code> that is installed, and included via <code>
-gedcom.h</code> (so no need to include <code>gedcom-tags.h</code> yourself).<br>
- <br>
- The example passes a simple integer as context, but an application could
- e.g. pass a <code>struct</code> that will contain the information for the
- header. In the end callback, the application could then e.g. do some
- finalizing operations on the <code>struct</code> to put it in its database.<br>
- <br>
- (Note that the <code>Gedcom_val</code> type for the <code>xref</code>
-argument was not discussed, see further for this)<br>
- <br>
-
- <h4><i>Callbacks for elements</i></h4>
- We will now retrieve the SOUR field (the name of the program that wrote
- the file) from the header:<br>
-
- <blockquote><code>Gedcom_ctxt <b>my_header_source_start_cb</b>(Gedcom_ctxt
- parent,<br>
-
- int
- level,<br>
-
- char*
- tag,<br>
-
- char*
- raw_value,<br>
-
- int
- parsed_tag,<br>
-
- Gedcom_val
- parsed_value)<br>
- {<br>
- char *source = GEDCOM_STRING(parsed_value);<br>
- printf("This file was written by %s\n", source);<br>
- return parent;<br>
- }<br>
- <br>
- void <b>my_header_source_end_cb</b>(Gedcom_ctxt parent,<br>
-
- Gedcom_ctxt self,<br>
-
- Gedcom_val parsed_value)<br>
- {<br>
- printf("End of the source description\n");<br>
- }<br>
- <br>
- ...<br>
- <b>gedcom_subscribe_to_element</b>(ELT_HEAD_SOUR,<br>
-
- my_header_source_start_cb,<br>
-
- my_header_source_end_cb);<br>
- ...<br>
- result = <b>gedcom_parse_file</b>("myfamily.ged");</code><br>
- </blockquote>
- The subscription mechanism for elements is similar, only the signatures
- of the callbacks differ. The signature for the start callback shows
- that the context of the parent line (e.g. the <code>struct</code> that describes
- the header) is passed to this start callback. The callback itself returns
- here the same context, but this can be its own context object of course.
- The end callback is called with both the context of the parent and
-the context of itself, which will be the same in the example. Again,
-the list of identifiers to use as a first argument for the subscription function
-are detailed in the <a href="interface.html#Element_identifiers">interface
-details</a> .<br>
- <br>
- If we look at the other arguments of the start callback, we see the level
- number (the initial number of the line in the GEDCOM file), the tag (e.g.
- "SOUR"), and then a raw value, a parsed tag and a parsed value. The
-raw value is just the raw string that occurs as value on the line next to
-the tag (in UTF-8 encoding). The parsed value is the meaningful value
-that is parsed from that raw string. The parsed tag is described in
-the section for record callbacks.<br>
- <br>
- The <code>Gedcom_val</code> type is meant to be an opaque type. The
- only thing that needs to be known about it is that it can contain specific
- data types, which have to be retrieved from it using pre-defined macros.
- These data types are described in the <a href="interface.html#Gedcom_val_types">
- interface details</a>. <br>
- <br>
- Some extra notes:<br>
-
- <ul>
- <li>The <code>Gedcom_val</code> argument of the end callback
- is currently not used. It is there for future enhancements.</li>
- <li>There is also a <code>Gedcom_val</code> argument in the
- start callback for records. This argument is currently a string value
- giving the pointer in string form.</li>
-
- </ul>
-
- <h3><a name="Default_callbacks"></a>Default callbacks<br>
- </h3>
- As described above, an application doesn't always implement the entire
-GEDCOM spec, and application-specific tags may have been added by other applications.
- To preserve this extra data anyway, a default callback can be registered
- by the application, as in the following example:<br>
-
- <blockquote><code>void <b>my_default_cb</b> (Gedcom_ctxt parent,
- int level, char* tag, char* raw_value, int parsed_tag)<br>
- {<br>
- ...<br>
- }<br>
- <br>