Test program for cross-reference updates.
[gedcom-parse.git] / t / src / gomtest.c
1 /* Test program for the Gedcom library.
2    Copyright (C) 2001, 2002 The Genes Development Team
3    This file is part of the Gedcom parser library.
4    Contributed by Peter Verthez <Peter.Verthez@advalvas.be>, 2001.
5
6    The Gedcom parser library is free software; you can redistribute it
7    and/or modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The Gedcom parser library is distributed in the hope that it will be
12    useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the Gedcom parser library; if not, write to the
18    Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
21 /* $Id$ */
22 /* $Name$ */
23
24 #include "gom.h"
25 #include <stdio.h>
26 #include <stdarg.h>
27 #include <locale.h>
28 #include "gedcom.h"
29
30 #define OUTFILE "testgedcom.out"
31 FILE* outfile = NULL;
32 int quiet = 0;
33
34 void output(int to_stdout_too, char* format, ...)
35 {
36   va_list ap;
37   va_start(ap, format);
38   if (outfile) {
39     vfprintf(outfile, format, ap);
40   }
41   if (to_stdout_too && !quiet) {
42     vprintf(format, ap);
43   }
44   va_end(ap);
45 }
46
47 void show_help ()
48 {
49   printf("gedcom-parse test program for libgedcom and libgom\n\n");
50   printf("Usage:  gom_test [options] file\n");
51   printf("Options:\n");
52   printf("  -h    Show this help text\n");
53   printf("  -nc   Disable compatibility mode\n");
54   printf("  -fi   Fail immediately on errors\n");
55   printf("  -fd   Deferred fail on errors, but parse completely\n");
56   printf("  -fn   No fail on errors\n");
57   printf("  -dg   Debug setting: only libgedcom debug messages\n");
58   printf("  -da   Debug setting: libgedcom + yacc debug messages\n");
59   printf("  -q    No output to standard output\n");
60 }
61
62 void gedcom_message_handler(Gedcom_msg_type type, char *msg)
63 {
64   output(1, "%s\n", msg);
65 }
66
67 char* make_prefix(int depth)
68 {
69   char* prefix = (char*)calloc(depth+1, sizeof(char));
70   memset(prefix, ' ', depth);
71   return prefix;
72 }
73
74 void dump_xref(int st, int prefix_depth, struct xref_value* xr);
75
76 void dump_user_data(int st, int prefix_depth, struct user_data* data)
77 {
78   char* prefix = make_prefix(prefix_depth);
79   if (data) {
80     output(st, "\n");
81     for (data; data; data = data->next) {
82       output(st, "%sData: \n", prefix);
83       output(st, "%s  %d, %s, %s\n", prefix, data->level, data->tag, data->str_value);
84       output(st, "%s  reference: ", prefix);
85       dump_xref(st, prefix_depth + 4, data->xref_value);
86     }
87   }
88   else {
89     output(st, "%p\n", data);
90   }
91   free(prefix);
92 }
93
94 void dump_address(int st, int prefix_depth, struct address* addr)
95 {
96   char* prefix = make_prefix(prefix_depth);
97   if (addr) {
98     output(st, "\n");
99     output(st, "%sFull label: %s\n", prefix, addr->full_label);
100     output(st, "%sLine 1: %s\n", prefix, addr->line1);
101     output(st, "%sLine 2: %s\n", prefix, addr->line2);
102     output(st, "%sCity: %s\n", prefix, addr->city);
103     output(st, "%sState: %s\n", prefix, addr->state);
104     output(st, "%sPostal: %s\n", prefix, addr->postal);
105     output(st, "%sCountry: %s\n", prefix, addr->country);
106     output(st, "%sUser data:", prefix);
107     dump_user_data(st, prefix_depth + 2, addr->extra);
108   }
109   else {
110     output(st, "%p\n", addr);
111   }
112   free(prefix);
113 }
114
115 void dump_date(int st, int prefix_depth, struct date_value* dv)
116 {
117   char* prefix = make_prefix(prefix_depth);
118   if (dv) {
119     output(st, "\n");
120     output(st, "%stype: %d\n", prefix, dv->type);
121     output(st, "%sdate1:\n", prefix);
122     output(st, "%s  calendar type: %d\n", prefix, dv->date1.cal);
123     output(st, "%s  day: %s\n", prefix, dv->date1.day_str);
124     output(st, "%s  month: %s\n", prefix, dv->date1.month_str);
125     output(st, "%s  year: %s\n", prefix, dv->date1.year_str);
126     output(st, "%s  date type: %d\n", prefix, dv->date1.type);
127     output(st, "%s  sdn1: %ld\n", prefix, dv->date1.sdn1);
128     output(st, "%s  sdn2: %ld\n", prefix, dv->date1.sdn2);
129     output(st, "%sdate2:\n", prefix);
130     output(st, "%s  calendar type: %d\n", prefix, dv->date2.cal);
131     output(st, "%s  day: %s\n", prefix, dv->date2.day_str);
132     output(st, "%s  month: %s\n", prefix, dv->date2.month_str);
133     output(st, "%s  year: %s\n", prefix, dv->date2.year_str);
134     output(st, "%s  date type: %d\n", prefix, dv->date2.type);
135     output(st, "%s  sdn1: %ld\n", prefix, dv->date2.sdn1);
136     output(st, "%s  sdn2: %ld\n", prefix, dv->date2.sdn2);
137     output(st, "%sphrase: %s\n", prefix, dv->phrase);
138   }
139   else {
140     output(st, "%p\n", dv);
141   }
142   free(prefix);
143 }
144
145 void dump_age(int st, int prefix_depth, struct age_value* age)
146 {
147   char* prefix = make_prefix(prefix_depth);
148   if (age) {
149     output(st, "\n");
150     output(st, "%stype: %d\n", prefix, age->type);
151     output(st, "%smodifier: %d\n", prefix, age->mod);
152     output(st, "%syears: %d\n", prefix, age->years);
153     output(st, "%smonths: %d\n", prefix, age->months);
154     output(st, "%sdays: %d\n", prefix, age->days);
155     output(st, "%sphrase: %s\n", prefix, age->phrase);
156   }
157   else {
158     output(st, "%p\n", age);
159   }
160   free(prefix);
161 }
162
163 void dump_xref(int st, int prefix_depth, struct xref_value* xr)
164 {
165   char* prefix = make_prefix(prefix_depth);
166   if (xr) {
167     output(st, "\n");
168     output(st, "%stype: %d\n", prefix, xr->type);
169     output(st, "%sxref: %s\n", prefix, xr->string);
170     output(st, "%sobject: %p\n", prefix, xr->object);
171   }
172   else {
173     output(st, "%p\n", xr);
174   }
175   free(prefix);
176 }
177
178 void dump_xref_list(int st, int prefix_depth, struct xref_list* xr)
179 {
180   char* prefix = make_prefix(prefix_depth);
181   if (xr) {
182     output(st, "\n");
183     for (xr; xr; xr = xr->next) {
184       output(st, "%sreference: ", prefix);
185       dump_xref(st, prefix_depth + 2, xr->xref);
186       output(st, "%sUser data:", prefix);
187       dump_user_data(st, prefix_depth + 2, xr->extra);
188     }
189   }
190   else {
191     output(st, "%p\n", xr);
192   }
193   free(prefix);
194 }
195
196 void dump_texts(int st, int prefix_depth, struct text* t)
197 {
198   char* prefix = make_prefix(prefix_depth);
199   if (t) {
200     output(st, "\n");
201     for (t; t; t = t->next) {
202       output(st, "%sText: %s\n", prefix, t->text);
203       output(st, "%sUser data:", prefix);
204       dump_user_data(st, prefix_depth + 2, t->extra);
205     }
206   }
207   else {
208     output(st, "%p\n", t);
209   }
210   free(prefix);
211 }
212
213 void dump_user_ref(int st, int prefix_depth, struct user_ref_number* ref)
214 {
215   char* prefix = make_prefix(prefix_depth);
216   if (ref) {
217     output(st, "\n");
218     for (ref; ref; ref = ref->next) {
219       output(st, "%sValue: %s\n", prefix, ref->value);
220       output(st, "%sType: %s\n", prefix, ref->type);
221       output(st, "%sUser data:", prefix);
222       dump_user_data(st, prefix_depth + 2, ref->extra);
223     }
224   }
225   else {
226     output(st, "%p\n", ref);
227   }
228   free(prefix);
229 }
230
231 void dump_citations(int st, int prefix_depth, struct source_citation* cit);
232
233 void dump_note_sub(int st, int prefix_depth, struct note_sub* note)
234 {
235   char* prefix = make_prefix(prefix_depth);
236   if (note) {
237     output(st, "\n");
238     for (note; note; note = note->next) {
239       output(st, "%sNote: \n", prefix);
240       output(st, "%s  text: %s\n", prefix, note->text);
241       output(st, "%s  reference: ", prefix);
242       dump_xref(st, prefix_depth + 4, note->reference);
243       output(st, "%s  citations: ", prefix);
244       dump_citations(st, prefix_depth + 4, note->citation);
245       output(st, "%s  User data:", prefix);
246       dump_user_data(st, prefix_depth + 4, note->extra);
247     }
248   }
249   else {
250     output(st, "%p\n", note);
251   }
252   free(prefix);
253 }
254
255 void dump_mm_links(int st, int prefix_depth, struct multimedia_link* link)
256 {
257   char* prefix = make_prefix(prefix_depth);
258   if (link) {
259     output(st, "\n");
260     for (link; link; link = link->next) {
261       output(st, "%slink: \n", prefix);
262       output(st, "%s  reference: ", prefix);
263       dump_xref(st, prefix_depth + 4, link->reference);
264       output(st, "%s  Form: %s\n", prefix, link->form);
265       output(st, "%s  Title: %s\n", prefix, link->title);
266       output(st, "%s  File: %s\n", prefix, link->file);      
267       output(st, "%s  notes: ", prefix);
268       dump_note_sub(st, prefix_depth + 4, link->note);
269       output(st, "%s  User data:", prefix);
270       dump_user_data(st, prefix_depth + 4, link->extra);
271     }
272   }
273   else {
274     output(st, "%p\n", link);
275   }
276   free(prefix);
277 }
278
279 void dump_citations(int st, int prefix_depth, struct source_citation* cit)
280 {
281   char* prefix = make_prefix(prefix_depth);
282   if (cit) {
283     output(st, "\n");
284     for (cit; cit; cit = cit->next) {
285       output(st, "%sCitation: \n", prefix);
286       output(st, "%s  description: %s\n", prefix, cit->description);
287       output(st, "%s  reference: ", prefix);
288       dump_xref(st, prefix_depth + 4, cit->reference);
289       output(st, "%s  page: %s\n", prefix, cit->page);
290       output(st, "%s  event: %s\n", prefix, cit->event);
291       output(st, "%s  role: %s\n", prefix, cit->role);
292       output(st, "%s  Date: ", prefix);
293       dump_date(st, prefix_depth + 4, cit->date);
294       output(st, "%s  texts: ", prefix, prefix);
295       dump_texts(st, prefix_depth + 4, cit->text);
296       output(st, "%s  quality: %s\n", prefix, cit->quality);
297       output(st, "%s  multimedia links: ", prefix);
298       dump_mm_links(st, prefix_depth + 4, cit->mm_link);
299       output(st, "%s  notes: ", prefix);
300       dump_note_sub(st, prefix_depth + 4, cit->note);
301       output(st, "%s  User data:", prefix);
302       dump_user_data(st, prefix_depth + 4, cit->extra);
303     }
304   }
305   else {
306     output(st, "%p\n", cit);
307   }
308   free(prefix);
309 }
310
311 void dump_lds(int st, int prefix_depth, struct lds_event* lds)
312 {
313   char* prefix = make_prefix(prefix_depth);
314   if (lds) {
315     output(st, "\n");
316     for (lds; lds; lds = lds->next) {
317       output(st, "%sDate status: %s\n", prefix, lds->date);
318       output(st, "%sDate: ", prefix);
319       dump_date(st, prefix_depth + 2, lds->date);
320       output(st, "%sTemple code: %s\n", prefix, lds->temple_code);
321       output(st, "%sPlace living ordinance: %s\n", prefix,
322              lds->place_living_ordinance);
323       output(st, "%scitations: ", prefix);
324       dump_citations(st, prefix_depth + 2, lds->citation);
325       output(st, "%snotes: ", prefix);
326       dump_note_sub(st, prefix_depth + 2, lds->note);
327       output(st, "%sfamily: ", prefix);
328       dump_xref(st, prefix_depth + 2, lds->family);
329       output(st, "%sUser data:", prefix);
330       dump_user_data(st, prefix_depth + 2, lds->extra);
331     }
332   }
333   else {
334     output(st, "%p\n", lds);
335   }
336   free(prefix);
337 }
338
339 void dump_change_date(int st, int prefix_depth, struct change_date* chan)
340 {
341   char* prefix = make_prefix(prefix_depth);
342   if (chan) {
343     output(st, "\n");
344     output(st, "%sDate: ", prefix);
345     dump_date(st, prefix_depth + 2, chan->date);
346     output(st, "%sTime: %s\n", prefix, chan->time);
347     output(st, "%snotes: ", prefix);
348     dump_note_sub(st, prefix_depth + 2, chan->note);
349     output(st, "%sUser data:", prefix);
350     dump_user_data(st, prefix_depth + 2, chan->extra);
351   }
352   else {
353     output(st, "%p\n", chan);
354   }
355   free(prefix);
356 }
357
358 void dump_personal_name(int st, int prefix_depth, struct personal_name* name)
359 {
360   char* prefix = make_prefix(prefix_depth);
361   if (name) {
362     output(st, "\n");
363     for (name; name; name = name->next) {
364       output(st, "%sName: \n", prefix);
365       output(st, "%s  Name: %s\n", prefix, name->name);
366       output(st, "%s  Prefix: %s\n", prefix, name->prefix);
367       output(st, "%s  Given: %s\n", prefix, name->given);
368       output(st, "%s  Nickname: %s\n", prefix, name->nickname);
369       output(st, "%s  Surname prefix: %s\n", prefix, name->surname_prefix);
370       output(st, "%s  Surname: %s\n", prefix, name->surname);
371       output(st, "%s  Suffix: %s\n", prefix, name->suffix);
372       output(st, "%s  citations: ", prefix);
373       dump_citations(st, prefix_depth + 4, name->citation);
374       output(st, "%s  notes: ", prefix);
375       dump_note_sub(st, prefix_depth + 4, name->note);
376       output(st, "%s  User data:", prefix);
377       dump_user_data(st, prefix_depth + 4, name->extra);
378     }
379   }
380   else {
381     output(st, "%p\n", name);
382   }
383   free(prefix);
384 }
385
386 void dump_pedigree(int st, int prefix_depth, struct pedigree* p)
387 {
388   char* prefix = make_prefix(prefix_depth);
389   if (p) {
390     output(st, "\n");
391     for (p; p; p = p->next) {
392       output(st, "%sPedigree: %s\n", prefix, p->pedigree);
393       output(st, "%sUser data:", prefix);
394       dump_user_data(st, prefix_depth + 2, p->extra);
395     }
396   }
397   else {
398     output(st, "%p\n", p);
399   }
400   free(prefix);
401 }
402
403 void dump_family_link(int st, int prefix_depth, struct family_link *link)
404 {
405   char* prefix = make_prefix(prefix_depth);
406   if (link) {
407     output(st, "\n");
408     for (link; link; link = link->next) {
409       output(st, "%sFamily:\n", prefix);
410       output(st, "%s  Family: ", prefix);
411       dump_xref(st, prefix_depth + 4, link->family);
412       output(st, "%s  pedigrees: ", prefix);
413       dump_pedigree(st, prefix_depth + 4, link->pedigree);
414       output(st, "%s  notes: ", prefix);
415       dump_note_sub(st, prefix_depth + 4, link->note);
416       output(st, "%s  User data:", prefix);
417       dump_user_data(st, prefix_depth + 4, link->extra);
418     }
419   }
420   else {
421     output(st, "%p\n", link);
422   }
423   free(prefix);
424 }
425
426 void dump_association(int st, int prefix_depth, struct association *assoc)
427 {
428   char* prefix = make_prefix(prefix_depth);
429   if (assoc) {
430     output(st, "\n");
431     for (assoc; assoc; assoc = assoc->next) {
432       output(st, "%sAssociation:\n", prefix);
433       output(st, "%s  To:\n", prefix);
434       dump_xref(st, prefix_depth + 4, assoc->to);
435       output(st, "%s  Type: %s\n", prefix, assoc->type);
436       output(st, "%s  Relation: %s\n", assoc->relation);
437       output(st, "%s  citations: ", prefix);
438       dump_citations(st, prefix_depth + 4, assoc->citation);
439       output(st, "%s  notes: ", prefix);
440       dump_note_sub(st, prefix_depth + 4, assoc->note);
441       output(st, "%s  User data:", prefix);
442       dump_user_data(st, prefix_depth + 4, assoc->extra);
443     }
444   }
445   else {
446     output(st, "%p\n", assoc);
447   }
448   free(prefix);
449 }
450
451 void dump_place(int st, int prefix_depth, struct place* place)
452 {
453   char* prefix = make_prefix(prefix_depth);
454   if (place) {
455     output(st, "\n");
456     output(st, "%svalue: %s\n", prefix, place->value);
457     output(st, "%splace_hierarchy: %s\n", prefix, place->place_hierarchy);
458     output(st, "%scitations: ", prefix);
459     dump_citations(st, prefix_depth + 2, place->citation);
460     output(st, "%snotes: ", prefix);
461     dump_note_sub(st, prefix_depth + 2, place->note);
462     output(st, "%sUser data:", prefix);
463     dump_user_data(st, prefix_depth + 2, place->extra);
464   }
465   else {
466     output(st, "%p\n", place);
467   }
468   free(prefix);
469 }
470
471 void dump_source_events(int st, int prefix_depth, struct source_event* evt)
472 {
473   char* prefix = make_prefix(prefix_depth);
474   if (evt) {
475     output(st, "\n");
476     for (evt; evt; evt = evt->next) {
477       output(st, "%sEvent:\n", prefix);
478       output(st, "%s  Recorded events: %s\n", prefix, evt->recorded_events);
479       output(st, "%s  Date period: ", prefix);
480       dump_date(st, prefix_depth + 4, evt->date_period);
481       output(st, "%s  Jurisdiction: %s\n", prefix, evt->jurisdiction);
482       output(st, "%s  User data:", prefix);
483       dump_user_data(st, prefix_depth + 4, evt->extra);
484     }
485   }
486   else {
487     output(st, "%p\n", evt);
488   }
489   free(prefix);
490 }
491
492 void dump_source_descriptions(int st, int prefix_depth,
493                               struct source_description* desc)
494 {
495   char* prefix = make_prefix(prefix_depth);
496   if (desc) {
497     output(st, "\n");
498     for (desc; desc; desc = desc->next) {
499       output(st, "%sSource description:\n", prefix);
500       output(st, "%s  Call number: %s\n", prefix, desc->call_number);
501       output(st, "%s  Media: %s\n", prefix, desc->media);
502       output(st, "%s  User data:", prefix);
503       dump_user_data(st, prefix_depth + 4, desc->extra);
504     }
505   }
506   else {
507     output(st, "%p\n", desc);
508   }
509   free(prefix);
510 }
511
512 void dump_events(int st, int prefix_depth, struct event *evt)
513 {
514   char* prefix = make_prefix(prefix_depth);
515   if (evt) {
516     output(st, "\n");
517     for (evt; evt; evt = evt->next) {
518       output(st, "%sEvent: %d (%s)\n", prefix, evt->event, evt->event_name);
519       output(st, "%s  Value: %s\n", prefix, evt->val);
520       output(st, "%s  Type: %s\n", prefix, evt->type);
521       output(st, "%s  Date: ", prefix);
522       dump_date(st, prefix_depth + 4, evt->date);
523       output(st, "%s  Place: ", prefix);
524       dump_place(st, prefix_depth + 4, evt->place);
525       output(st, "%s  Address: ", prefix);
526       dump_address(st, prefix_depth + 4, evt->address);
527       output(st, "%s  Phone 1: %s\n", prefix, evt->phone[0]);
528       output(st, "%s  Phone 2: %s\n", prefix, evt->phone[1]);
529       output(st, "%s  Phone 3: %s\n", prefix, evt->phone[2]);
530       output(st, "%s  Age: ", prefix);
531       dump_age(st, prefix_depth + 4, evt->age);
532       output(st, "%s  Agency: %s\n", prefix, evt->agency);
533       output(st, "%s  Cause: %s\n", prefix, evt->cause);
534       output(st, "%s  citations: ", prefix);
535       dump_citations(st, prefix_depth + 4, evt->citation);
536       output(st, "%s  multimedia links: ", prefix);
537       dump_mm_links(st, prefix_depth + 4, evt->mm_link);
538       output(st, "%s  notes: ", prefix);
539       dump_note_sub(st, prefix_depth + 4, evt->note);
540       output(st, "%s  Age of husband: ", prefix);
541       dump_age(st, prefix_depth + 4, evt->husband_age);
542       output(st, "%s  Age of wife: ", prefix);
543       dump_age(st, prefix_depth + 4, evt->wife_age);
544       output(st, "%s  Family: ", prefix);
545       dump_xref(st, prefix_depth + 4, evt->family);
546       output(st, "%s  Adoption parent: %s\n", prefix, evt->adoption_parent);
547       output(st, "%s  User data:", prefix);
548       dump_user_data(st, prefix_depth + 4, evt->extra);
549     }
550   }
551   else {
552     output(st, "%p\n", evt);
553   }
554   free(prefix);
555 }
556
557 void dump_header()
558 {
559   struct header* header = gom_get_header();
560   output(1, "=== HEADER ===\n");
561   output(0, "Source:\n");
562   output(0, "  ID: %s\n", header->source.id);
563   output(0, "  Name: %s\n", header->source.name);
564   output(0, "  Version: %s\n", header->source.version);
565   output(0, "  Corporation:\n");
566   output(0, "    Name: %s\n", header->source.corporation.name);
567   output(0, "    Address: ");
568   dump_address(0, 6, header->source.corporation.address);
569   output(0, "    Phone 1: %s\n", header->source.corporation.phone[0]);
570   output(0, "    Phone 2: %s\n", header->source.corporation.phone[1]);
571   output(0, "    Phone 3: %s\n", header->source.corporation.phone[2]);
572   output(0, "  Data:\n");
573   output(0, "    Name: %s\n", header->source.data.name);
574   output(0, "    Date: ");
575   dump_date(0, 6, header->source.data.date);
576   output(0, "    Copyright: %s\n", header->source.data.copyright);
577   output(0, "Destination: %s\n", header->destination);
578   output(0, "Date: ");
579   dump_date(0, 2, header->date);
580   output(0, "Time: %s\n", header->time);
581   output(0, "Submitter: ");
582   dump_xref(0, 2, header->submitter);
583   output(0, "Submission: ");
584   dump_xref(0, 2, header->submission);
585   output(0, "File name: %s\n", header->filename);
586   output(0, "Copyright: %s\n", header->copyright);
587   output(0, "Gedcom:\n");
588   output(0, "  Version: %s\n", header->gedcom.version);
589   output(0, "  Form: %s\n", header->gedcom.form);
590   output(0, "Character set:\n");
591   output(0, "  Name: %s\n", header->charset.name);
592   output(0, "  Version: %s\n", header->charset.version);
593   output(0, "Language: %s\n", header->language);
594   output(0, "Place hierarchy: %s\n", header->place_hierarchy);
595   output(0, "Note:\n");
596   output(0, "====\n");
597   output(0, "%s\n", header->note);
598   output(0, "====\n");
599   output(0, "User data:");
600   dump_user_data(0, 2, header->extra);
601 }
602
603 void dump_submission()
604 {
605   struct submission* subn = gom_get_submission();
606   if (subn) {
607     output(1, "=== SUBMISSION (%s) ===\n", subn->xrefstr);
608     output(0, "Submitter: ");
609     dump_xref(0, 2, subn->submitter);
610     output(0, "Family file: %s\n", subn->family_file);
611     output(0, "Temple code: %s\n", subn->temple_code);
612     output(0, "Nr of ancestor generations: %s\n", subn->nr_of_ancestor_gens);
613     output(0, "Nr of descendant generations: %s\n",
614            subn->nr_of_descendant_gens);
615     output(0, "Ordinance process flag: %s\n", subn->ordinance_process_flag);
616     output(0, "Record id: %s\n", subn->record_id);
617     output(0, "User data:");
618     dump_user_data(0, 2, subn->extra);
619   }
620 }
621
622 void dump_families()
623 {
624   struct family* fam = gom_get_first_family();
625   for (fam; fam; fam = fam->next) {
626     output(1, "=== FAMILY (%s) ===\n", fam->xrefstr);
627     output(0, "Family events: ");
628     dump_events(0, 2, fam->event);
629     output(0, "Husband: ");
630     dump_xref(0, 2, fam->husband);
631     output(0, "Wife: ");
632     dump_xref(0, 2, fam->wife);
633     output(0, "Children: ");
634     dump_xref_list(0, 2, fam->children);
635     output(0, "Number of children: %s\n", fam->nr_of_children);
636     output(0, "Submitters: ");
637     dump_xref_list(0, 2, fam->submitters);
638     output(0, "LDS spouse sealings: ");
639     dump_lds(0, 2, fam->lds_spouse_sealing);
640     output(0, "citations: ");
641     dump_citations(0, 2, fam->citation);
642     output(0, "multimedia links: ");
643     dump_mm_links(0, 2, fam->mm_link);
644     output(0, "notes: ");
645     dump_note_sub(0, 2, fam->note);
646     output(0, "user refs: ");
647     dump_user_ref(0, 2, fam->ref);
648     output(0, "Record ID: %s\n", fam->record_id);
649     output(0, "change date: ");
650     dump_change_date(0, 2, fam->change_date);
651     output(0, "User data:");
652     dump_user_data(0, 2, fam->extra);
653   }
654 }
655
656 void dump_individuals()
657 {
658   struct individual* indiv = gom_get_first_individual();
659   for (indiv; indiv; indiv = indiv->next) {
660     output(1, "=== INDIVIDUAL (%s) ===\n", indiv->xrefstr);
661     output(0, "Restriction notice: %s\n", indiv->restriction_notice);
662     output(0, "names: ");
663     dump_personal_name(0, 2, indiv->name);
664     output(0, "Sex: %s\n", indiv->sex);
665     output(0, "Individual events: ");
666     dump_events(0, 2, indiv->event);
667     output(0, "Individual attributes: ");
668     dump_events(0, 2, indiv->attribute);
669     output(0, "LDS individual ordinance: ");
670     dump_lds(0, 2, indiv->lds_individual_ordinance);
671     output(0, "Child to family links: ");
672     dump_family_link(0, 2, indiv->child_to_family);
673     output(0, "Spouse to family links: ");
674     dump_family_link(0, 2, indiv->spouse_to_family);
675     output(0, "Submitters: ");
676     dump_xref_list(0, 2, indiv->submitters);
677     output(0, "Associations: ");
678     dump_association(0, 2, indiv->association);
679     output(0, "Aliases: ");
680     dump_xref_list(0, 2, indiv->alias);
681     output(0, "Ancestor interest: ");
682     dump_xref_list(0, 2, indiv->ancestor_interest);
683     output(0, "Descendant interest: ");
684     dump_xref_list(0, 2, indiv->descendant_interest);
685     output(0, "citations: ");
686     dump_citations(0, 2, indiv->citation);
687     output(0, "multimedia links: ");
688     dump_mm_links(0, 2, indiv->mm_link);
689     output(0, "notes: ");
690     dump_note_sub(0, 2, indiv->note);
691     output(0, "Record file nr: %s\n", indiv->record_file_nr);
692     output(0, "Ancestral file nr: %s\n", indiv->ancestral_file_nr);
693     output(0, "user refs: ");
694     dump_user_ref(0, 2, indiv->ref);
695     output(0, "Record ID: %s\n", indiv->record_id);
696     output(0, "change date: ");
697     dump_change_date(0, 2, indiv->change_date);
698     output(0, "User data:");
699     dump_user_data(0, 2, indiv->extra);
700   }
701 }
702
703 void dump_multimedia()
704 {
705   struct multimedia* obj = gom_get_first_multimedia();
706   for (obj; obj; obj = obj->next) {
707     output(1, "=== MULTIMEDIA (%s) ===\n", obj->xrefstr);
708     output(0, "Form: %s\n", obj->form);
709     output(0, "Title: %s\n", obj->title);
710     output(0, "notes: ");
711     dump_note_sub(0, 2, obj->note);
712     output(0, "Data: %s\n", obj->data);
713     output(0, "Continued: ");
714     dump_xref(0, 2, obj->continued);
715     output(0, "user refs: ");
716     dump_user_ref(0, 2, obj->ref);
717     output(0, "Record ID: %s\n", obj->record_id);
718     output(0, "change date: ");
719     dump_change_date(0, 2, obj->change_date);
720     output(0, "User data:");
721     dump_user_data(0, 2, obj->extra);
722   }  
723 }
724
725 void dump_notes()
726 {
727   struct note* note = gom_get_first_note();
728   for (note; note; note = note->next) {
729     output(1, "=== NOTE (%s) ===\n", note->xrefstr);
730     output(0, "Text: %s\n", note->text);
731     output(0, "citations: ");
732     dump_citations(0, 2, note->citation);
733     output(0, "user refs: ");
734     dump_user_ref(0, 2, note->ref);
735     output(0, "Record ID: %s\n", note->record_id);
736     output(0, "change date: ");
737     dump_change_date(0, 2, note->change_date);
738     output(0, "User data:");
739     dump_user_data(0, 2, note->extra);
740   }  
741 }
742
743 void dump_repositories()
744 {
745   struct repository* repo = gom_get_first_repository();
746   for (repo; repo; repo = repo->next) {
747     output(1, "=== REPOSITORY (%s) ===\n", repo->xrefstr);
748     output(0, "Name: %s\n", repo->name);
749     output(0, "Address: ");
750     dump_address(0, 2, repo->address);
751     output(0, "Phone 1: %s\n", repo->phone[0]);
752     output(0, "Phone 2: %s\n", repo->phone[1]);
753     output(0, "Phone 3: %s\n", repo->phone[2]);
754     output(0, "notes: ");
755     dump_note_sub(0, 2, repo->note);
756     output(0, "user refs: ");
757     dump_user_ref(0, 2, repo->ref);
758     output(0, "Record ID: %s\n", repo->record_id);
759     output(0, "change date: ");
760     dump_change_date(0, 2, repo->change_date);
761     output(0, "User data:");
762     dump_user_data(0, 2, repo->extra);
763   }  
764 }
765
766 void dump_sources()
767 {
768   struct source* sour = gom_get_first_source();
769   for (sour; sour; sour = sour->next) {
770     output(1, "=== SOURCE (%s) ===\n", sour->xrefstr);
771     output(0, "Data: \n");
772     output(0, "  events: ");
773     dump_source_events(0, 4, sour->data.event);
774     output(0, "  Agency: %s\n", sour->data.agency);
775     output(0, "  notes: ");
776     dump_note_sub(0, 4, sour->data.note);
777     output(0, "Author: %s\n", sour->author);
778     output(0, "Title: %s\n", sour->title);
779     output(0, "Abbreviation: %s\n", sour->abbreviation);
780     output(0, "Publication: %s\n", sour->publication);
781     output(0, "Text: %s\n", sour->text);
782     output(0, "Repository:\n");
783     output(0, "  Link: ");
784     dump_xref(0, 4, sour->repository.link);
785     output(0, "  notes: ");
786     dump_note_sub(0, 4, sour->repository.note);
787     output(0, "  source descriptions: ");
788     dump_source_descriptions(0, 4, sour->repository.description);
789     output(0, "multimedia links: ");
790     dump_mm_links(0, 2, sour->mm_link);
791     output(0, "notes: ");
792     dump_note_sub(0, 2, sour->note);
793     output(0, "user refs: ");
794     dump_user_ref(0, 2, sour->ref);
795     output(0, "Record ID: %s\n", sour->record_id);
796     output(0, "change date: ");
797     dump_change_date(0, 2, sour->change_date);
798     output(0, "User data:");
799     dump_user_data(0, 2, sour->extra);
800   }  
801 }
802
803 void dump_submitters()
804 {
805   struct submitter* subm = gom_get_first_submitter();
806   for (subm; subm; subm = subm->next) {
807     output(1, "=== SUBMITTER (%s) ===\n", subm->xrefstr);
808     output(0, "Name: %s\n", subm->name);
809     output(0, "Address: ");
810     dump_address(0, 2, subm->address);
811     output(0, "Phone 1: %s\n", subm->phone[0]);
812     output(0, "Phone 2: %s\n", subm->phone[1]);
813     output(0, "Phone 3: %s\n", subm->phone[2]);
814     output(0, "multimedia links: ");
815     dump_mm_links(0, 2, subm->mm_link);
816     output(0, "Language 1: %s\n", subm->language[0]);
817     output(0, "Language 2: %s\n", subm->language[1]);
818     output(0, "Language 3: %s\n", subm->language[2]);
819     output(0, "Record file nr: %s\n", subm->record_file_nr);
820     output(0, "Record ID: %s\n", subm->record_id);
821     output(0, "change date: ");
822     dump_change_date(0, 2, subm->change_date);
823     output(0, "User data:");
824     dump_user_data(0, 2, subm->extra);
825   }  
826 }
827
828 void dump_user_records()
829 {
830   struct user_rec* rec = gom_get_first_user_rec();
831   for (rec; rec; rec = rec->next) {
832     output(1, "=== USER RECORD (%s) ===\n", rec->xrefstr);
833     output(0, "Tag: %s\n", rec->tag);
834     output(0, "String value: %s\n", rec->str_value);
835     output(0, "Xref value: ");
836     dump_xref(0, 2, rec->xref_value);
837     output(0, "User data:");
838     dump_user_data(0, 2, rec->extra);
839   }  
840 }
841
842 void show_data()
843 {
844   dump_header();
845   dump_submission();
846   dump_families();
847   dump_individuals();
848   dump_multimedia();
849   dump_notes();
850   dump_repositories();
851   dump_sources();
852   dump_submitters();
853   dump_user_records();
854 }
855
856 int main(int argc, char* argv[])
857 {
858   Gedcom_err_mech mech = IMMED_FAIL;
859   int compat_enabled = 1;
860   int debug_level = 0;
861   int result      = 0;
862   char* file_name = NULL;
863
864   if (argc > 1) {
865     int i;
866     for (i=1; i<argc; i++) {
867       if (!strncmp(argv[i], "-da", 4))
868         debug_level = 2;
869       else if (!strncmp(argv[i], "-dg", 4))
870         debug_level = 1;
871       else if (!strncmp(argv[i], "-fi", 4))
872         mech = IMMED_FAIL;
873       else if (!strncmp(argv[i], "-fd", 4))
874         mech = DEFER_FAIL;
875       else if (!strncmp(argv[i], "-fn", 4))
876         mech = IGNORE_ERRORS;
877       else if (!strncmp(argv[i], "-nc", 4))
878         compat_enabled = 0;
879       else if (!strncmp(argv[i], "-h", 3)) {
880         show_help();
881         exit(1);
882       }
883       else if (!strncmp(argv[i], "-q", 3)) {
884         quiet = 1;
885       }
886       else if (strncmp(argv[i], "-", 1)) {
887         file_name = argv[i];
888         break;
889       }
890       else {
891         printf ("Unrecognized option: %s\n", argv[i]);
892         show_help();
893         exit(1);
894       }
895     }
896   }
897   
898   if (!file_name) {
899     printf("No file name given\n");
900     show_help();
901     exit(1);
902   }
903
904   gedcom_init();
905   setlocale(LC_ALL, "");
906   gedcom_set_debug_level(debug_level, NULL);
907   gedcom_set_compat_handling(compat_enabled);
908   gedcom_set_error_handling(mech);
909   gedcom_set_message_handler(gedcom_message_handler);
910
911   outfile = fopen(OUTFILE, "a");
912   if (!outfile) {
913     printf("Could not open %s for appending\n", OUTFILE);
914   }
915   output(0, "\n=== Parsing file %s\n", file_name);
916   result = gom_parse_file(file_name);
917   if (result == 0) {
918     output(1, "Parse succeeded\n");
919   }
920   else {
921     output(1, "Parse failed\n");
922   }
923   show_data();
924   fclose(outfile);
925   return result;
926 }