X-Git-Url: https://git.dlugolecki.net.pl/?a=blobdiff_plain;f=gom%2Fevent.c;h=b585a688abca91f686c7e5ac5d840e85ff0ff8fa;hb=8073f669d16f11bfd50d42bb2cf6fdb79d358565;hp=e19fd379ba2e11f2ab77ac2d41d96be113a6ecd0;hpb=7ea4ef8cae7b52f2bf66371a5e7b493cbd12900e;p=gedcom-parse.git diff --git a/gom/event.c b/gom/event.c index e19fd37..b585a68 100644 --- a/gom/event.c +++ b/gom/event.c @@ -39,124 +39,153 @@ Gedcom_ctxt sub_evt_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; - struct event *evt = NULL; - - if (ctxt) { - evt = (struct event *)malloc(sizeof(struct event)); - memset (evt, 0, sizeof(struct event)); - evt->event = parsed_tag; - evt->event_name = strdup(tag); - if (GEDCOM_IS_STRING(parsed_value)) - evt->val = strdup(GEDCOM_STRING(parsed_value)); - - switch (ctxt->ctxt_type) { - case REC_FAM: - family_add_event(ctxt, evt); break; - case REC_INDI: - individual_add_event(ctxt, evt); break; - default: - UNEXPECTED_CONTEXT(ctxt->ctxt_type); + Gom_ctxt result = NULL; + + if (! ctxt) + NO_CONTEXT; + else { + struct event *evt = SUB_MAKEFUNC(event)(); + if (evt) { + evt->event = parsed_tag; + evt->event_name = strdup(tag); + if (! evt->event_name) { + MEMORY_ERROR; + free(evt); + } + else { + int err = 0; + if (GEDCOM_IS_STRING(parsed_value)) { + evt->val = strdup(GEDCOM_STRING(parsed_value)); + if (! evt->val) { + MEMORY_ERROR; + free(evt->event_name); + free(evt); + err = 1; + } + } + + if (! err) { + int type = ctxt_type(ctxt); + switch (type) { + case REC_FAM: + ADDFUNC2(family,event)(ctxt, evt); break; + case REC_INDI: + ADDFUNC2(individual,event)(ctxt, evt); break; + default: + UNEXPECTED_CONTEXT(type); + } + result = MAKE_GOM_CTXT(elt, event, evt); + } + } } } - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, event, evt); + return (Gedcom_ctxt)result; } Gedcom_ctxt sub_attr_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; - struct event *evt = NULL; - - if (ctxt) { - evt = (struct event *)malloc(sizeof(struct event)); - memset (evt, 0, sizeof(struct event)); - evt->event = parsed_tag; - evt->event_name = strdup(tag); - if (GEDCOM_IS_STRING(parsed_value)) - evt->val = strdup(GEDCOM_STRING(parsed_value)); - switch (ctxt->ctxt_type) { - case REC_INDI: - individual_add_attribute(ctxt, evt); break; - default: - UNEXPECTED_CONTEXT(ctxt->ctxt_type); + Gom_ctxt result = NULL; + + if (! ctxt) + NO_CONTEXT; + else { + struct event *evt = SUB_MAKEFUNC(event)(); + if (evt) { + evt->event = parsed_tag; + evt->event_name = strdup(tag); + if (! evt->event_name) { + MEMORY_ERROR; + free(evt); + } + else { + int err = 0; + if (GEDCOM_IS_STRING(parsed_value)) { + evt->val = strdup(GEDCOM_STRING(parsed_value)); + if (! evt->val) { + MEMORY_ERROR; + free(evt->event_name); + free(evt); + err = 1; + } + } + + if (! err) { + int type = ctxt_type(ctxt); + switch (type) { + case REC_INDI: + ADDFUNC2_TOVAR(individual,event,attribute)(ctxt, evt); break; + default: + UNEXPECTED_CONTEXT(type); + } + result = MAKE_GOM_CTXT(elt, event, evt); + } + } } } - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, event, evt); + return (Gedcom_ctxt)result; } -STRING_CB(event, sub_evt_type_start, type) -DATE_CB(event, sub_evt_date_start, date) -AGE_CB(event, sub_evt_age_start, age) -STRING_CB(event, sub_evt_agnc_start, agency) -STRING_CB(event, sub_evt_caus_start, cause) -NULL_CB(event, sub_fam_evt_husb_wife_start) -XREF_CB(event, sub_evt_famc_start, family, make_family_record) -STRING_CB(event, sub_evt_famc_adop_start, adoption_parent) +DEFINE_SUB_MAKEFUNC(event) +DEFINE_SUB_ADDFUNC(event) +DEFINE_SUB_FINDFUNC(event) +DEFINE_SUB_REMOVEFUNC(event) +DEFINE_SUB_MOVEFUNC(event) +DEFINE_STRING_CB(event, sub_evt_type_start, type) +DEFINE_DATE_CB(event, sub_evt_date_start, date) +DEFINE_AGE_CB(event, sub_evt_age_start, age) +DEFINE_STRING_CB(event, sub_evt_agnc_start, agency) +DEFINE_STRING_CB(event, sub_evt_caus_start, cause) +DEFINE_NULL_CB(event, sub_fam_evt_husb_wife_start) +DEFINE_XREF_CB(event, sub_evt_famc_start, family, family) +DEFINE_STRING_CB(event, sub_evt_famc_adop_start, adoption_parent) + +DEFINE_ADDFUNC2(event, source_citation, citation) +DEFINE_ADDFUNC2(event, multimedia_link, mm_link) +DEFINE_ADDFUNC2(event, note_sub, note) +DEFINE_ADDFUNC2(event, user_data, extra) +DEFINE_ADDFUNC2_NOLIST(event, place, place) +DEFINE_ADDFUNC2_NOLIST(event, address, address) +DEFINE_ADDFUNC2_STRN(event, phone, 3) + Gedcom_ctxt sub_fam_evt_age_start(_ELT_PARAMS_) { - struct age_value age = GEDCOM_AGE(parsed_value); Gom_ctxt ctxt = (Gom_ctxt)parent; - struct event *evt = NULL; - if (ctxt) { - evt = SAFE_CTXT_CAST(event, ctxt); - switch (ctxt->ctxt_type) { - case ELT_SUB_FAM_EVT_HUSB: - evt->husband_age = dup_age(age); break; - case ELT_SUB_FAM_EVT_WIFE: - evt->wife_age = dup_age(age); break; - default: - UNEXPECTED_CONTEXT(ctxt->ctxt_type); + Gom_ctxt result = NULL; + + if (! ctxt) + NO_CONTEXT; + else { + struct event *evt = SAFE_CTXT_CAST(event, ctxt); + if (evt) { + int err = 0; + struct age_value age = GEDCOM_AGE(parsed_value); + int type = ctxt_type(ctxt); + switch (type) { + case ELT_SUB_FAM_EVT_HUSB: + evt->husband_age = gedcom_new_age_value(&age); + if (! evt->husband_age) { + MEMORY_ERROR; + err = 1; + } + break; + case ELT_SUB_FAM_EVT_WIFE: + evt->wife_age = gedcom_new_age_value(&age); + if (! evt->wife_age) { + MEMORY_ERROR; + err = 1; + } + break; + default: + UNEXPECTED_CONTEXT(type); + } + if (! err) + result = MAKE_GOM_CTXT(elt, event, evt); } } - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, event, evt); -} - -void event_add_place(Gom_ctxt ctxt, struct place* place) -{ - struct event *evt = SAFE_CTXT_CAST(event, ctxt); - evt->place = place; -} - -void event_add_address(Gom_ctxt ctxt, struct address* address) -{ - struct event *evt = SAFE_CTXT_CAST(event, ctxt); - evt->address = address; -} - -void event_add_phone(Gom_ctxt ctxt, char *phone) -{ - struct event *evt = SAFE_CTXT_CAST(event, ctxt); - if (! evt->phone[0]) - evt->phone[0] = strdup(phone); - else if (! evt->phone[1]) - evt->phone[1] = strdup(phone); - else if (! evt->phone[2]) - evt->phone[2] = strdup(phone); -} - -void event_add_citation(Gom_ctxt ctxt, struct source_citation* cit) -{ - struct event *evt = SAFE_CTXT_CAST(event, ctxt); - LINK_CHAIN_ELT(source_citation, evt->citation, cit) -} - -void event_add_mm_link(Gom_ctxt ctxt, struct multimedia_link* mm) -{ - struct event *evt = SAFE_CTXT_CAST(event, ctxt); - LINK_CHAIN_ELT(multimedia_link, evt->mm_link, mm) -} - -void event_add_note(Gom_ctxt ctxt, struct note_sub* note) -{ - struct event *evt = SAFE_CTXT_CAST(event, ctxt); - LINK_CHAIN_ELT(note_sub, evt->note, note) -} - -void event_add_user_data(Gom_ctxt ctxt, struct user_data* data) -{ - struct event *obj = SAFE_CTXT_CAST(event, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + return (Gedcom_ctxt)result; } void event_subscribe() @@ -200,27 +229,168 @@ void event_subscribe() sub_evt_caus_start, def_elt_end); } -void event_cleanup(struct event* evt) +void UNREFALLFUNC(event)(struct event* obj) +{ + if (obj) { + struct event* runner; + for (runner = obj; runner; runner = runner->next) { + UNREFALLFUNC(place)(runner->place); + UNREFALLFUNC(address)(runner->address); + UNREFALLFUNC(source_citation)(runner->citation); + UNREFALLFUNC(multimedia_link)(runner->mm_link); + UNREFALLFUNC(note_sub)(runner->note); + unref_xref_value(runner->family); + UNREFALLFUNC(user_data)(runner->extra); + } + } +} + +void CLEANFUNC(event)(struct event* evt) { if (evt) { SAFE_FREE(evt->event_name); SAFE_FREE(evt->val); SAFE_FREE(evt->type); SAFE_FREE(evt->date); - place_cleanup(evt->place); - address_cleanup(evt->address); + CLEANFUNC(place)(evt->place); + CLEANFUNC(address)(evt->address); SAFE_FREE(evt->phone[0]); SAFE_FREE(evt->phone[1]); SAFE_FREE(evt->phone[2]); SAFE_FREE(evt->age); SAFE_FREE(evt->agency); SAFE_FREE(evt->cause); - DESTROY_CHAIN_ELTS(source_citation, evt->citation, citation_cleanup) - DESTROY_CHAIN_ELTS(multimedia_link, evt->mm_link, multimedia_link_cleanup) - DESTROY_CHAIN_ELTS(note_sub, evt->note, note_sub_cleanup) + DESTROY_CHAIN_ELTS(source_citation, evt->citation); + DESTROY_CHAIN_ELTS(multimedia_link, evt->mm_link); + DESTROY_CHAIN_ELTS(note_sub, evt->note); SAFE_FREE(evt->husband_age); SAFE_FREE(evt->wife_age); SAFE_FREE(evt->adoption_parent); - DESTROY_CHAIN_ELTS(user_data, evt->extra, user_data_cleanup) + DESTROY_CHAIN_ELTS(user_data, evt->extra); + } +} + +static int get_gedcom_elt(EventType evt_type, int parsed_tag) +{ + int obj_elt = 0; + switch (evt_type) { + case EVT_TYPE_FAMILY: + obj_elt = (parsed_tag == TAG_EVEN ? ELT_SUB_FAM_EVT_EVEN : + ELT_SUB_FAM_EVT); + break; + case EVT_TYPE_INDIV_ATTR: + obj_elt = (parsed_tag == TAG_RESI ? ELT_SUB_INDIV_RESI : + ELT_SUB_INDIV_ATTR); + break; + case EVT_TYPE_INDIV_EVT: + switch (parsed_tag) { + case TAG_BIRT: case TAG_CHR: + obj_elt = ELT_SUB_INDIV_BIRT; break; + case TAG_DEAT: case TAG_BURI: case TAG_CREM: case TAG_BAPM: + case TAG_BARM: case TAG_BASM: case TAG_BLES: case TAG_CHRA: + case TAG_CONF: case TAG_FCOM: case TAG_ORDN: case TAG_NATU: + case TAG_EMIG: case TAG_IMMI: case TAG_CENS: case TAG_PROB: + case TAG_WILL: case TAG_GRAD: case TAG_RETI: + obj_elt = ELT_SUB_INDIV_GEN; break; + case TAG_ADOP: + obj_elt = ELT_SUB_INDIV_ADOP; break; + case TAG_EVEN: + obj_elt = ELT_SUB_INDIV_EVEN; break; + default: + gedcom_warning(_("Internal error: unknown evt tag %d"), parsed_tag); + } + break; + default: + gedcom_warning(_("Internal error: unknown evt type %d"), evt_type); + } + return obj_elt; +} + +int get_gedcom_fam_elt(int elt) +{ + int fam_obj_elt = 0; + switch (elt) { + case ELT_SUB_INDIV_BIRT: + fam_obj_elt = ELT_SUB_INDIV_BIRT_FAMC; + break; + case ELT_SUB_INDIV_ADOP: + fam_obj_elt = ELT_SUB_INDIV_ADOP_FAMC; + break; + default: + gedcom_warning(_("Internal error: wrong parent for evt->family")); + } + return fam_obj_elt; +} + +int write_events(Gedcom_write_hndl hndl, int parent, EventType evt_type, + struct event* evt) +{ + int result = 0; + int i; + struct event* obj; + + if (!evt) return 1; + + for (obj = evt; obj; obj = obj->next) { + int obj_elt = get_gedcom_elt(evt_type, obj->event); + result |= gedcom_write_element_str(hndl, obj_elt, obj->event, + parent, obj->val); + if (obj->type) + result |= gedcom_write_element_str(hndl, ELT_SUB_EVT_TYPE, 0, + obj_elt, obj->type); + if (obj->date) + result |= gedcom_write_element_date(hndl, ELT_SUB_EVT_DATE, 0, + obj_elt, obj->date); + if (obj->place) + result |= write_place(hndl, obj_elt, obj->place); + if (obj->address) + result |= write_address(hndl, obj_elt, obj->address); + for (i = 0; i < 3 && obj->phone[i]; i++) + result |= gedcom_write_element_str(hndl, ELT_SUB_PHON, 0, obj_elt, + obj->phone[i]); + if (obj->age) + result |= gedcom_write_element_age(hndl, ELT_SUB_EVT_AGE, 0, + obj_elt, obj->age); + if (obj->agency) + result |= gedcom_write_element_str(hndl, ELT_SUB_EVT_AGNC, 0, + obj_elt, obj->agency); + if (obj->cause) + result |= gedcom_write_element_str(hndl, ELT_SUB_EVT_CAUS, 0, + obj_elt, obj->cause); + if (obj->citation) + result |= write_citations(hndl, obj_elt, obj->citation); + if (obj->mm_link) + result |= write_multimedia_links(hndl, obj_elt, obj->mm_link); + if (obj->note) + result |= write_note_subs(hndl, obj_elt, obj->note); + if (obj->husband_age) { + result |= gedcom_write_element_str(hndl, ELT_SUB_FAM_EVT_HUSB, 0, + obj_elt, NULL); + result |= gedcom_write_element_age(hndl, ELT_SUB_FAM_EVT_AGE, 0, + ELT_SUB_FAM_EVT_HUSB, + obj->husband_age); + } + if (obj->wife_age) { + result |= gedcom_write_element_str(hndl, ELT_SUB_FAM_EVT_WIFE, 0, + obj_elt, NULL); + result |= gedcom_write_element_age(hndl, ELT_SUB_FAM_EVT_AGE, 0, + ELT_SUB_FAM_EVT_WIFE, + obj->wife_age); + } + if (obj->family) { + int fam_obj_elt = get_gedcom_fam_elt(obj_elt); + result |= gedcom_write_element_xref(hndl, fam_obj_elt, 0, + obj_elt, obj->family); + if (obj->adoption_parent) { + result |= gedcom_write_element_str(hndl, ELT_SUB_INDIV_ADOP_FAMC_ADOP, + 0, fam_obj_elt, + obj->adoption_parent); + } + } + if (obj->extra) + result |= write_user_data(hndl, obj->extra); } + + return result; } +