Unlink xrefs properly when struct is deleted.
[gedcom-parse.git] / gom / family.c
1 /* Family object in the gedcom object model.
2    Copyright (C) 2002 The Genes Development Team
3    This file is part of the Gedcom parser library.
4    Contributed by Peter Verthez <Peter.Verthez@advalvas.be>, 2002.
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 <stdlib.h>
25 #include <string.h>
26 #include "family.h"
27 #include "individual.h"
28 #include "submitter.h"
29 #include "event.h"
30 #include "lds_event.h"
31 #include "source_citation.h"
32 #include "multimedia_link.h"
33 #include "note_sub.h"
34 #include "user_ref.h"
35 #include "change_date.h"
36 #include "user_rec.h"
37 #include "gom.h"
38 #include "gedcom.h"
39 #include "gom_internal.h"
40
41 struct family* gom_first_family = NULL;
42
43 DEFINE_MAKEFUNC(family, gom_first_family)
44 DEFINE_DESTROYFUNC(family, gom_first_family)
45 DEFINE_ADDFUNC(family, XREF_FAM)
46 DEFINE_DELETEFUNC(family)
47 DEFINE_GETXREFFUNC(family, XREF_FAM)
48      
49 DEFINE_REC_CB(family, fam_start)
50 DEFINE_XREF_CB(family, fam_husb_start, husband, individual)
51 DEFINE_XREF_CB(family, fam_wife_start, wife, individual)
52 DEFINE_STRING_CB(family, fam_nchi_start, nr_of_children)
53 DEFINE_XREF_LIST_CB(family, fam_chil_start, children, individual)
54 DEFINE_XREF_LIST_CB(family, fam_subm_start, submitters, submitter)
55
56 DEFINE_ADDFUNC2(family, event, event)
57 DEFINE_ADDFUNC2(family, lds_event, lds_spouse_sealing)
58 DEFINE_ADDFUNC2(family, source_citation, citation)
59 DEFINE_ADDFUNC2(family, multimedia_link, mm_link)
60 DEFINE_ADDFUNC2(family, note_sub, note)
61 DEFINE_ADDFUNC2(family, user_ref_number, ref)
62 DEFINE_ADDFUNC2(family, user_data, extra)
63 DEFINE_ADDFUNC2_NOLIST(family, change_date, change_date)
64 DEFINE_ADDFUNC2_STR(family, record_id)
65
66 void family_subscribe()
67 {
68   gedcom_subscribe_to_record(REC_FAM, fam_start, def_rec_end);
69   gedcom_subscribe_to_element(ELT_FAM_HUSB, fam_husb_start, def_elt_end);
70   gedcom_subscribe_to_element(ELT_FAM_WIFE, fam_wife_start, def_elt_end);
71   gedcom_subscribe_to_element(ELT_FAM_CHIL, fam_chil_start, def_elt_end);
72   gedcom_subscribe_to_element(ELT_FAM_NCHI, fam_nchi_start, def_elt_end);
73   gedcom_subscribe_to_element(ELT_FAM_SUBM, fam_subm_start, def_elt_end);
74 }
75
76 void UNREFALLFUNC(family)(struct family *fam)
77 {
78   if (fam) {
79     UNREFALLFUNC(event)(fam->event);
80     unref_xref_value(fam->husband);
81     unref_xref_value(fam->wife);
82     UNREFALLFUNC(xref_list)(fam->children);
83     UNREFALLFUNC(xref_list)(fam->submitters);
84     UNREFALLFUNC(lds_event)(fam->lds_spouse_sealing);
85     UNREFALLFUNC(source_citation)(fam->citation);
86     UNREFALLFUNC(multimedia_link)(fam->mm_link);
87     UNREFALLFUNC(note_sub)(fam->note);
88     UNREFALLFUNC(user_ref_number)(fam->ref);
89     UNREFALLFUNC(change_date)(fam->change_date);
90     UNREFALLFUNC(user_data)(fam->extra);
91   }
92 }
93
94 void CLEANFUNC(family)(struct family* fam)
95 {
96   if (fam) {
97     SAFE_FREE(fam->xrefstr);
98     DESTROY_CHAIN_ELTS(event, fam->event); 
99     DESTROY_CHAIN_ELTS(xref_list, fam->children);
100     SAFE_FREE(fam->nr_of_children);
101     DESTROY_CHAIN_ELTS(xref_list, fam->submitters);
102     DESTROY_CHAIN_ELTS(lds_event, fam->lds_spouse_sealing);
103     DESTROY_CHAIN_ELTS(source_citation, fam->citation);
104     DESTROY_CHAIN_ELTS(multimedia_link, fam->mm_link);
105     DESTROY_CHAIN_ELTS(note_sub, fam->note);
106     DESTROY_CHAIN_ELTS(user_ref_number, fam->ref);
107     SAFE_FREE(fam->record_id);
108     CLEANFUNC(change_date)(fam->change_date);
109     DESTROY_CHAIN_ELTS(user_data, fam->extra);
110   }
111 }
112
113 void families_cleanup()
114 {
115   DESTROY_CHAIN_ELTS(family, gom_first_family);
116 }
117
118 struct family* gom_get_first_family()
119 {
120   return gom_first_family;
121 }
122
123 int write_families(Gedcom_write_hndl hndl)
124 {
125   int result = 0;
126   struct family* obj;
127
128   for (obj = gom_first_family; obj; obj = obj->next) {
129     result |= gedcom_write_record_str(hndl, REC_FAM, obj->xrefstr, NULL);
130     if (obj->event)
131       result |= write_events(hndl, REC_FAM, EVT_TYPE_FAMILY, obj->event);
132     if (obj->husband)
133       result |= gedcom_write_element_xref(hndl, ELT_FAM_HUSB, 0,
134                                           REC_FAM, obj->husband);
135     if (obj->wife)
136       result |= gedcom_write_element_xref(hndl, ELT_FAM_WIFE, 0,
137                                           REC_FAM, obj->wife);
138     result |= gom_write_xref_list(hndl, ELT_FAM_CHIL, 0,
139                                   REC_FAM, obj->children);
140     if (obj->nr_of_children)
141       result |= gedcom_write_element_str(hndl, ELT_FAM_NCHI, 0,
142                                          REC_FAM, obj->nr_of_children);
143     result |= gom_write_xref_list(hndl, ELT_FAM_SUBM, 0,
144                                   REC_FAM, obj->submitters);
145     if (obj->lds_spouse_sealing)
146       result |= write_lds_events(hndl, REC_FAM, obj->lds_spouse_sealing);
147     if (obj->citation)
148       result |= write_citations(hndl, REC_FAM, obj->citation);
149     if (obj->mm_link)
150       result |= write_multimedia_links(hndl, REC_FAM, obj->mm_link);
151     if (obj->note)
152       result |= write_note_subs(hndl, REC_FAM, obj->note);
153     if (obj->ref)
154       result |= write_user_refs(hndl, REC_FAM, obj->ref);
155     if (obj->record_id)
156       result |= gedcom_write_element_str(hndl, ELT_SUB_IDENT_RIN, 0,
157                                          REC_FAM, obj->record_id);
158     if (obj->change_date)
159       result |= write_change_date(hndl, REC_FAM, obj->change_date);
160     if (obj->extra)
161       result |= write_user_data(hndl, obj->extra);
162   }
163   
164   return result;
165 }
166