Beginnings of write support.
[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 REC_CB(individual, indi_start, make_individual_record)
46 GET_REC_BY_XREF(individual, XREF_INDI, gom_get_individual_by_xref)
47 STRING_CB(individual, indi_resn_start, restriction_notice)
48 STRING_CB(individual, indi_sex_start, sex)
49 XREF_LIST_CB(individual, indi_subm_start, submitters, make_submitter_record)
50 XREF_LIST_CB(individual, indi_alia_start, alias, make_individual_record)
51 XREF_LIST_CB(individual, indi_anci_start, ancestor_interest,
52              make_submitter_record)
53 XREF_LIST_CB(individual, indi_desi_start, descendant_interest,
54              make_submitter_record)
55 STRING_CB(individual, indi_rfn_start, record_file_nr)
56 STRING_CB(individual, indi_afn_start, ancestral_file_nr)
57
58 void individual_subscribe()
59 {
60   gedcom_subscribe_to_record(REC_INDI, indi_start, def_rec_end);
61   gedcom_subscribe_to_element(ELT_INDI_RESN, indi_resn_start, def_elt_end);
62   gedcom_subscribe_to_element(ELT_INDI_SEX, indi_sex_start, def_elt_end);
63   gedcom_subscribe_to_element(ELT_INDI_SUBM, indi_subm_start, def_elt_end);
64   gedcom_subscribe_to_element(ELT_INDI_ALIA, indi_alia_start, def_elt_end);
65   gedcom_subscribe_to_element(ELT_INDI_ANCI, indi_anci_start, def_elt_end);
66   gedcom_subscribe_to_element(ELT_INDI_DESI, indi_desi_start, def_elt_end);
67   gedcom_subscribe_to_element(ELT_INDI_RFN, indi_rfn_start, def_elt_end);
68   gedcom_subscribe_to_element(ELT_INDI_AFN, indi_afn_start, def_elt_end);
69 }
70
71 void individual_add_event(Gom_ctxt ctxt, struct event* evt)
72 {
73   struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt);
74   if (indiv)
75     LINK_CHAIN_ELT(event, indiv->event, evt);
76 }
77
78 void individual_add_attribute(Gom_ctxt ctxt, struct event* evt)
79 {
80   struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt);
81   if (indiv)
82     LINK_CHAIN_ELT(event, indiv->attribute, evt);
83 }
84
85 void individual_add_name(Gom_ctxt ctxt, struct personal_name* name)
86 {
87   struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt);
88   if (indiv)
89     LINK_CHAIN_ELT(personal_name, indiv->name, name);
90 }
91
92 void individual_add_lio(Gom_ctxt ctxt, struct lds_event* evt)
93 {
94   struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt);
95   if (indiv)
96     LINK_CHAIN_ELT(lds_event, indiv->lds_individual_ordinance, evt);
97 }
98
99 void individual_add_family_link(Gom_ctxt ctxt, int ctxt_type,
100                                 struct family_link* link)
101 {
102   struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt);
103   if (indiv) {
104     switch (ctxt_type) {
105       case ELT_SUB_FAMC:
106         LINK_CHAIN_ELT(family_link, indiv->child_to_family, link);
107         break;
108       case ELT_SUB_FAMS:
109         LINK_CHAIN_ELT(family_link, indiv->spouse_to_family, link);
110         break;
111       default:
112         UNEXPECTED_CONTEXT(ctxt_type);
113     }
114   }
115 }
116
117 void individual_add_association(Gom_ctxt ctxt, struct association* assoc)
118 {
119   struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt);
120   if (indiv)
121     LINK_CHAIN_ELT(association, indiv->association, assoc);
122 }
123
124 void individual_add_citation(Gom_ctxt ctxt, struct source_citation* cit)
125 {
126   struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt);
127   if (indiv)
128     LINK_CHAIN_ELT(source_citation, indiv->citation, cit);
129 }
130
131 void individual_add_mm_link(Gom_ctxt ctxt, struct multimedia_link* link)
132 {
133   struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt);
134   if (indiv)
135     LINK_CHAIN_ELT(multimedia_link, indiv->mm_link, link);
136 }
137
138 void individual_add_note(Gom_ctxt ctxt, struct note_sub* note)
139 {
140   struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt);
141   if (indiv)
142     LINK_CHAIN_ELT(note_sub, indiv->note, note);
143 }
144
145 void individual_add_user_ref(Gom_ctxt ctxt, struct user_ref_number* ref)
146 {
147   struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt);
148   if (indiv)
149     LINK_CHAIN_ELT(user_ref_number, indiv->ref, ref);
150 }
151
152 void individual_set_record_id(Gom_ctxt ctxt, const char *rin)
153 {
154   struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt);
155   if (indiv) {
156     indiv->record_id = strdup(rin);
157     if (! indiv->record_id) MEMORY_ERROR;
158   }
159 }
160
161 void individual_set_change_date(Gom_ctxt ctxt, struct change_date* chan)
162 {
163   struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt);
164   if (indiv)
165     indiv->change_date = chan;
166 }
167
168 void individual_add_user_data(Gom_ctxt ctxt, struct user_data* data)
169 {
170   struct individual *obj = SAFE_CTXT_CAST(individual, ctxt);
171   if (obj)
172     LINK_CHAIN_ELT(user_data, obj->extra, data);
173 }
174
175 void individual_cleanup(struct individual* indiv)
176 {
177   if (indiv) {
178     SAFE_FREE(indiv->xrefstr);
179     SAFE_FREE(indiv->restriction_notice);
180     DESTROY_CHAIN_ELTS(personal_name, indiv->name, name_cleanup);
181     SAFE_FREE(indiv->sex);
182     DESTROY_CHAIN_ELTS(event, indiv->event, event_cleanup);
183     DESTROY_CHAIN_ELTS(event, indiv->attribute, event_cleanup);
184     DESTROY_CHAIN_ELTS(lds_event, indiv->lds_individual_ordinance,
185                        lds_event_cleanup);
186     DESTROY_CHAIN_ELTS(family_link,indiv->child_to_family,family_link_cleanup);
187     DESTROY_CHAIN_ELTS(family_link,indiv->spouse_to_family,
188                        family_link_cleanup);
189     DESTROY_CHAIN_ELTS(xref_list, indiv->submitters, NULL_DESTROY);
190     DESTROY_CHAIN_ELTS(association, indiv->association, association_cleanup);  
191     DESTROY_CHAIN_ELTS(xref_list, indiv->alias, NULL_DESTROY);
192     DESTROY_CHAIN_ELTS(xref_list, indiv->ancestor_interest, NULL_DESTROY);
193     DESTROY_CHAIN_ELTS(xref_list, indiv->descendant_interest, NULL_DESTROY);
194     DESTROY_CHAIN_ELTS(source_citation, indiv->citation, citation_cleanup);
195     DESTROY_CHAIN_ELTS(multimedia_link,indiv->mm_link,multimedia_link_cleanup);
196     DESTROY_CHAIN_ELTS(note_sub, indiv->note, note_sub_cleanup);
197     SAFE_FREE(indiv->record_file_nr);
198     SAFE_FREE(indiv->ancestral_file_nr);
199     DESTROY_CHAIN_ELTS(user_ref_number, indiv->ref, user_ref_cleanup);
200     SAFE_FREE(indiv->record_id);
201     change_date_cleanup(indiv->change_date);
202     DESTROY_CHAIN_ELTS(user_data, indiv->extra, user_data_cleanup);
203   }
204 }
205
206 void individuals_cleanup()
207 {
208   DESTROY_CHAIN_ELTS(individual, gom_first_individual, individual_cleanup);
209 }
210
211 struct individual* gom_get_first_individual()
212 {
213   return gom_first_individual;
214 }
215
216 struct individual* make_individual_record(const char* xrefstr)
217 {
218   struct individual* indiv = NULL;
219   MAKE_CHAIN_ELT(individual, gom_first_individual, indiv);
220   if (indiv) {
221     indiv->xrefstr = strdup(xrefstr);
222     if (! indiv->xrefstr) MEMORY_ERROR;
223   }
224   return indiv;
225 }