Only try to delete address if present.
[gedcom-parse.git] / gom / individual.c
1 /* Individual 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 "individual.h"
27 #include "event.h"
28 #include "personal_name.h"
29 #include "lds_event.h"
30 #include "family_link.h"
31 #include "association.h"
32 #include "submitter.h"
33 #include "source_citation.h"
34 #include "multimedia_link.h"
35 #include "note_sub.h"
36 #include "user_ref.h"
37 #include "change_date.h"
38 #include "user_rec.h"
39 #include "gom.h"
40 #include "gedcom.h"
41 #include "gom_internal.h"
42
43 struct individual* gom_first_individual = NULL;
44
45 DEFINE_MAKEFUNC(individual, gom_first_individual)
46 DEFINE_DESTROYFUNC(individual, gom_first_individual)
47 DEFINE_ADDFUNC(individual, XREF_INDI)
48 DEFINE_DELETEFUNC(individual)
49 DEFINE_GETXREFFUNC(individual, XREF_INDI)
50      
51 DEFINE_REC_CB(individual, indi_start)
52 DEFINE_STRING_CB(individual, indi_resn_start, restriction_notice)
53 DEFINE_STRING_CB(individual, indi_sex_start, sex)
54 DEFINE_XREF_LIST_CB(individual, indi_subm_start, submitters, submitter)
55 DEFINE_XREF_LIST_CB(individual, indi_alia_start, alias, individual)
56 DEFINE_XREF_LIST_CB(individual, indi_anci_start, ancestor_interest, submitter)
57 DEFINE_XREF_LIST_CB(individual, indi_desi_start, descendant_interest,submitter)
58 DEFINE_STRING_CB(individual, indi_rfn_start, record_file_nr)
59 DEFINE_STRING_CB(individual, indi_afn_start, ancestral_file_nr)
60
61 DEFINE_ADDFUNC2(individual, event, event)
62 DEFINE_ADDFUNC2_TOVAR(individual, event, attribute)
63 DEFINE_ADDFUNC2(individual, personal_name, name)
64 DEFINE_ADDFUNC2(individual, lds_event, lds_individual_ordinance)
65 DEFINE_ADDFUNC2(individual, association, association)
66 DEFINE_ADDFUNC2(individual, source_citation, citation)
67 DEFINE_ADDFUNC2(individual, multimedia_link, mm_link)
68 DEFINE_ADDFUNC2(individual, note_sub, note)
69 DEFINE_ADDFUNC2(individual, user_ref_number, ref)
70 DEFINE_ADDFUNC2(individual, user_data, extra)
71 DEFINE_ADDFUNC2_NOLIST(individual, change_date, change_date)
72 DEFINE_ADDFUNC2_STR(individual, record_id)
73
74 void individual_subscribe()
75 {
76   gedcom_subscribe_to_record(REC_INDI, indi_start, def_rec_end);
77   gedcom_subscribe_to_element(ELT_INDI_RESN, indi_resn_start, def_elt_end);
78   gedcom_subscribe_to_element(ELT_INDI_SEX, indi_sex_start, def_elt_end);
79   gedcom_subscribe_to_element(ELT_INDI_SUBM, indi_subm_start, def_elt_end);
80   gedcom_subscribe_to_element(ELT_INDI_ALIA, indi_alia_start, def_elt_end);
81   gedcom_subscribe_to_element(ELT_INDI_ANCI, indi_anci_start, def_elt_end);
82   gedcom_subscribe_to_element(ELT_INDI_DESI, indi_desi_start, def_elt_end);
83   gedcom_subscribe_to_element(ELT_INDI_RFN, indi_rfn_start, def_elt_end);
84   gedcom_subscribe_to_element(ELT_INDI_AFN, indi_afn_start, def_elt_end);
85 }
86
87 void individual_add_family_link(Gom_ctxt ctxt, int ctxt_type,
88                                 struct family_link* link)
89 {
90   struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt);
91   if (indiv) {
92     switch (ctxt_type) {
93       case ELT_SUB_FAMC:
94         LINK_CHAIN_ELT(family_link, indiv->child_to_family, link);
95         break;
96       case ELT_SUB_FAMS:
97         LINK_CHAIN_ELT(family_link, indiv->spouse_to_family, link);
98         break;
99       default:
100         UNEXPECTED_CONTEXT(ctxt_type);
101     }
102   }
103 }
104
105 void UNREFALLFUNC(individual)(struct individual *obj)
106 {
107   if (obj) {
108     UNREFALLFUNC(personal_name)(obj->name);
109     UNREFALLFUNC(event)(obj->event);
110     UNREFALLFUNC(event)(obj->attribute);
111     UNREFALLFUNC(lds_event)(obj->lds_individual_ordinance);
112     UNREFALLFUNC(family_link)(obj->child_to_family);
113     UNREFALLFUNC(family_link)(obj->spouse_to_family);
114     UNREFALLFUNC(xref_list)(obj->submitters);
115     UNREFALLFUNC(association)(obj->association);
116     UNREFALLFUNC(xref_list)(obj->alias);
117     UNREFALLFUNC(xref_list)(obj->ancestor_interest);
118     UNREFALLFUNC(xref_list)(obj->descendant_interest);
119     UNREFALLFUNC(source_citation)(obj->citation);
120     UNREFALLFUNC(multimedia_link)(obj->mm_link);
121     UNREFALLFUNC(note_sub)(obj->note);
122     UNREFALLFUNC(user_ref_number)(obj->ref);
123     UNREFALLFUNC(change_date)(obj->change_date);
124     UNREFALLFUNC(user_data)(obj->extra);
125   }
126 }
127
128 void CLEANFUNC(individual)(struct individual* indiv)
129 {
130   if (indiv) {
131     SAFE_FREE(indiv->xrefstr);
132     SAFE_FREE(indiv->restriction_notice);
133     DESTROY_CHAIN_ELTS(personal_name, indiv->name);
134     SAFE_FREE(indiv->sex);
135     DESTROY_CHAIN_ELTS(event, indiv->event);
136     DESTROY_CHAIN_ELTS(event, indiv->attribute);
137     DESTROY_CHAIN_ELTS(lds_event, indiv->lds_individual_ordinance);
138     DESTROY_CHAIN_ELTS(family_link, indiv->child_to_family);
139     DESTROY_CHAIN_ELTS(family_link, indiv->spouse_to_family);
140     DESTROY_CHAIN_ELTS(xref_list, indiv->submitters);
141     DESTROY_CHAIN_ELTS(association, indiv->association);  
142     DESTROY_CHAIN_ELTS(xref_list, indiv->alias);
143     DESTROY_CHAIN_ELTS(xref_list, indiv->ancestor_interest);
144     DESTROY_CHAIN_ELTS(xref_list, indiv->descendant_interest);
145     DESTROY_CHAIN_ELTS(source_citation, indiv->citation);
146     DESTROY_CHAIN_ELTS(multimedia_link, indiv->mm_link);
147     DESTROY_CHAIN_ELTS(note_sub, indiv->note);
148     SAFE_FREE(indiv->record_file_nr);
149     SAFE_FREE(indiv->ancestral_file_nr);
150     DESTROY_CHAIN_ELTS(user_ref_number, indiv->ref);
151     SAFE_FREE(indiv->record_id);
152     CLEANFUNC(change_date)(indiv->change_date);
153     DESTROY_CHAIN_ELTS(user_data, indiv->extra);
154   }
155 }
156
157 void individuals_cleanup()
158 {
159   DESTROY_CHAIN_ELTS(individual, gom_first_individual);
160 }
161
162 struct individual* gom_get_first_individual()
163 {
164   return gom_first_individual;
165 }
166
167 int write_individuals(Gedcom_write_hndl hndl)
168 {
169   int result = 0;
170   struct individual* obj;
171
172   for (obj = gom_first_individual; obj; obj = obj->next) {
173     result |= gedcom_write_record_str(hndl, REC_INDI, obj->xrefstr, NULL);
174     if (obj->restriction_notice)
175       result |= gedcom_write_element_str(hndl, ELT_INDI_RESN, 0,
176                                          REC_INDI, obj->restriction_notice);
177     if (obj->name)
178       result |= write_names(hndl, REC_INDI, obj->name);
179     if (obj->sex)
180       result |= gedcom_write_element_str(hndl, ELT_INDI_SEX, 0,
181                                          REC_INDI, obj->sex);
182     if (obj->event)
183       result |= write_events(hndl, REC_INDI, EVT_TYPE_INDIV_EVT, obj->event);
184     if (obj->attribute)
185       result |= write_events(hndl, REC_INDI, EVT_TYPE_INDIV_ATTR,
186                              obj->attribute);
187     if (obj->lds_individual_ordinance)
188       result |= write_lds_events(hndl, REC_INDI,
189                                  obj->lds_individual_ordinance);
190     if (obj->child_to_family)
191       result |= write_family_links(hndl, REC_INDI, LINK_TYPE_CHILD,
192                                    obj->child_to_family);
193     if (obj->spouse_to_family)
194       result |= write_family_links(hndl, REC_INDI, LINK_TYPE_SPOUSE,
195                                    obj->spouse_to_family);
196     result |= gom_write_xref_list(hndl, ELT_INDI_SUBM, 0,
197                                   REC_INDI, obj->submitters);
198     if (obj->association)
199       result |= write_associations(hndl, REC_INDI, obj->association);
200     result |= gom_write_xref_list(hndl, ELT_INDI_ALIA, 0,
201                                   REC_INDI, obj->alias);
202     result |= gom_write_xref_list(hndl, ELT_INDI_ANCI, 0,
203                                   REC_INDI, obj->ancestor_interest);
204     result |= gom_write_xref_list(hndl, ELT_INDI_DESI, 0,
205                                   REC_INDI, obj->descendant_interest);
206     if (obj->citation)
207       result |= write_citations(hndl, REC_INDI, obj->citation);
208     if (obj->mm_link)
209       result |= write_multimedia_links(hndl, REC_INDI, obj->mm_link);
210     if (obj->note)
211       result |= write_note_subs(hndl, REC_INDI, obj->note);
212     if (obj->record_file_nr)
213       result |= gedcom_write_element_str(hndl, ELT_INDI_RFN, 0,
214                                          REC_INDI, obj->record_file_nr);
215     if (obj->ancestral_file_nr)
216       result |= gedcom_write_element_str(hndl, ELT_INDI_AFN, 0,
217                                          REC_INDI, obj->ancestral_file_nr);
218     if (obj->ref)
219       result |= write_user_refs(hndl, REC_INDI, obj->ref);
220     if (obj->record_id)
221       result |= gedcom_write_element_str(hndl, ELT_SUB_IDENT_RIN, 0,
222                                          REC_INDI, obj->record_id);
223     if (obj->change_date)
224       result |= write_change_date(hndl, REC_INDI, obj->change_date);
225     if (obj->extra)
226       result |= write_user_data(hndl, obj->extra);
227   }
228   
229   return result;
230 }
231