cd050df414a0f2e707d0e8b9a71fd0999318046f
[gedcom-parse.git] / usage.html
1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title>Using the GEDCOM parser library</title>
2   
3                                          
4   <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"></head><body text="#000000" bgcolor="#ffffff" link="#000099" vlink="#990099" alink="#000099">
5            
6 <h1 align="center">Using the GEDCOM parser library</h1>
7       <br>
8            
9 <h2>Index</h2>
10          
11 <ul>
12        <li><a href="#anchor">Overview</a></li>
13        <li><a href="#Error_handling">Error handling</a></li>
14        <li><a href="#Data_callback_mechanism">Data callback mechanism</a></li>
15                    
16   <ul>
17          <li><a href="#Start_and_end_callbacks">Start and end callbacks</a></li>
18          <li><a href="#Default_callbacks">Default callbacks</a></li>
19                    
20   </ul>
21       <li><a href="#Other_API_functions">Other API functions</a></li>
22                
23   <ul>
24         <li><a href="#Debugging">Debugging</a></li>
25         <li><a href="#Error_treatment">Error treatment</a></li>
26         <li><a href="#Compatibility_mode">Compatibility mode</a></li>
27                
28   </ul>
29       <li><a href="interface.html">Interface details</a><br>
30          </li>
31          
32 </ul>
33          
34 <hr width="100%" size="2">      
35 <h2><a name="Overview"></a>Overview<br>
36       </h2>
37       The GEDCOM parser library is built as a callback-based parser (comparable
38    to the SAX interface of XML). &nbsp;It comes with:<br>
39            
40 <ul>
41         <li>a library (<code>libgedcom.so</code>), to be linked in the application
42    program</li>
43         <li>a header file (<code>gedcom.h</code>), to be used in the sources
44   of  the application program</li>
45     <li>a header file (<code>gedcom-tags.h</code>) that is also installed,
46  but that is automatically included via <code>gedcom.h</code><br>
47     </li>
48            
49 </ul>
50       Next to these, there is also a data directory in <code>$PREFIX/share/gedcom-parse</code>
51        that contains some additional stuff, but which is not immediately
52 important    at first. &nbsp;I'll leave the description of the data directory
53 for later.<br>
54       <br>
55       The very simplest call of the gedcom parser is simply the following 
56 piece   of code (include of the gedcom header is assumed, as everywhere in 
57 this manual):<br>
58            
59 <blockquote><code>int result;<br>
60       ...<br>
61       result = <b>gedcom_parse_file</b>("myfamily.ged");<br>
62         </code>   </blockquote>
63       Although this will not provide much information, one thing it does
64 is  parse  the entire file and return the result. &nbsp;The function returns 
65 0 on success  and 1 on failure. &nbsp;No other information is available using 
66  this function  only.<br>
67        <br>
68      The next sections will refine this to be able to have meaningful errors
69   and the actual data that is in the file.<br>
70                    
71   <hr width="100%" size="2">                  
72   <h2><a name="Error_handling"></a>Error handling</h2>
73      Since this is a relatively simple topic, it is discussed before the
74 actual   callback mechanism, although it also uses a callback...<br>
75        <br>
76      The library can be used in several different circumstances, both terminal-based 
77   as GUI-based. &nbsp;Therefore, it leaves the actual display of the error 
78  message up to the application. &nbsp;For this, the application needs to register
79  a callback before parsing the GEDCOM file, which will be called by the library
80   on errors, warnings and messages.<br>
81        <br>
82      A typical piece of code would be:<br>
83                    
84   <blockquote><code>void <b>my_message_handler</b> (Gedcom_msg_type type, 
85   char *msg)<br>
86      {<br>
87      &nbsp; ...<br>
88      }<br>
89      ...<br>
90          <b>gedcom_set_message_handler</b>(my_message_handler);<br>
91      ...<br>
92      result = <b>gedcom_parse_file</b>("myfamily.ged");</code><br>
93          </blockquote>
94      In the above piece of code, <code>my_message_handler</code> is the callback 
95   that will be called for errors (<code>type=ERROR</code>), warnings (<code>type=WARNING</code>) and messages (<code>type=MESSAGE</code>). &nbsp;The 
96  callback must have the signature as in the example. &nbsp;For errors, the 
97      <code> msg</code> passed to the callback will have the format:<br>
98                              
99     <blockquote><code>Error on line</code> <i>&lt;lineno&gt;</i>: <i>&lt;actual_message&gt;</i><br>
100            </blockquote>
101      Note that the entire string will be properly internationalized, and
102 encoded   in UTF-8 (see "Why UTF-8?" &nbsp;<i>LINK TBD</i>). &nbsp;Also,
103 no newline   is appended, so that the application program can use it in any
104 way it wants.   &nbsp;Warnings are similar, but use "Warning" instead of
105 "Error". &nbsp;Messages   are plain text, without any prefix.<br>
106            <br>
107      With this in place, the resulting code will already show errors and
108 warnings   produced by the parser, e.g. on the terminal if a simple <code>
109 printf</code>      is used in the message handler.<br>
110                                        
111       <hr width="100%" size="2">                                   
112       <h2><a name="Data_callback_mechanism"></a>Data callback mechanism</h2>
113      The most important use of the parser is of course to get the data out
114  of  the GEDCOM file. &nbsp;As already mentioned, the parser uses a callback 
115  mechanism  for that. &nbsp;In fact, the mechanism involves two levels.<br>
116            <br>
117      The primary level is that each of the sections in a GEDCOM file is notified 
118   to the application code via a "start element" callback and an "end element" 
119   callback (much like in a SAX interface for XML), i.e. when a line containing 
120   a certain tag is parsed, the "start element" callback is called for that 
121  tag, and when all its subordinate lines with their tags have been processed, 
122  the "end element" callback is called for the original tag. &nbsp;Since GEDCOM 
123   is hierarchical, this results in properly nested calls to appropriate "start 
124   element" and "end element" callbacks.<br>
125            <br>
126      However, it would be typical for a genealogy program to support only 
127 a  subset  of the GEDCOM standard, certainly a program that is still under 
128 development.   &nbsp;Moreover, under GEDCOM it is allowed for an application 
129 to define its  own tags, which will typically not &nbsp;be supported by another 
130 application.   &nbsp;Still, in that case, data preservation is important; 
131 it would hardly   be accepted that information that is not understood by a
132 certain program  is just removed.<br>
133            <br>
134      Therefore, the second level of callbacks involves a "default callback".
135   &nbsp;An application needs to subscribe to callbacks for tags it does support,
136   and need to provide a "default callback" which will be called for tags
137 it   doesn't support. &nbsp;The application can then choose to just store
138 the  information that comes via the default callback in plain textual format.<br>
139            <br>
140      After this introduction, let's see what the API looks like...<br>
141            <br>
142                                        
143       <h3><a name="Start_and_end_callbacks"></a>Start and end callbacks</h3>
144                                        
145       <h4><i>Callbacks for records</i> <br>
146            </h4>
147      As a simple example, we will get some information from the header of 
148 a  GEDCOM  file. &nbsp;First, have a look at the following piece of code:<br>
149                                        
150       <blockquote><code>Gedcom_ctxt <b>my_header_start_cb</b> (int level, 
151   <br>
152  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
153 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Gedcom_val xref, <br>
154  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
155 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; char *tag, <br>
156  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
157 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; char *raw_value,<br>
158  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
159 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int parsed_tag, <br>
160  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
161 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Gedcom_val parsed_value)<br>
162      {<br>
163      &nbsp; printf("The header starts\n");<br>
164      &nbsp; return (Gedcom_ctxt)1;<br>
165      }<br>
166              <br>
167      void <b>my_header_end_cb</b> (Gedcom_ctxt self)<br>
168      {<br>
169      &nbsp; printf("The header ends, context is %d\n", (int)self); &nbsp; /* context 
170   will print as "1" */<br>
171      }<br>
172              <br>
173      ...<br>
174              <b>gedcom_subscribe_to_record</b>(REC_HEAD, my_header_start_cb,
175   my_header_end_cb);<br>
176      ...<br>
177      result = <b>gedcom_parse_file</b>("myfamily.ged");</code><br>
178              </blockquote>
179         Using the <code>gedcom_subscribe_to_record</code> function, the application 
180   requests to use the specified callbacks as start and end callback. The end
181   callback is optional: you can pass <code>NULL</code> if you are not interested
182   in the end callback. &nbsp;The identifiers to use as first argument to
183 the   function (here <code>REC_HEAD</code>) are described in the <a href="interface.html#Record_identifiers">
184     interface details</a>.<br>
185              <br>
186      From the name of the function it becomes clear that this function is 
187 specific   to complete records. &nbsp;For the separate elements in records 
188 there is  another function, which we'll see shortly. &nbsp;Again, the callbacks 
189 need  to have the signatures as shown in the example.<br>
190              <br>
191      The <code>Gedcom_ctxt</code> type that is used as a result of the start
192   callback and as an argument to the end callback is vital for passing context
193   necessary for the application. &nbsp;This type is meant to be opaque; in
194  fact, it's a void pointer, so you can pass anything via it. &nbsp;The important
195   thing to know is that the context that the application returns in the start
196   callback will be passed in the end callback as an argument, and as we will
197   see shortly, also to all the directly subordinate elements of the record.<br>
198           <br>
199   The <code>tag</code> is the GEDCOM tag in string format, the <code>parsed_tag</code>
200    is an integer, for which symbolic values are defined as <code>TAG_HEAD,</code>
201    <code>TAG_SOUR,</code> <code>TAG_DATA,</code> ... and <code>USERTAG </code><code></code>
202   for the application-specific tags. &nbsp;These values are defined in the
203  header <code>gedcom-tags.h</code> that is installed, and included via <code>
204   gedcom.h</code> (so no need to include <code>gedcom-tags.h</code> yourself).<br>
205              <br>
206      The example passes a simple integer as context, but an application could 
207   e.g. pass a <code>struct</code> (or an object in a C++ application) that will contain the information for the 
208   header. &nbsp;In the end callback, the application could then e.g. do some 
209   finalizing operations on the <code>struct</code> to put it in its database.<br>
210              <br>
211      (Note that the <code>Gedcom_val</code> type for the <code>xref</code>
212   and <code>parsed_value</code> arguments  was not discussed, see further 
213 for this)<br>
214              <br>
215                                                  
216         <h4><i>Callbacks for elements</i></h4>
217      We will now retrieve the SOUR field (the name of the program that wrote
218   the file) from the header:<br>
219                                                  
220         <blockquote><code>Gedcom_ctxt <b>my_header_source_start_cb</b>(Gedcom_ctxt 
221   parent,<br>
222      &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
223  &nbsp;  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int &nbsp;
224  &nbsp;  &nbsp; &nbsp; level,<br>
225      &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
226  &nbsp;  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; char* &nbsp;
227  &nbsp;  &nbsp; tag,<br>
228      &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
229  &nbsp;  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; char* &nbsp;
230  &nbsp;  &nbsp; raw_value,<br>
231   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
232  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int &nbsp; &nbsp;
233  &nbsp; &nbsp; parsed_tag,<br>
234      &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
235  &nbsp;  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Gedcom_val
236  &nbsp;parsed_value)<br>
237      {<br>
238      &nbsp; char *source = GEDCOM_STRING(parsed_value);<br>
239      &nbsp; printf("This file was written by %s\n", source);<br>
240      &nbsp; return parent;<br>
241      }<br>
242                <br>
243      void <b>my_header_source_end_cb</b>(Gedcom_ctxt parent,<br>
244      &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
245  &nbsp;  &nbsp; &nbsp; &nbsp; &nbsp;Gedcom_ctxt self,<br>
246      &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
247  &nbsp;  &nbsp; &nbsp; &nbsp; &nbsp;Gedcom_val &nbsp;parsed_value)<br>
248      {<br>
249      &nbsp; printf("End of the source description\n");<br>
250      }<br>
251                <br>
252      ...<br>
253                <b>gedcom_subscribe_to_element</b>(ELT_HEAD_SOUR,<br>
254      &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
255  &nbsp;  &nbsp; &nbsp; &nbsp; my_header_source_start_cb,<br>
256      &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
257  &nbsp;  &nbsp; &nbsp; &nbsp; my_header_source_end_cb);<br>
258      ...<br>
259      result = <b>gedcom_parse_file</b>("myfamily.ged");</code><br>
260                </blockquote>
261      The subscription mechanism for elements is similar, only the signatures
262   of the callbacks differ. &nbsp;The signature for the start callback shows
263   that the context of the parent line (here e.g. the <code>struct</code> that
264 describes   the header) is passed to this start callback. &nbsp;The callback
265 itself returns  here in this example the same context, but this can be its own context object
266 of course. &nbsp;The end callback is called with both the context of the
267 parent and the context of itself, which in this example will be the same.
268 &nbsp;Again,  the list of identifiers to use as a first argument for the
269 subscription function  are detailed in the <a href="interface.html#Element_identifiers">
270  interface  details</a> .<br>
271                <br>
272      If we look at the other arguments of the start callback, we see the
273 level   number (the initial number of the line in the GEDCOM file), the tag
274 (e.g.   "SOUR"), and then a raw value, a parsed tag and a parsed value. &nbsp;The
275  raw value is just the raw string that occurs as value on the line next to
276  the tag (in UTF-8 encoding). &nbsp;The parsed value is the meaningful value
277  that is parsed from that raw string. &nbsp;The parsed tag is described in
278  the section for record callbacks above.<br>
279                <br>
280      The <code>Gedcom_val</code> type is meant to be an opaque type. &nbsp;The 
281   only thing that needs to be known about it is that it can contain specific 
282   data types, which have to be retrieved from it using pre-defined macros. 
283  &nbsp;These data types are described in the <a href="interface.html#Gedcom_val_types">
284     interface details</a>.           <br>
285               <br>
286      Some extra notes:<br>
287                                                            
288           <ul>
289                  <li>The <code>Gedcom_val</code> argument of the end callback 
290   is currently not used. &nbsp;It is there for future enhancements.</li>
291                  <li>There are also two <code>Gedcom_val</code> arguments in
292 the   start callback for records. &nbsp;The first one (<code>xref</code>) contains the <code>xref_value</code> corresponding to the cross-reference (or <code>NULL</code> if there isn't one), the second one (<code>parsed_value</code>) contains the value that is parsed from the <code>raw_value</code>. &nbsp;See the&nbsp;<a href="interface.html#Record_identifiers">interface details</a>.</li>
293                                                            
294           </ul>
295                                                            
296           <h3><a name="Default_callbacks"></a>Default callbacks<br>
297                </h3>
298      As described above, an application doesn't always implement the entire 
299  GEDCOM spec, and application-specific tags may have been added by other applications.
300  &nbsp;To preserve this extra data anyway, a default callback can be registered
301  by the application, as in the following example:<br>
302                                                
303           <blockquote><code>void <b>my_default_cb</b> (Gedcom_ctxt parent,
304   int level, char* tag, char* raw_value, int parsed_tag)<br>
305     {<br>
306     &nbsp; ...<br>
307     }<br>
308                 <br>
309     ...<br>
310                 <b>gedcom_set_default_callback</b>(my_default_cb);<br>
311     ...<br>
312     result = <b>gedcom_parse_file</b>("myfamily.ged");</code><br>
313                 </blockquote>
314                This callback has a similar signature as the previous ones,
315  but  it doesn't contain a parsed value. &nbsp;However, it does contain the
316  parent  context, that was returned by the application for the most specific
317  containing  tag that the application supported.<br>
318                 <br>
319     Suppose e.g. that this callback is called for some tags in the header 
320 that  are specific to some other application, then our application could make
321 sure  that the parent context contains the struct or object that represents
322  the  header, and use the default callback here to add the level, tag and
323 raw_value  as plain text in a member of that struct or object, thus preserving
324 the information.  &nbsp;The application can then write this out when the
325 data is saved again  in a GEDCOM file. &nbsp;To make it more specific, consider
326  the following example:<br>
327                                                        
328             <blockquote><code>struct header {<br>
329     &nbsp; char* source;<br>
330     &nbsp; ...<br>
331     &nbsp; char* extra_text;<br>
332     };<br>
333                   <br>
334     Gedcom_ctxt my_header_start_cb(int level, Gedcom_val xref, char* tag, 
335 char *raw_value,<br>
336  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
337 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int parsed_tag, Gedcom_val parsed_value)<br>
338     {<br>
339     &nbsp; struct header head = my_make_header_struct();<br>
340     &nbsp; return (Gedcom_ctxt)head;<br>
341     }<br>
342                   <br>
343     void my_default_cb(Gedcom_ctxt parent, int level, char* tag, char* raw_value,
344  int parsed_tag)<br>
345     {<br>
346     &nbsp; struct header head = (struct header)parent;<br>
347     &nbsp; my_header_add_to_extra_text(head, level, tag, raw_value);<br>
348     }<br>
349                   <br>
350     gedcom_set_default_callback(my_default_cb);<br>
351     gedcom_subscribe_to_record(REC_HEAD, my_header_start, NULL);<br>
352     ...<br>
353     result = gedcom_parse_file(filename);</code><br>
354                   </blockquote>
355     Note that the default callback will be called for any tag that isn't
356 specifically   subscribed upon by the application, and can thus be called
357 in various contexts.   &nbsp;For simplicity, the example above doesn't take
358 this into account (the                 <code>parent</code> could be of different
359 types, depending  on the context).<br>
360               <br>
361 Note also that the default callback is not called when the parent context is&nbsp;<code>NULL</code><code></code>. &nbsp;This is e.g. the case if none of the "upper" tags has been subscribed upon.<br>
362                                                                
363               <hr width="100%" size="2">                                 
364                           
365               <h2><a name="Other_API_functions"></a>Other API functions<br>
366                   </h2>
367     Although the above describes the basic interface of libgedcom, there
368 are   some other functions that allow to customize the behaviour of the library.
369   &nbsp;These will be explained in the current section.<br>
370                                                                
371               <h3><a name="Debugging"></a>Debugging</h3>
372     The library can generate various debugging output, not only from itself,
373   but also the debugging output generated by the yacc parser. &nbsp;By default,
374   no debugging output is generated, but this can be customized using the
375 following   function:<br>
376                                                                
377               <blockquote><code>void <b>gedcom_set_debug_level</b> (int level,
378   FILE* trace_output)</code><br>
379                     </blockquote>
380     The <code>level</code> can be one of the following values:<br>
381                                                                        
382                 <ul>
383                       <li>0: &nbsp;no debugging information (this is the
384 default)</li>
385                       <li>1: &nbsp;only debugging information from libgedcom
386   itself</li>
387                       <li>2: &nbsp;debugging information from libgedcom and 
388  yacc</li>
389                                                                        
390                 </ul>
391     If the <code>trace_output</code> is <code>NULL</code>, debugging information
392   will be written to <code>stderr</code>, otherwise the given file handle
393 is  used (which must be open).<br>
394                     <br>
395                                                                        
396                 <h3><a name="Error_treatment"></a>Error treatment</h3>
397     One of the previous sections already described the callback to be registered
398   to get error messages. &nbsp;The library also allows to customize what
399 happens   on an error, using the following function:<br>
400                                                                        
401                 <blockquote><code>void <b>gedcom_set_error_handling</b> (Gedcom_err_mech
402   mechanism)</code><br>
403                       </blockquote>
404     The <code>mechanism</code> can be one of:<br>
405                                                                         
406       
407                   <ul>
408                         <li><code>IMMED_FAIL</code>: immediately fail the 
409 parsing  on an error (this is the default)</li>
410                         <li><code>DEFER_FAIL</code>: continue parsing after 
411  an error, but return a failure code eventually</li>
412                         <li><code>IGNORE_ERRORS</code>: continue parsing
413 after   an error, return success always</li>
414                                                                         
415       
416                   </ul>
417     This doesn't influence the generation of error or warning messages, only
418   the behaviour of the parser and its return code.<br>
419                       <br>
420                                                                         
421       
422                   <h3><a name="Compatibility_mode"></a>Compatibility mode<br>
423                       </h3>
424     Applications are not necessarily true to the GEDCOM spec (or use a different
425   version than 5.5). &nbsp;The intention is that the library is resilient
426 to  this, and goes in compatibility mode for files written by specific programs
427   (detected via the HEAD.SOUR tag). &nbsp;This compatibility mode can be
428 enabled   and disabled via the following function:<br>
429                                                                         
430       
431                   <blockquote><code>void <b>gedcom_set_compat_handling</b>
432      (int enable_compat)</code><br>
433                         </blockquote>
434     The argument can be:<br>
435                                                                         
436               
437                     <ul>
438                           <li>0: disable compatibility mode</li>
439                           <li>1: allow compatibility mode (this is the default)<br>
440                           </li>
441                                                                         
442               
443                     </ul>
444     Note that, currently, no actual compatibility code is present, but this 
445  is on the to-do list.<br>
446                                                                         
447               
448                     <hr width="100%" size="2">                           
449                                    
450                     <pre><font size="-1">$Id$<br>$Name$</font><br></pre>
451                                                                  
452                     <pre>                    </pre>
453                                                                         
454                               
455                     </body></html>