Portability fix: printf of null string sometimes core dumps.
[gedcom-parse.git] / t / src / dump_gom.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 "dump_gom.h"
25 #include "output.h"
26 #include "gom.h"
27 #include "gedcom.h"
28
29 char* null_str = "(null)";
30
31 char* chk(char* input)
32 {
33   if (input)
34     return input;
35   else
36     return null_str;
37 }
38
39 char* make_prefix(int depth)
40 {
41   char* prefix = (char*)calloc(depth+1, sizeof(char));
42   memset(prefix, ' ', depth);
43   return prefix;
44 }
45
46 void dump_xref(int st, int prefix_depth, struct xref_value* xr);
47
48 void dump_user_data(int st, int prefix_depth, struct user_data* data)
49 {
50   char* prefix = make_prefix(prefix_depth);
51   if (data) {
52     output(st, "\n");
53     for (data; data; data = data->next) {
54       output(st, "%sData: \n", prefix);
55       output(st, "%s  %d, %s, %s\n", prefix,
56              data->level, chk(data->tag), chk(data->str_value));
57       output(st, "%s  reference: ", prefix);
58       dump_xref(st, prefix_depth + 4, data->xref_value);
59     }
60   }
61   else {
62     output(st, "%p\n", data);
63   }
64   free(prefix);
65 }
66
67 void dump_address(int st, int prefix_depth, struct address* addr)
68 {
69   char* prefix = make_prefix(prefix_depth);
70   if (addr) {
71     output(st, "\n");
72     output(st, "%sFull label: %s\n", prefix, chk(addr->full_label));
73     output(st, "%sLine 1: %s\n", prefix, chk(addr->line1));
74     output(st, "%sLine 2: %s\n", prefix, chk(addr->line2));
75     output(st, "%sCity: %s\n", prefix, chk(addr->city));
76     output(st, "%sState: %s\n", prefix, chk(addr->state));
77     output(st, "%sPostal: %s\n", prefix, chk(addr->postal));
78     output(st, "%sCountry: %s\n", prefix, chk(addr->country));
79     output(st, "%sUser data:", prefix);
80     dump_user_data(st, prefix_depth + 2, addr->extra);
81   }
82   else {
83     output(st, "%p\n", addr);
84   }
85   free(prefix);
86 }
87
88 void dump_date(int st, int prefix_depth, struct date_value* dv)
89 {
90   char* prefix = make_prefix(prefix_depth);
91   if (dv) {
92     output(st, "\n");
93     output(st, "%stype: %d\n", prefix, dv->type);
94     output(st, "%sdate1:\n", prefix);
95     output(st, "%s  calendar type: %d\n", prefix, dv->date1.cal);
96     output(st, "%s  day: %s\n", prefix, chk(dv->date1.day_str));
97     output(st, "%s  month: %s\n", prefix, chk(dv->date1.month_str));
98     output(st, "%s  year: %s\n", prefix, chk(dv->date1.year_str));
99     output(st, "%s  date type: %d\n", prefix, dv->date1.type);
100     output(st, "%s  sdn1: %ld\n", prefix, dv->date1.sdn1);
101     output(st, "%s  sdn2: %ld\n", prefix, dv->date1.sdn2);
102     output(st, "%sdate2:\n", prefix);
103     output(st, "%s  calendar type: %d\n", prefix, dv->date2.cal);
104     output(st, "%s  day: %s\n", prefix, chk(dv->date2.day_str));
105     output(st, "%s  month: %s\n", prefix, chk(dv->date2.month_str));
106     output(st, "%s  year: %s\n", prefix, chk(dv->date2.year_str));
107     output(st, "%s  date type: %d\n", prefix, dv->date2.type);
108     output(st, "%s  sdn1: %ld\n", prefix, dv->date2.sdn1);
109     output(st, "%s  sdn2: %ld\n", prefix, dv->date2.sdn2);
110     output(st, "%sphrase: %s\n", prefix, chk(dv->phrase));
111   }
112   else {
113     output(st, "%p\n", dv);
114   }
115   free(prefix);
116 }
117
118 void dump_age(int st, int prefix_depth, struct age_value* age)
119 {
120   char* prefix = make_prefix(prefix_depth);
121   if (age) {
122     output(st, "\n");
123     output(st, "%stype: %d\n", prefix, age->type);
124     output(st, "%smodifier: %d\n", prefix, age->mod);
125     output(st, "%syears: %d\n", prefix, age->years);
126     output(st, "%smonths: %d\n", prefix, age->months);
127     output(st, "%sdays: %d\n", prefix, age->days);
128     output(st, "%sphrase: %s\n", prefix, chk(age->phrase));
129   }
130   else {
131     output(st, "%p\n", age);
132   }
133   free(prefix);
134 }
135
136 void dump_xref(int st, int prefix_depth, struct xref_value* xr)
137 {
138   char* prefix = make_prefix(prefix_depth);
139   if (xr) {
140     output(st, "\n");
141     output(st, "%stype: %d\n", prefix, xr->type);
142     output(st, "%sxref: %s\n", prefix, chk(xr->string));
143     output(st, "%sobject: %p\n", prefix, xr->object);
144   }
145   else {
146     output(st, "%p\n", xr);
147   }
148   free(prefix);
149 }
150
151 void dump_xref_list(int st, int prefix_depth, struct xref_list* xr)
152 {
153   char* prefix = make_prefix(prefix_depth);
154   if (xr) {
155     output(st, "\n");
156     for (xr; xr; xr = xr->next) {
157       output(st, "%sreference: ", prefix);
158       dump_xref(st, prefix_depth + 2, xr->xref);
159       output(st, "%sUser data:", prefix);
160       dump_user_data(st, prefix_depth + 2, xr->extra);
161     }
162   }
163   else {
164     output(st, "%p\n", xr);
165   }
166   free(prefix);
167 }
168
169 void dump_texts(int st, int prefix_depth, struct text* t)
170 {
171   char* prefix = make_prefix(prefix_depth);
172   if (t) {
173     output(st, "\n");
174     for (t; t; t = t->next) {
175       output(st, "%sText: %s\n", prefix, chk(t->text));
176       output(st, "%sUser data:", prefix);
177       dump_user_data(st, prefix_depth + 2, t->extra);
178     }
179   }
180   else {
181     output(st, "%p\n", t);
182   }
183   free(prefix);
184 }
185
186 void dump_user_ref(int st, int prefix_depth, struct user_ref_number* ref)
187 {
188   char* prefix = make_prefix(prefix_depth);
189   if (ref) {
190     output(st, "\n");
191     for (ref; ref; ref = ref->next) {
192       output(st, "%sValue: %s\n", prefix, chk(ref->value));
193       output(st, "%sType: %s\n", prefix, chk(ref->type));
194       output(st, "%sUser data:", prefix);
195       dump_user_data(st, prefix_depth + 2, ref->extra);
196     }
197   }
198   else {
199     output(st, "%p\n", ref);
200   }
201   free(prefix);
202 }
203
204 void dump_citations(int st, int prefix_depth, struct source_citation* cit);
205
206 void dump_note_sub(int st, int prefix_depth, struct note_sub* note)
207 {
208   char* prefix = make_prefix(prefix_depth);
209   if (note) {
210     output(st, "\n");
211     for (note; note; note = note->next) {
212       output(st, "%sNote: \n", prefix);
213       output(st, "%s  text: %s\n", prefix, chk(note->text));
214       output(st, "%s  reference: ", prefix);
215       dump_xref(st, prefix_depth + 4, note->reference);
216       output(st, "%s  citations: ", prefix);
217       dump_citations(st, prefix_depth + 4, note->citation);
218       output(st, "%s  User data:", prefix);
219       dump_user_data(st, prefix_depth + 4, note->extra);
220     }
221   }
222   else {
223     output(st, "%p\n", note);
224   }
225   free(prefix);
226 }
227
228 void dump_mm_links(int st, int prefix_depth, struct multimedia_link* link)
229 {
230   char* prefix = make_prefix(prefix_depth);
231   if (link) {
232     output(st, "\n");
233     for (link; link; link = link->next) {
234       output(st, "%slink: \n", prefix);
235       output(st, "%s  reference: ", prefix);
236       dump_xref(st, prefix_depth + 4, link->reference);
237       output(st, "%s  Form: %s\n", prefix, chk(link->form));
238       output(st, "%s  Title: %s\n", prefix, chk(link->title));
239       output(st, "%s  File: %s\n", prefix, chk(link->file));      
240       output(st, "%s  notes: ", prefix);
241       dump_note_sub(st, prefix_depth + 4, link->note);
242       output(st, "%s  User data:", prefix);
243       dump_user_data(st, prefix_depth + 4, link->extra);
244     }
245   }
246   else {
247     output(st, "%p\n", link);
248   }
249   free(prefix);
250 }
251
252 void dump_citations(int st, int prefix_depth, struct source_citation* cit)
253 {
254   char* prefix = make_prefix(prefix_depth);
255   if (cit) {
256     output(st, "\n");
257     for (cit; cit; cit = cit->next) {
258       output(st, "%sCitation: \n", prefix);
259       output(st, "%s  description: %s\n", prefix, chk(cit->description));
260       output(st, "%s  reference: ", prefix);
261       dump_xref(st, prefix_depth + 4, cit->reference);
262       output(st, "%s  page: %s\n", prefix, chk(cit->page));
263       output(st, "%s  event: %s\n", prefix, chk(cit->event));
264       output(st, "%s  role: %s\n", prefix, chk(cit->role));
265       output(st, "%s  Date: ", prefix);
266       dump_date(st, prefix_depth + 4, cit->date);
267       output(st, "%s  texts: ", prefix, prefix);
268       dump_texts(st, prefix_depth + 4, cit->text);
269       output(st, "%s  quality: %s\n", prefix, chk(cit->quality));
270       output(st, "%s  multimedia links: ", prefix);
271       dump_mm_links(st, prefix_depth + 4, cit->mm_link);
272       output(st, "%s  notes: ", prefix);
273       dump_note_sub(st, prefix_depth + 4, cit->note);
274       output(st, "%s  User data:", prefix);
275       dump_user_data(st, prefix_depth + 4, cit->extra);
276     }
277   }
278   else {
279     output(st, "%p\n", cit);
280   }
281   free(prefix);
282 }
283
284 void dump_lds(int st, int prefix_depth, struct lds_event* lds)
285 {
286   char* prefix = make_prefix(prefix_depth);
287   if (lds) {
288     output(st, "\n");
289     for (lds; lds; lds = lds->next) {
290       output(st, "%sDate status: %s\n", prefix, chk(lds->date_status));
291       output(st, "%sDate: ", prefix);
292       dump_date(st, prefix_depth + 2, lds->date);
293       output(st, "%sTemple code: %s\n", prefix, chk(lds->temple_code));
294       output(st, "%sPlace living ordinance: %s\n", prefix,
295              chk(lds->place_living_ordinance));
296       output(st, "%scitations: ", prefix);
297       dump_citations(st, prefix_depth + 2, lds->citation);
298       output(st, "%snotes: ", prefix);
299       dump_note_sub(st, prefix_depth + 2, lds->note);
300       output(st, "%sfamily: ", prefix);
301       dump_xref(st, prefix_depth + 2, lds->family);
302       output(st, "%sUser data:", prefix);
303       dump_user_data(st, prefix_depth + 2, lds->extra);
304     }
305   }
306   else {
307     output(st, "%p\n", lds);
308   }
309   free(prefix);
310 }
311
312 void dump_change_date(int st, int prefix_depth, struct change_date* chan)
313 {
314   char* prefix = make_prefix(prefix_depth);
315   if (chan) {
316     output(st, "\n");
317     output(st, "%sDate: ", prefix);
318     dump_date(st, prefix_depth + 2, chan->date);
319     output(st, "%sTime: %s\n", prefix, chk(chan->time));
320     output(st, "%snotes: ", prefix);
321     dump_note_sub(st, prefix_depth + 2, chan->note);
322     output(st, "%sUser data:", prefix);
323     dump_user_data(st, prefix_depth + 2, chan->extra);
324   }
325   else {
326     output(st, "%p\n", chan);
327   }
328   free(prefix);
329 }
330
331 void dump_personal_name(int st, int prefix_depth, struct personal_name* name)
332 {
333   char* prefix = make_prefix(prefix_depth);
334   if (name) {
335     output(st, "\n");
336     for (name; name; name = name->next) {
337       output(st, "%sName: \n", prefix);
338       output(st, "%s  Name: %s\n", prefix, chk(name->name));
339       output(st, "%s  Prefix: %s\n", prefix, chk(name->prefix));
340       output(st, "%s  Given: %s\n", prefix, chk(name->given));
341       output(st, "%s  Nickname: %s\n", prefix, chk(name->nickname));
342       output(st, "%s  Surname prefix: %s\n", prefix,chk(name->surname_prefix));
343       output(st, "%s  Surname: %s\n", prefix, chk(name->surname));
344       output(st, "%s  Suffix: %s\n", prefix, chk(name->suffix));
345       output(st, "%s  citations: ", prefix);
346       dump_citations(st, prefix_depth + 4, name->citation);
347       output(st, "%s  notes: ", prefix);
348       dump_note_sub(st, prefix_depth + 4, name->note);
349       output(st, "%s  User data:", prefix);
350       dump_user_data(st, prefix_depth + 4, name->extra);
351     }
352   }
353   else {
354     output(st, "%p\n", name);
355   }
356   free(prefix);
357 }
358
359 void dump_pedigree(int st, int prefix_depth, struct pedigree* p)
360 {
361   char* prefix = make_prefix(prefix_depth);
362   if (p) {
363     output(st, "\n");
364     for (p; p; p = p->next) {
365       output(st, "%sPedigree: %s\n", prefix, chk(p->pedigree));
366       output(st, "%sUser data:", prefix);
367       dump_user_data(st, prefix_depth + 2, p->extra);
368     }
369   }
370   else {
371     output(st, "%p\n", p);
372   }
373   free(prefix);
374 }
375
376 void dump_family_link(int st, int prefix_depth, struct family_link *link)
377 {
378   char* prefix = make_prefix(prefix_depth);
379   if (link) {
380     output(st, "\n");
381     for (link; link; link = link->next) {
382       output(st, "%sFamily:\n", prefix);
383       output(st, "%s  Family: ", prefix);
384       dump_xref(st, prefix_depth + 4, link->family);
385       output(st, "%s  pedigrees: ", prefix);
386       dump_pedigree(st, prefix_depth + 4, link->pedigree);
387       output(st, "%s  notes: ", prefix);
388       dump_note_sub(st, prefix_depth + 4, link->note);
389       output(st, "%s  User data:", prefix);
390       dump_user_data(st, prefix_depth + 4, link->extra);
391     }
392   }
393   else {
394     output(st, "%p\n", link);
395   }
396   free(prefix);
397 }
398
399 void dump_association(int st, int prefix_depth, struct association *assoc)
400 {
401   char* prefix = make_prefix(prefix_depth);
402   if (assoc) {
403     output(st, "\n");
404     for (assoc; assoc; assoc = assoc->next) {
405       output(st, "%sAssociation:\n", prefix);
406       output(st, "%s  To:\n", prefix);
407       dump_xref(st, prefix_depth + 4, assoc->to);
408       output(st, "%s  Type: %s\n", prefix, chk(assoc->type));
409       output(st, "%s  Relation: %s\n", chk(assoc->relation));
410       output(st, "%s  citations: ", prefix);
411       dump_citations(st, prefix_depth + 4, assoc->citation);
412       output(st, "%s  notes: ", prefix);
413       dump_note_sub(st, prefix_depth + 4, assoc->note);
414       output(st, "%s  User data:", prefix);
415       dump_user_data(st, prefix_depth + 4, assoc->extra);
416     }
417   }
418   else {
419     output(st, "%p\n", assoc);
420   }
421   free(prefix);
422 }
423
424 void dump_place(int st, int prefix_depth, struct place* place)
425 {
426   char* prefix = make_prefix(prefix_depth);
427   if (place) {
428     output(st, "\n");
429     output(st, "%svalue: %s\n", prefix, chk(place->value));
430     output(st, "%splace_hierarchy: %s\n", prefix, chk(place->place_hierarchy));
431     output(st, "%scitations: ", prefix);
432     dump_citations(st, prefix_depth + 2, place->citation);
433     output(st, "%snotes: ", prefix);
434     dump_note_sub(st, prefix_depth + 2, place->note);
435     output(st, "%sUser data:", prefix);
436     dump_user_data(st, prefix_depth + 2, place->extra);
437   }
438   else {
439     output(st, "%p\n", place);
440   }
441   free(prefix);
442 }
443
444 void dump_source_events(int st, int prefix_depth, struct source_event* evt)
445 {
446   char* prefix = make_prefix(prefix_depth);
447   if (evt) {
448     output(st, "\n");
449     for (evt; evt; evt = evt->next) {
450       output(st, "%sEvent:\n", prefix);
451       output(st, "%s  Recorded events: %s\n", prefix,
452              chk(evt->recorded_events));
453       output(st, "%s  Date period: ", prefix);
454       dump_date(st, prefix_depth + 4, evt->date_period);
455       output(st, "%s  Jurisdiction: %s\n", prefix, chk(evt->jurisdiction));
456       output(st, "%s  User data:", prefix);
457       dump_user_data(st, prefix_depth + 4, evt->extra);
458     }
459   }
460   else {
461     output(st, "%p\n", evt);
462   }
463   free(prefix);
464 }
465
466 void dump_source_descriptions(int st, int prefix_depth,
467                               struct source_description* desc)
468 {
469   char* prefix = make_prefix(prefix_depth);
470   if (desc) {
471     output(st, "\n");
472     for (desc; desc; desc = desc->next) {
473       output(st, "%sSource description:\n", prefix);
474       output(st, "%s  Call number: %s\n", prefix, chk(desc->call_number));
475       output(st, "%s  Media: %s\n", prefix, chk(desc->media));
476       output(st, "%s  User data:", prefix);
477       dump_user_data(st, prefix_depth + 4, desc->extra);
478     }
479   }
480   else {
481     output(st, "%p\n", desc);
482   }
483   free(prefix);
484 }
485
486 void dump_events(int st, int prefix_depth, struct event *evt)
487 {
488   char* prefix = make_prefix(prefix_depth);
489   if (evt) {
490     output(st, "\n");
491     for (evt; evt; evt = evt->next) {
492       output(st, "%sEvent: %d (%s)\n", prefix, evt->event,
493              chk(evt->event_name));
494       output(st, "%s  Value: %s\n", prefix, chk(evt->val));
495       output(st, "%s  Type: %s\n", prefix, chk(evt->type));
496       output(st, "%s  Date: ", prefix);
497       dump_date(st, prefix_depth + 4, evt->date);
498       output(st, "%s  Place: ", prefix);
499       dump_place(st, prefix_depth + 4, evt->place);
500       output(st, "%s  Address: ", prefix);
501       dump_address(st, prefix_depth + 4, evt->address);
502       output(st, "%s  Phone 1: %s\n", prefix, chk(evt->phone[0]));
503       output(st, "%s  Phone 2: %s\n", prefix, chk(evt->phone[1]));
504       output(st, "%s  Phone 3: %s\n", prefix, chk(evt->phone[2]));
505       output(st, "%s  Age: ", prefix);
506       dump_age(st, prefix_depth + 4, evt->age);
507       output(st, "%s  Agency: %s\n", prefix, chk(evt->agency));
508       output(st, "%s  Cause: %s\n", prefix, chk(evt->cause));
509       output(st, "%s  citations: ", prefix);
510       dump_citations(st, prefix_depth + 4, evt->citation);
511       output(st, "%s  multimedia links: ", prefix);
512       dump_mm_links(st, prefix_depth + 4, evt->mm_link);
513       output(st, "%s  notes: ", prefix);
514       dump_note_sub(st, prefix_depth + 4, evt->note);
515       output(st, "%s  Age of husband: ", prefix);
516       dump_age(st, prefix_depth + 4, evt->husband_age);
517       output(st, "%s  Age of wife: ", prefix);
518       dump_age(st, prefix_depth + 4, evt->wife_age);
519       output(st, "%s  Family: ", prefix);
520       dump_xref(st, prefix_depth + 4, evt->family);
521       output(st, "%s  Adoption parent: %s\n", prefix,
522              chk(evt->adoption_parent));
523       output(st, "%s  User data:", prefix);
524       dump_user_data(st, prefix_depth + 4, evt->extra);
525     }
526   }
527   else {
528     output(st, "%p\n", evt);
529   }
530   free(prefix);
531 }
532
533 void dump_header()
534 {
535   struct header* header = gom_get_header();
536   output(1, "=== HEADER ===\n");
537   output(0, "Source:\n");
538   output(0, "  ID: %s\n", chk(header->source.id));
539   output(0, "  Name: %s\n", chk(header->source.name));
540   output(0, "  Version: %s\n", chk(header->source.version));
541   output(0, "  Corporation:\n");
542   output(0, "    Name: %s\n", chk(header->source.corporation.name));
543   output(0, "    Address: ");
544   dump_address(0, 6, header->source.corporation.address);
545   output(0, "    Phone 1: %s\n", chk(header->source.corporation.phone[0]));
546   output(0, "    Phone 2: %s\n", chk(header->source.corporation.phone[1]));
547   output(0, "    Phone 3: %s\n", chk(header->source.corporation.phone[2]));
548   output(0, "  Data:\n");
549   output(0, "    Name: %s\n", chk(header->source.data.name));
550   output(0, "    Date: ");
551   dump_date(0, 6, header->source.data.date);
552   output(0, "    Copyright: %s\n", chk(header->source.data.copyright));
553   output(0, "Destination: %s\n", chk(header->destination));
554   output(0, "Date: ");
555   dump_date(0, 2, header->date);
556   output(0, "Time: %s\n", chk(header->time));
557   output(0, "Submitter: ");
558   dump_xref(0, 2, header->submitter);
559   output(0, "Submission: ");
560   dump_xref(0, 2, header->submission);
561   output(0, "File name: %s\n", chk(header->filename));
562   output(0, "Copyright: %s\n", chk(header->copyright));
563   output(0, "Gedcom:\n");
564   output(0, "  Version: %s\n", chk(header->gedcom.version));
565   output(0, "  Form: %s\n", chk(header->gedcom.form));
566   output(0, "Character set:\n");
567   output(0, "  Name: %s\n", chk(header->charset.name));
568   output(0, "  Version: %s\n", chk(header->charset.version));
569   output(0, "Language: %s\n", chk(header->language));
570   output(0, "Place hierarchy: %s\n", chk(header->place_hierarchy));
571   output(0, "Note:\n");
572   output(0, "====\n");
573   output(0, "%s\n", chk(header->note));
574   output(0, "====\n");
575   output(0, "User data:");
576   dump_user_data(0, 2, header->extra);
577 }
578
579 void dump_submission()
580 {
581   struct submission* subn = gom_get_submission();
582   if (subn) {
583     output(1, "=== SUBMISSION (%s) ===\n", chk(subn->xrefstr));
584     output(0, "Submitter: ");
585     dump_xref(0, 2, subn->submitter);
586     output(0, "Family file: %s\n", chk(subn->family_file));
587     output(0, "Temple code: %s\n", chk(subn->temple_code));
588     output(0, "Nr of ancestor generations: %s\n",
589            chk(subn->nr_of_ancestor_gens));
590     output(0, "Nr of descendant generations: %s\n",
591            chk(subn->nr_of_descendant_gens));
592     output(0, "Ordinance process flag: %s\n",
593            chk(subn->ordinance_process_flag));
594     output(0, "Record id: %s\n", chk(subn->record_id));
595     output(0, "User data:");
596     dump_user_data(0, 2, subn->extra);
597   }
598 }
599
600 void dump_families()
601 {
602   struct family* fam = gom_get_first_family();
603   for (fam; fam; fam = fam->next) {
604     output(1, "=== FAMILY (%s) ===\n", chk(fam->xrefstr));
605     output(0, "Family events: ");
606     dump_events(0, 2, fam->event);
607     output(0, "Husband: ");
608     dump_xref(0, 2, fam->husband);
609     output(0, "Wife: ");
610     dump_xref(0, 2, fam->wife);
611     output(0, "Children: ");
612     dump_xref_list(0, 2, fam->children);
613     output(0, "Number of children: %s\n", chk(fam->nr_of_children));
614     output(0, "Submitters: ");
615     dump_xref_list(0, 2, fam->submitters);
616     output(0, "LDS spouse sealings: ");
617     dump_lds(0, 2, fam->lds_spouse_sealing);
618     output(0, "citations: ");
619     dump_citations(0, 2, fam->citation);
620     output(0, "multimedia links: ");
621     dump_mm_links(0, 2, fam->mm_link);
622     output(0, "notes: ");
623     dump_note_sub(0, 2, fam->note);
624     output(0, "user refs: ");
625     dump_user_ref(0, 2, fam->ref);
626     output(0, "Record ID: %s\n", chk(fam->record_id));
627     output(0, "change date: ");
628     dump_change_date(0, 2, fam->change_date);
629     output(0, "User data:");
630     dump_user_data(0, 2, fam->extra);
631   }
632 }
633
634 void dump_individuals()
635 {
636   struct individual* indiv = gom_get_first_individual();
637   for (indiv; indiv; indiv = indiv->next) {
638     output(1, "=== INDIVIDUAL (%s) ===\n", chk(indiv->xrefstr));
639     output(0, "Restriction notice: %s\n", chk(indiv->restriction_notice));
640     output(0, "names: ");
641     dump_personal_name(0, 2, indiv->name);
642     output(0, "Sex: %s\n", chk(indiv->sex));
643     output(0, "Individual events: ");
644     dump_events(0, 2, indiv->event);
645     output(0, "Individual attributes: ");
646     dump_events(0, 2, indiv->attribute);
647     output(0, "LDS individual ordinance: ");
648     dump_lds(0, 2, indiv->lds_individual_ordinance);
649     output(0, "Child to family links: ");
650     dump_family_link(0, 2, indiv->child_to_family);
651     output(0, "Spouse to family links: ");
652     dump_family_link(0, 2, indiv->spouse_to_family);
653     output(0, "Submitters: ");
654     dump_xref_list(0, 2, indiv->submitters);
655     output(0, "Associations: ");
656     dump_association(0, 2, indiv->association);
657     output(0, "Aliases: ");
658     dump_xref_list(0, 2, indiv->alias);
659     output(0, "Ancestor interest: ");
660     dump_xref_list(0, 2, indiv->ancestor_interest);
661     output(0, "Descendant interest: ");
662     dump_xref_list(0, 2, indiv->descendant_interest);
663     output(0, "citations: ");
664     dump_citations(0, 2, indiv->citation);
665     output(0, "multimedia links: ");
666     dump_mm_links(0, 2, indiv->mm_link);
667     output(0, "notes: ");
668     dump_note_sub(0, 2, indiv->note);
669     output(0, "Record file nr: %s\n", chk(indiv->record_file_nr));
670     output(0, "Ancestral file nr: %s\n", chk(indiv->ancestral_file_nr));
671     output(0, "user refs: ");
672     dump_user_ref(0, 2, indiv->ref);
673     output(0, "Record ID: %s\n", chk(indiv->record_id));
674     output(0, "change date: ");
675     dump_change_date(0, 2, indiv->change_date);
676     output(0, "User data:");
677     dump_user_data(0, 2, indiv->extra);
678   }
679 }
680
681 void dump_multimedia()
682 {
683   struct multimedia* obj = gom_get_first_multimedia();
684   for (obj; obj; obj = obj->next) {
685     output(1, "=== MULTIMEDIA (%s) ===\n", chk(obj->xrefstr));
686     output(0, "Form: %s\n", chk(obj->form));
687     output(0, "Title: %s\n", chk(obj->title));
688     output(0, "notes: ");
689     dump_note_sub(0, 2, obj->note);
690     output(0, "Data: %s\n", chk(obj->data));
691     output(0, "Continued: ");
692     dump_xref(0, 2, obj->continued);
693     output(0, "user refs: ");
694     dump_user_ref(0, 2, obj->ref);
695     output(0, "Record ID: %s\n", chk(obj->record_id));
696     output(0, "change date: ");
697     dump_change_date(0, 2, obj->change_date);
698     output(0, "User data:");
699     dump_user_data(0, 2, obj->extra);
700   }  
701 }
702
703 void dump_notes()
704 {
705   struct note* note = gom_get_first_note();
706   for (note; note; note = note->next) {
707     output(1, "=== NOTE (%s) ===\n", chk(note->xrefstr));
708     output(0, "Text: %s\n", chk(note->text));
709     output(0, "citations: ");
710     dump_citations(0, 2, note->citation);
711     output(0, "user refs: ");
712     dump_user_ref(0, 2, note->ref);
713     output(0, "Record ID: %s\n", chk(note->record_id));
714     output(0, "change date: ");
715     dump_change_date(0, 2, note->change_date);
716     output(0, "User data:");
717     dump_user_data(0, 2, note->extra);
718   }  
719 }
720
721 void dump_repositories()
722 {
723   struct repository* repo = gom_get_first_repository();
724   for (repo; repo; repo = repo->next) {
725     output(1, "=== REPOSITORY (%s) ===\n", chk(repo->xrefstr));
726     output(0, "Name: %s\n", chk(repo->name));
727     output(0, "Address: ");
728     dump_address(0, 2, repo->address);
729     output(0, "Phone 1: %s\n", chk(repo->phone[0]));
730     output(0, "Phone 2: %s\n", chk(repo->phone[1]));
731     output(0, "Phone 3: %s\n", chk(repo->phone[2]));
732     output(0, "notes: ");
733     dump_note_sub(0, 2, repo->note);
734     output(0, "user refs: ");
735     dump_user_ref(0, 2, repo->ref);
736     output(0, "Record ID: %s\n", chk(repo->record_id));
737     output(0, "change date: ");
738     dump_change_date(0, 2, repo->change_date);
739     output(0, "User data:");
740     dump_user_data(0, 2, repo->extra);
741   }  
742 }
743
744 void dump_sources()
745 {
746   struct source* sour = gom_get_first_source();
747   for (sour; sour; sour = sour->next) {
748     output(1, "=== SOURCE (%s) ===\n", chk(sour->xrefstr));
749     output(0, "Data: \n");
750     output(0, "  events: ");
751     dump_source_events(0, 4, sour->data.event);
752     output(0, "  Agency: %s\n", chk(sour->data.agency));
753     output(0, "  notes: ");
754     dump_note_sub(0, 4, sour->data.note);
755     output(0, "Author: %s\n", chk(sour->author));
756     output(0, "Title: %s\n", chk(sour->title));
757     output(0, "Abbreviation: %s\n", chk(sour->abbreviation));
758     output(0, "Publication: %s\n", chk(sour->publication));
759     output(0, "Text: %s\n", chk(sour->text));
760     output(0, "Repository:\n");
761     output(0, "  Link: ");
762     dump_xref(0, 4, sour->repository.link);
763     output(0, "  notes: ");
764     dump_note_sub(0, 4, sour->repository.note);
765     output(0, "  source descriptions: ");
766     dump_source_descriptions(0, 4, sour->repository.description);
767     output(0, "multimedia links: ");
768     dump_mm_links(0, 2, sour->mm_link);
769     output(0, "notes: ");
770     dump_note_sub(0, 2, sour->note);
771     output(0, "user refs: ");
772     dump_user_ref(0, 2, sour->ref);
773     output(0, "Record ID: %s\n", chk(sour->record_id));
774     output(0, "change date: ");
775     dump_change_date(0, 2, sour->change_date);
776     output(0, "User data:");
777     dump_user_data(0, 2, sour->extra);
778   }  
779 }
780
781 void dump_submitters()
782 {
783   struct submitter* subm = gom_get_first_submitter();
784   for (subm; subm; subm = subm->next) {
785     output(1, "=== SUBMITTER (%s) ===\n", chk(subm->xrefstr));
786     output(0, "Name: %s\n", chk(subm->name));
787     output(0, "Address: ");
788     dump_address(0, 2, subm->address);
789     output(0, "Phone 1: %s\n", chk(subm->phone[0]));
790     output(0, "Phone 2: %s\n", chk(subm->phone[1]));
791     output(0, "Phone 3: %s\n", chk(subm->phone[2]));
792     output(0, "multimedia links: ");
793     dump_mm_links(0, 2, subm->mm_link);
794     output(0, "Language 1: %s\n", chk(subm->language[0]));
795     output(0, "Language 2: %s\n", chk(subm->language[1]));
796     output(0, "Language 3: %s\n", chk(subm->language[2]));
797     output(0, "Record file nr: %s\n", chk(subm->record_file_nr));
798     output(0, "Record ID: %s\n", chk(subm->record_id));
799     output(0, "change date: ");
800     dump_change_date(0, 2, subm->change_date);
801     output(0, "User data:");
802     dump_user_data(0, 2, subm->extra);
803   }  
804 }
805
806 void dump_user_records()
807 {
808   struct user_rec* rec = gom_get_first_user_rec();
809   for (rec; rec; rec = rec->next) {
810     output(1, "=== USER RECORD (%s) ===\n", chk(rec->xrefstr));
811     output(0, "Tag: %s\n", rec->tag);
812     output(0, "String value: %s\n", chk(rec->str_value));
813     output(0, "Xref value: ");
814     dump_xref(0, 2, rec->xref_value);
815     output(0, "User data:");
816     dump_user_data(0, 2, rec->extra);
817   }  
818 }
819
820 void show_data()
821 {
822   dump_header();
823   dump_submission();
824   dump_families();
825   dump_individuals();
826   dump_multimedia();
827   dump_notes();
828   dump_repositories();
829   dump_sources();
830   dump_submitters();
831   dump_user_records();
832 }