1 /* Event sub-structure 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.
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.
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.
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
27 #include "individual.h"
31 #include "source_citation.h"
32 #include "multimedia_link.h"
37 #include "gom_internal.h"
39 Gedcom_ctxt sub_evt_start(_ELT_PARAMS_)
41 Gom_ctxt ctxt = (Gom_ctxt)parent;
42 Gom_ctxt result = NULL;
47 struct event *evt = (struct event *)malloc(sizeof(struct event));
51 memset (evt, 0, sizeof(struct event));
52 evt->event = parsed_tag;
53 evt->event_name = strdup(tag);
54 if (! evt->event_name) {
60 if (GEDCOM_IS_STRING(parsed_value)) {
61 evt->val = strdup(GEDCOM_STRING(parsed_value));
64 free(evt->event_name);
71 switch (ctxt->ctxt_type) {
73 family_add_event(ctxt, evt); break;
75 individual_add_event(ctxt, evt); break;
77 UNEXPECTED_CONTEXT(ctxt->ctxt_type);
79 result = MAKE_GOM_CTXT(elt, event, evt);
85 return (Gedcom_ctxt)result;
88 Gedcom_ctxt sub_attr_start(_ELT_PARAMS_)
90 Gom_ctxt ctxt = (Gom_ctxt)parent;
91 Gom_ctxt result = NULL;
96 struct event *evt = (struct event *)malloc(sizeof(struct event));
100 memset (evt, 0, sizeof(struct event));
101 evt->event = parsed_tag;
102 evt->event_name = strdup(tag);
103 if (! evt->event_name) {
109 if (GEDCOM_IS_STRING(parsed_value)) {
110 evt->val = strdup(GEDCOM_STRING(parsed_value));
113 free(evt->event_name);
120 switch (ctxt->ctxt_type) {
122 individual_add_attribute(ctxt, evt); break;
124 UNEXPECTED_CONTEXT(ctxt->ctxt_type);
126 result = MAKE_GOM_CTXT(elt, event, evt);
131 return (Gedcom_ctxt)result;
134 STRING_CB(event, sub_evt_type_start, type)
135 DATE_CB(event, sub_evt_date_start, date)
136 AGE_CB(event, sub_evt_age_start, age)
137 STRING_CB(event, sub_evt_agnc_start, agency)
138 STRING_CB(event, sub_evt_caus_start, cause)
139 NULL_CB(event, sub_fam_evt_husb_wife_start)
140 XREF_CB(event, sub_evt_famc_start, family, make_family_record)
141 STRING_CB(event, sub_evt_famc_adop_start, adoption_parent)
143 Gedcom_ctxt sub_fam_evt_age_start(_ELT_PARAMS_)
145 Gom_ctxt ctxt = (Gom_ctxt)parent;
146 Gom_ctxt result = NULL;
151 struct event *evt = SAFE_CTXT_CAST(event, ctxt);
154 struct age_value age = GEDCOM_AGE(parsed_value);
155 switch (ctxt->ctxt_type) {
156 case ELT_SUB_FAM_EVT_HUSB:
157 evt->husband_age = gedcom_new_age_value(&age);
158 if (! evt->husband_age) {
163 case ELT_SUB_FAM_EVT_WIFE:
164 evt->wife_age = gedcom_new_age_value(&age);
165 if (! evt->wife_age) {
171 UNEXPECTED_CONTEXT(ctxt->ctxt_type);
174 result = MAKE_GOM_CTXT(elt, event, evt);
177 return (Gedcom_ctxt)result;
180 void event_add_place(Gom_ctxt ctxt, struct place* place)
182 struct event *evt = SAFE_CTXT_CAST(event, ctxt);
187 void event_add_address(Gom_ctxt ctxt, struct address* address)
189 struct event *evt = SAFE_CTXT_CAST(event, ctxt);
191 evt->address = address;
194 void event_add_phone(Gom_ctxt ctxt, char *phone)
196 struct event *evt = SAFE_CTXT_CAST(event, ctxt);
199 while (i<2 && evt->phone[i]) i++;
200 if (! evt->phone[i]) {
201 evt->phone[i] = strdup(phone);
202 if (! evt->phone[i]) MEMORY_ERROR;
207 void event_add_citation(Gom_ctxt ctxt, struct source_citation* cit)
209 struct event *evt = SAFE_CTXT_CAST(event, ctxt);
211 LINK_CHAIN_ELT(source_citation, evt->citation, cit);
214 void event_add_mm_link(Gom_ctxt ctxt, struct multimedia_link* mm)
216 struct event *evt = SAFE_CTXT_CAST(event, ctxt);
218 LINK_CHAIN_ELT(multimedia_link, evt->mm_link, mm);
221 void event_add_note(Gom_ctxt ctxt, struct note_sub* note)
223 struct event *evt = SAFE_CTXT_CAST(event, ctxt);
225 LINK_CHAIN_ELT(note_sub, evt->note, note);
228 void event_add_user_data(Gom_ctxt ctxt, struct user_data* data)
230 struct event *obj = SAFE_CTXT_CAST(event, ctxt);
232 LINK_CHAIN_ELT(user_data, obj->extra, data);
235 void event_subscribe()
237 gedcom_subscribe_to_element(ELT_SUB_FAM_EVT, sub_evt_start, def_elt_end);
238 gedcom_subscribe_to_element(ELT_SUB_FAM_EVT_EVEN,
239 sub_evt_start, def_elt_end);
240 gedcom_subscribe_to_element(ELT_SUB_INDIV_ATTR,
241 sub_attr_start, def_elt_end);
242 gedcom_subscribe_to_element(ELT_SUB_INDIV_RESI,
243 sub_attr_start, def_elt_end);
244 gedcom_subscribe_to_element(ELT_SUB_INDIV_BIRT,
245 sub_evt_start, def_elt_end);
246 gedcom_subscribe_to_element(ELT_SUB_INDIV_BIRT_FAMC,
247 sub_evt_famc_start, def_elt_end);
248 gedcom_subscribe_to_element(ELT_SUB_INDIV_GEN,
249 sub_evt_start, def_elt_end);
250 gedcom_subscribe_to_element(ELT_SUB_INDIV_ADOP,
251 sub_evt_start, def_elt_end);
252 gedcom_subscribe_to_element(ELT_SUB_INDIV_ADOP_FAMC,
253 sub_evt_famc_start, def_elt_end);
254 gedcom_subscribe_to_element(ELT_SUB_INDIV_ADOP_FAMC_ADOP,
255 sub_evt_famc_adop_start, def_elt_end);
256 gedcom_subscribe_to_element(ELT_SUB_INDIV_EVEN,
257 sub_evt_start, def_elt_end);
258 gedcom_subscribe_to_element(ELT_SUB_FAM_EVT_HUSB,
259 sub_fam_evt_husb_wife_start, def_elt_end);
260 gedcom_subscribe_to_element(ELT_SUB_FAM_EVT_WIFE,
261 sub_fam_evt_husb_wife_start, def_elt_end);
262 gedcom_subscribe_to_element(ELT_SUB_FAM_EVT_AGE,
263 sub_fam_evt_age_start, def_elt_end);
264 gedcom_subscribe_to_element(ELT_SUB_EVT_TYPE,
265 sub_evt_type_start, def_elt_end);
266 gedcom_subscribe_to_element(ELT_SUB_EVT_DATE,
267 sub_evt_date_start, def_elt_end);
268 gedcom_subscribe_to_element(ELT_SUB_EVT_AGE,
269 sub_evt_age_start, def_elt_end);
270 gedcom_subscribe_to_element(ELT_SUB_EVT_AGNC,
271 sub_evt_agnc_start, def_elt_end);
272 gedcom_subscribe_to_element(ELT_SUB_EVT_CAUS,
273 sub_evt_caus_start, def_elt_end);
276 void event_cleanup(struct event* evt)
279 SAFE_FREE(evt->event_name);
281 SAFE_FREE(evt->type);
282 SAFE_FREE(evt->date);
283 place_cleanup(evt->place);
284 address_cleanup(evt->address);
285 SAFE_FREE(evt->phone[0]);
286 SAFE_FREE(evt->phone[1]);
287 SAFE_FREE(evt->phone[2]);
289 SAFE_FREE(evt->agency);
290 SAFE_FREE(evt->cause);
291 DESTROY_CHAIN_ELTS(source_citation, evt->citation, citation_cleanup);
292 DESTROY_CHAIN_ELTS(multimedia_link, evt->mm_link, multimedia_link_cleanup);
293 DESTROY_CHAIN_ELTS(note_sub, evt->note, note_sub_cleanup);
294 SAFE_FREE(evt->husband_age);
295 SAFE_FREE(evt->wife_age);
296 SAFE_FREE(evt->adoption_parent);
297 DESTROY_CHAIN_ELTS(user_data, evt->extra, user_data_cleanup);
301 static int get_gedcom_elt(EventType evt_type, int parsed_tag)
305 case EVT_TYPE_FAMILY:
306 obj_elt = (parsed_tag == TAG_EVEN ? ELT_SUB_FAM_EVT_EVEN :
309 case EVT_TYPE_INDIV_ATTR:
310 obj_elt = (parsed_tag == TAG_RESI ? ELT_SUB_INDIV_RESI :
313 case EVT_TYPE_INDIV_EVT:
314 switch (parsed_tag) {
315 case TAG_BIRT: case TAG_CHR:
316 obj_elt = ELT_SUB_INDIV_BIRT; break;
317 case TAG_DEAT: case TAG_BURI: case TAG_CREM: case TAG_BAPM:
318 case TAG_BARM: case TAG_BASM: case TAG_BLES: case TAG_CHRA:
319 case TAG_CONF: case TAG_FCOM: case TAG_ORDN: case TAG_NATU:
320 case TAG_EMIG: case TAG_IMMI: case TAG_CENS: case TAG_PROB:
321 case TAG_WILL: case TAG_GRAD: case TAG_RETI:
322 obj_elt = ELT_SUB_INDIV_GEN; break;
324 obj_elt = ELT_SUB_INDIV_ADOP; break;
326 obj_elt = ELT_SUB_INDIV_EVEN; break;
328 gedcom_warning(_("Internal error: unknown evt tag %d"), parsed_tag);
332 gedcom_warning(_("Internal error: unknown evt type %d"), evt_type);
337 int get_gedcom_fam_elt(int elt)
341 case ELT_SUB_INDIV_BIRT:
342 fam_obj_elt = ELT_SUB_INDIV_BIRT_FAMC;
344 case ELT_SUB_INDIV_ADOP:
345 fam_obj_elt = ELT_SUB_INDIV_ADOP_FAMC;
348 gedcom_warning(_("Internal error: wrong parent for evt->family"));
353 int write_events(Gedcom_write_hndl hndl, int parent, EventType evt_type,
362 for (obj = evt; obj; obj = obj->next) {
363 int obj_elt = get_gedcom_elt(evt_type, obj->event);
364 result |= gedcom_write_element_str(hndl, obj_elt, obj->event,
367 result |= gedcom_write_element_str(hndl, ELT_SUB_EVT_TYPE, 0,
370 result |= gedcom_write_element_date(hndl, ELT_SUB_EVT_DATE, 0,
373 result |= write_place(hndl, obj_elt, obj->place);
375 result |= write_address(hndl, obj_elt, obj->address);
376 for (i = 0; i < 3 && obj->phone[i]; i++)
377 result |= gedcom_write_element_str(hndl, ELT_SUB_PHON, 0, obj_elt,
380 result |= gedcom_write_element_age(hndl, ELT_SUB_EVT_AGE, 0,
383 result |= gedcom_write_element_str(hndl, ELT_SUB_EVT_AGNC, 0,
384 obj_elt, obj->agency);
386 result |= gedcom_write_element_str(hndl, ELT_SUB_EVT_CAUS, 0,
387 obj_elt, obj->cause);
389 result |= write_citations(hndl, obj_elt, obj->citation);
391 result |= write_multimedia_links(hndl, obj_elt, obj->mm_link);
393 result |= write_note_subs(hndl, obj_elt, obj->note);
394 if (obj->husband_age) {
395 result |= gedcom_write_element_str(hndl, ELT_SUB_FAM_EVT_HUSB, 0,
397 result |= gedcom_write_element_age(hndl, ELT_SUB_FAM_EVT_AGE, 0,
398 ELT_SUB_FAM_EVT_HUSB,
402 result |= gedcom_write_element_str(hndl, ELT_SUB_FAM_EVT_WIFE, 0,
404 result |= gedcom_write_element_age(hndl, ELT_SUB_FAM_EVT_AGE, 0,
405 ELT_SUB_FAM_EVT_WIFE,
409 int fam_obj_elt = get_gedcom_fam_elt(obj_elt);
410 result |= gedcom_write_element_xref(hndl, fam_obj_elt, 0,
411 obj_elt, obj->family);
412 if (obj->adoption_parent) {
413 result |= gedcom_write_element_str(hndl, ELT_SUB_INDIV_ADOP_FAMC_ADOP,
415 obj->adoption_parent);
419 result |= write_user_data(hndl, obj->extra);