From bdf47fdee469d5a1d7ddfd06a0e4b26f3b40b0f4 Mon Sep 17 00:00:00 2001 From: Peter Verthez Date: Wed, 11 Sep 2002 18:39:16 +0000 Subject: [PATCH] More thorough error handling. --- gom/address.c | 100 ++++++++++++------- gom/association.c | 70 ++++++++----- gom/change_date.c | 63 +++++++----- gom/event.c | 195 ++++++++++++++++++++++++------------ gom/family.c | 64 +++++++----- gom/family_link.c | 71 ++++++++----- gom/gom.c | 10 +- gom/gom_internal.h | 147 ++++++++++++++++++--------- gom/header.c | 32 +++--- gom/individual.c | 116 +++++++++++++--------- gom/lds_event.c | 49 +++++---- gom/multimedia.c | 80 ++++++++++----- gom/multimedia_link.c | 78 ++++++++------- gom/note.c | 72 +++++++++----- gom/note_sub.c | 142 +++++++++++++++----------- gom/personal_name.c | 47 ++++++--- gom/place.c | 66 ++++++++----- gom/repository.c | 65 +++++++----- gom/source.c | 122 +++++++++++++++-------- gom/source_citation.c | 160 +++++++++++++++++++----------- gom/source_description.c | 40 +++++--- gom/source_event.c | 41 +++++--- gom/submission.c | 14 ++- gom/submitter.c | 98 +++++++++++------- gom/user_rec.c | 208 ++++++++++++++++++++++++--------------- gom/user_ref.c | 71 ++++++++----- 26 files changed, 1432 insertions(+), 789 deletions(-) diff --git a/gom/address.c b/gom/address.c index 03da991..f8972e6 100644 --- a/gom/address.c +++ b/gom/address.c @@ -36,44 +36,71 @@ Gedcom_ctxt sub_addr_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; - struct address *addr = (struct address *)malloc(sizeof(struct address)); - char *str = GEDCOM_STRING(parsed_value); - - memset (addr, 0, sizeof(struct address)); - addr->full_label = strdup(str); + Gom_ctxt result = NULL; - if (ctxt) { - switch (ctxt->ctxt_type) { - case ELT_HEAD_SOUR_CORP: - header_add_address(ctxt, addr); break; - case ELT_SUB_FAM_EVT: - case ELT_SUB_FAM_EVT_EVEN: - case ELT_SUB_INDIV_ATTR: - case ELT_SUB_INDIV_RESI: - case ELT_SUB_INDIV_BIRT: - case ELT_SUB_INDIV_GEN: - case ELT_SUB_INDIV_ADOP: - case ELT_SUB_INDIV_EVEN: - event_add_address(ctxt, addr); break; - case REC_REPO: - repository_add_address(ctxt, addr); break; - case REC_SUBM: - submitter_add_address(ctxt, addr); break; - default: - UNEXPECTED_CONTEXT(ctxt->ctxt_type); + if (!ctxt) + NO_CONTEXT; + else { + struct address *addr = (struct address *)malloc(sizeof(struct address)); + if (!addr) + MEMORY_ERROR; + else { + char *str = GEDCOM_STRING(parsed_value); + memset (addr, 0, sizeof(struct address)); + addr->full_label = strdup(str); + + if (! addr->full_label) { + MEMORY_ERROR; + free(addr); + } + else { + switch (ctxt->ctxt_type) { + case ELT_HEAD_SOUR_CORP: + header_add_address(ctxt, addr); break; + case ELT_SUB_FAM_EVT: + case ELT_SUB_FAM_EVT_EVEN: + case ELT_SUB_INDIV_ATTR: + case ELT_SUB_INDIV_RESI: + case ELT_SUB_INDIV_BIRT: + case ELT_SUB_INDIV_GEN: + case ELT_SUB_INDIV_ADOP: + case ELT_SUB_INDIV_EVEN: + event_add_address(ctxt, addr); break; + case REC_REPO: + repository_add_address(ctxt, addr); break; + case REC_SUBM: + submitter_add_address(ctxt, addr); break; + default: + UNEXPECTED_CONTEXT(ctxt->ctxt_type); + } + result = MAKE_GOM_CTXT(elt, address, addr); + } } } - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, address, addr); + return (Gedcom_ctxt)result; } Gedcom_ctxt sub_addr_cont_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; - struct address *addr = SAFE_CTXT_CAST(address, ctxt); - char *str = GEDCOM_STRING(parsed_value); - addr->full_label = concat_strings (WITH_NL, addr->full_label, str); - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, address, addr); + Gom_ctxt result = NULL; + if (! ctxt) + NO_CONTEXT; + else { + struct address *addr = SAFE_CTXT_CAST(address, ctxt); + if (addr) { + char *str = GEDCOM_STRING(parsed_value); + char *newvalue = concat_strings (WITH_NL, addr->full_label, str); + if (! newvalue) + MEMORY_ERROR; + else { + addr->full_label = newvalue; + result = MAKE_GOM_CTXT(elt, address, addr); + } + } + } + return (Gedcom_ctxt)result; } STRING_CB(address, sub_addr_adr1_start, line1) @@ -86,8 +113,11 @@ STRING_CB(address, sub_addr_ctry_start, country) Gedcom_ctxt sub_phon_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; + Gom_ctxt result = NULL; - if (ctxt) { + if (! ctxt) + NO_CONTEXT; + else { char *str = GEDCOM_STRING(parsed_value); switch (ctxt->ctxt_type) { case ELT_HEAD_SOUR_CORP: @@ -107,10 +137,9 @@ Gedcom_ctxt sub_phon_start(_ELT_PARAMS_) default: UNEXPECTED_CONTEXT(ctxt->ctxt_type); } - return (Gedcom_ctxt) make_gom_ctxt(elt, ctxt->obj_type, ctxt->ctxt_ptr); + result = make_gom_ctxt(elt, ctxt->obj_type, ctxt->ctxt_ptr); } - else - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, NULL, NULL); + return (Gedcom_ctxt)result; } void address_subscribe() @@ -136,7 +165,8 @@ void address_subscribe() void address_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct address *obj = SAFE_CTXT_CAST(address, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data); } void address_cleanup(struct address *address) @@ -149,7 +179,7 @@ void address_cleanup(struct address *address) SAFE_FREE(address->state); SAFE_FREE(address->postal); SAFE_FREE(address->country); - DESTROY_CHAIN_ELTS(user_data, address->extra, user_data_cleanup) + DESTROY_CHAIN_ELTS(user_data, address->extra, user_data_cleanup); } SAFE_FREE(address); } diff --git a/gom/association.c b/gom/association.c index b42d481..fdd833b 100644 --- a/gom/association.c +++ b/gom/association.c @@ -35,34 +35,55 @@ Gedcom_ctxt sub_assoc_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; - struct association *assoc = NULL; + Gom_ctxt result = NULL; - if (ctxt) { + if (!ctxt) + NO_CONTEXT; + else { + struct association *assoc; assoc = (struct association *)malloc(sizeof(struct association)); - memset (assoc, 0, sizeof(struct association)); - assoc->to = GEDCOM_XREF_PTR(parsed_value); - - switch (ctxt->ctxt_type) { - case REC_INDI: - individual_add_association(ctxt, assoc); - default: - UNEXPECTED_CONTEXT(ctxt->ctxt_type); + if (! assoc) + MEMORY_ERROR; + else { + memset (assoc, 0, sizeof(struct association)); + assoc->to = GEDCOM_XREF_PTR(parsed_value); + + switch (ctxt->ctxt_type) { + case REC_INDI: + individual_add_association(ctxt, assoc); + default: + UNEXPECTED_CONTEXT(ctxt->ctxt_type); + } + result = MAKE_GOM_CTXT(elt, association, assoc); } } - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, association, assoc); + return (Gedcom_ctxt)result; } STRING_CB(association, sub_assoc_rela_start, relation) Gedcom_ctxt sub_assoc_type_start(_ELT_PARAMS_) { - char *str = GEDCOM_STRING(parsed_value); - struct association *obj = SAFE_CTXT_CAST(association, (Gom_ctxt)parent); - if (obj) - obj->type = strdup(str); - set_xref_type(obj->to, str); - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, association, obj); + Gom_ctxt ctxt = (Gom_ctxt)parent; + Gom_ctxt result = NULL; + + if (! ctxt) + NO_CONTEXT; + else { + struct association *obj = SAFE_CTXT_CAST(association, ctxt); + char *str = GEDCOM_STRING(parsed_value); + if (obj) { + obj->type = strdup(str); + if (! obj->type) + MEMORY_ERROR; + else { + set_xref_type(obj->to, str); + result = MAKE_GOM_CTXT(elt, association, obj); + } + } + } + return (Gedcom_ctxt)result; } void association_subscribe() @@ -77,19 +98,22 @@ void association_subscribe() void association_add_note(Gom_ctxt ctxt, struct note_sub* note) { struct association *assoc = SAFE_CTXT_CAST(association, ctxt); - LINK_CHAIN_ELT(note_sub, assoc->note, note) + if (assoc) + LINK_CHAIN_ELT(note_sub, assoc->note, note); } void association_add_citation(Gom_ctxt ctxt, struct source_citation* cit) { struct association *assoc = SAFE_CTXT_CAST(association, ctxt); - LINK_CHAIN_ELT(source_citation, assoc->citation, cit) + if (assoc) + LINK_CHAIN_ELT(source_citation, assoc->citation, cit); } void association_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct association *obj = SAFE_CTXT_CAST(association, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data); } void association_cleanup(struct association* assoc) @@ -97,8 +121,8 @@ void association_cleanup(struct association* assoc) if (assoc) { SAFE_FREE(assoc->type); SAFE_FREE(assoc->relation); - DESTROY_CHAIN_ELTS(note_sub, assoc->note, note_sub_cleanup) - DESTROY_CHAIN_ELTS(source_citation, assoc->citation, citation_cleanup) - DESTROY_CHAIN_ELTS(user_data, assoc->extra, user_data_cleanup) + DESTROY_CHAIN_ELTS(note_sub, assoc->note, note_sub_cleanup); + DESTROY_CHAIN_ELTS(source_citation, assoc->citation, citation_cleanup); + DESTROY_CHAIN_ELTS(user_data, assoc->extra, user_data_cleanup); } } diff --git a/gom/change_date.c b/gom/change_date.c index 9bcb616..cca7067 100644 --- a/gom/change_date.c +++ b/gom/change_date.c @@ -40,32 +40,41 @@ Gedcom_ctxt sub_chan_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; - struct change_date *chan - = (struct change_date *)malloc(sizeof(struct change_date)); - memset (chan, 0, sizeof(struct change_date)); + Gom_ctxt result = NULL; - if (ctxt) { - switch (ctxt->ctxt_type) { - case REC_FAM: - family_set_change_date(ctxt, chan); break; - case REC_INDI: - individual_set_change_date(ctxt, chan); break; - case REC_OBJE: - multimedia_set_change_date(ctxt, chan); break; - case REC_NOTE: - note_set_change_date(ctxt, chan); break; - case REC_REPO: - repository_set_change_date(ctxt, chan); break; - case REC_SOUR: - source_set_change_date(ctxt, chan); break; - case REC_SUBM: - submitter_set_change_date(ctxt, chan); break; - default: - UNEXPECTED_CONTEXT(ctxt->ctxt_type); + if (! ctxt) + NO_CONTEXT; + else { + struct change_date *chan + = (struct change_date *)malloc(sizeof(struct change_date)); + if (! chan) + MEMORY_ERROR; + else { + memset (chan, 0, sizeof(struct change_date)); + + switch (ctxt->ctxt_type) { + case REC_FAM: + family_set_change_date(ctxt, chan); break; + case REC_INDI: + individual_set_change_date(ctxt, chan); break; + case REC_OBJE: + multimedia_set_change_date(ctxt, chan); break; + case REC_NOTE: + note_set_change_date(ctxt, chan); break; + case REC_REPO: + repository_set_change_date(ctxt, chan); break; + case REC_SOUR: + source_set_change_date(ctxt, chan); break; + case REC_SUBM: + submitter_set_change_date(ctxt, chan); break; + default: + UNEXPECTED_CONTEXT(ctxt->ctxt_type); + } + result = MAKE_GOM_CTXT(elt, change_date, chan); } } - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, change_date, chan); + return (Gedcom_ctxt)result; } DATE_CB(change_date, sub_chan_date_start, date) @@ -83,13 +92,15 @@ void change_date_subscribe() void change_date_add_note(Gom_ctxt ctxt, struct note_sub* note) { struct change_date *chan = SAFE_CTXT_CAST(change_date, ctxt); - LINK_CHAIN_ELT(note_sub, chan->note, note) + if (chan) + LINK_CHAIN_ELT(note_sub, chan->note, note); } void change_date_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct change_date *obj = SAFE_CTXT_CAST(change_date, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data); } void change_date_cleanup(struct change_date *chan) @@ -97,8 +108,8 @@ void change_date_cleanup(struct change_date *chan) if (chan) { SAFE_FREE(chan->date); SAFE_FREE(chan->time); - DESTROY_CHAIN_ELTS(note_sub, chan->note, note_sub_cleanup) - DESTROY_CHAIN_ELTS(user_data, chan->extra, user_data_cleanup) + DESTROY_CHAIN_ELTS(note_sub, chan->note, note_sub_cleanup); + DESTROY_CHAIN_ELTS(user_data, chan->extra, user_data_cleanup); } SAFE_FREE(chan); } diff --git a/gom/event.c b/gom/event.c index e19fd37..aa15cda 100644 --- a/gom/event.c +++ b/gom/event.c @@ -39,49 +39,96 @@ 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 = (struct event *)malloc(sizeof(struct event)); + if (! evt) + MEMORY_ERROR; + else { + memset (evt, 0, sizeof(struct event)); + 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) { + 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); + } + 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 = (struct event *)malloc(sizeof(struct event)); + if (! evt) + MEMORY_ERROR; + else { + memset (evt, 0, sizeof(struct event)); + 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) { + switch (ctxt->ctxt_type) { + case REC_INDI: + individual_add_attribute(ctxt, evt); break; + default: + UNEXPECTED_CONTEXT(ctxt->ctxt_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) @@ -95,68 +142,94 @@ STRING_CB(event, sub_evt_famc_adop_start, adoption_parent) 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); + switch (ctxt->ctxt_type) { + case ELT_SUB_FAM_EVT_HUSB: + evt->husband_age = dup_age(age); + if (! evt->husband_age) { + MEMORY_ERROR; + err = 1; + } + break; + case ELT_SUB_FAM_EVT_WIFE: + evt->wife_age = dup_age(age); + if (! evt->wife_age) { + MEMORY_ERROR; + err = 1; + } + break; + default: + UNEXPECTED_CONTEXT(ctxt->ctxt_type); + } + if (! err) + result = MAKE_GOM_CTXT(elt, event, evt); } } - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, event, evt); + return (Gedcom_ctxt)result; } void event_add_place(Gom_ctxt ctxt, struct place* place) { struct event *evt = SAFE_CTXT_CAST(event, ctxt); - evt->place = place; + if (evt) + evt->place = place; } void event_add_address(Gom_ctxt ctxt, struct address* address) { struct event *evt = SAFE_CTXT_CAST(event, ctxt); - evt->address = address; + if (evt) + 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); + if (evt) { + int i = 0; + while (i<2 && evt->phone[i]) i++; + if (! evt->phone[i]) { + evt->phone[i] = strdup(phone); + if (! evt->phone[i]) MEMORY_ERROR; + } + } } 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) + if (evt) + 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) + if (evt) + 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) + if (evt) + 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) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data); } void event_subscribe() @@ -215,12 +288,12 @@ void event_cleanup(struct event* evt) 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, citation_cleanup); + DESTROY_CHAIN_ELTS(multimedia_link, evt->mm_link, multimedia_link_cleanup); + DESTROY_CHAIN_ELTS(note_sub, evt->note, note_sub_cleanup); 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, user_data_cleanup); } } diff --git a/gom/family.c b/gom/family.c index 34a5c5a..066753b 100644 --- a/gom/family.c +++ b/gom/family.c @@ -61,72 +61,85 @@ void family_subscribe() void family_add_event(Gom_ctxt ctxt, struct event* evt) { struct family *fam = SAFE_CTXT_CAST(family, ctxt); - LINK_CHAIN_ELT(event, fam->event, evt) + if (fam) + LINK_CHAIN_ELT(event, fam->event, evt); } void family_add_lss(Gom_ctxt ctxt, struct lds_event* lss) { struct family *fam = SAFE_CTXT_CAST(family, ctxt); - LINK_CHAIN_ELT(lds_event, fam->lds_spouse_sealing, lss) + if (fam) + LINK_CHAIN_ELT(lds_event, fam->lds_spouse_sealing, lss); } void family_add_citation(Gom_ctxt ctxt, struct source_citation* cit) { struct family *fam = SAFE_CTXT_CAST(family, ctxt); - LINK_CHAIN_ELT(source_citation, fam->citation, cit) + if (fam) + LINK_CHAIN_ELT(source_citation, fam->citation, cit); } void family_add_mm_link(Gom_ctxt ctxt, struct multimedia_link* link) { struct family *fam = SAFE_CTXT_CAST(family, ctxt); - LINK_CHAIN_ELT(multimedia_link, fam->mm_link, link) + if (fam) + LINK_CHAIN_ELT(multimedia_link, fam->mm_link, link); } void family_add_note(Gom_ctxt ctxt, struct note_sub* note) { struct family *fam = SAFE_CTXT_CAST(family, ctxt); - LINK_CHAIN_ELT(note_sub, fam->note, note) + if (fam) + LINK_CHAIN_ELT(note_sub, fam->note, note); } void family_add_user_ref(Gom_ctxt ctxt, struct user_ref_number* ref) { struct family *fam = SAFE_CTXT_CAST(family, ctxt); - LINK_CHAIN_ELT(user_ref_number, fam->ref, ref) + if (fam) + LINK_CHAIN_ELT(user_ref_number, fam->ref, ref); } void family_set_record_id(Gom_ctxt ctxt, char *rin) { struct family *fam = SAFE_CTXT_CAST(family, ctxt); - fam->record_id = strdup(rin); + if (fam) { + fam->record_id = strdup(rin); + if (! fam->record_id) MEMORY_ERROR; + } } void family_set_change_date(Gom_ctxt ctxt, struct change_date* chan) { struct family *fam = SAFE_CTXT_CAST(family, ctxt); - fam->change_date = chan; + if (fam) + fam->change_date = chan; } void family_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct family *obj = SAFE_CTXT_CAST(family, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data); } void family_cleanup(struct family* fam) { - SAFE_FREE(fam->xrefstr); - DESTROY_CHAIN_ELTS(event, fam->event, event_cleanup) - DESTROY_CHAIN_ELTS(xref_list, fam->children, NULL_DESTROY) - SAFE_FREE(fam->nr_of_children); - DESTROY_CHAIN_ELTS(xref_list, fam->submitters, NULL_DESTROY) - DESTROY_CHAIN_ELTS(lds_event, fam->lds_spouse_sealing, lds_event_cleanup) - DESTROY_CHAIN_ELTS(source_citation, fam->citation, citation_cleanup) - DESTROY_CHAIN_ELTS(multimedia_link, fam->mm_link, multimedia_link_cleanup) - DESTROY_CHAIN_ELTS(note_sub, fam->note, note_sub_cleanup) - DESTROY_CHAIN_ELTS(user_ref_number, fam->ref, user_ref_cleanup) - SAFE_FREE(fam->record_id); - change_date_cleanup(fam->change_date); - DESTROY_CHAIN_ELTS(user_data, fam->extra, user_data_cleanup) + if (fam) { + SAFE_FREE(fam->xrefstr); + DESTROY_CHAIN_ELTS(event, fam->event, event_cleanup); + DESTROY_CHAIN_ELTS(xref_list, fam->children, NULL_DESTROY); + SAFE_FREE(fam->nr_of_children); + DESTROY_CHAIN_ELTS(xref_list, fam->submitters, NULL_DESTROY); + DESTROY_CHAIN_ELTS(lds_event, fam->lds_spouse_sealing, lds_event_cleanup); + DESTROY_CHAIN_ELTS(source_citation, fam->citation, citation_cleanup); + DESTROY_CHAIN_ELTS(multimedia_link, fam->mm_link, multimedia_link_cleanup); + DESTROY_CHAIN_ELTS(note_sub, fam->note, note_sub_cleanup); + DESTROY_CHAIN_ELTS(user_ref_number, fam->ref, user_ref_cleanup); + SAFE_FREE(fam->record_id); + change_date_cleanup(fam->change_date); + DESTROY_CHAIN_ELTS(user_data, fam->extra, user_data_cleanup); + } } void families_cleanup() @@ -141,8 +154,11 @@ struct family* gom_get_first_family() struct family* make_family_record(char* xrefstr) { - struct family* fam; + struct family* fam = NULL; MAKE_CHAIN_ELT(family, gom_first_family, fam); - fam->xrefstr = strdup(xrefstr); + if (fam) { + fam->xrefstr = strdup(xrefstr); + if (! fam->xrefstr) MEMORY_ERROR; + } return fam; } diff --git a/gom/family_link.c b/gom/family_link.c index dfffbd5..4c5fa9b 100644 --- a/gom/family_link.c +++ b/gom/family_link.c @@ -34,32 +34,57 @@ Gedcom_ctxt sub_fam_link_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; - struct family_link *link = NULL; + Gom_ctxt result = NULL; - if (ctxt) { - link = (struct family_link *)malloc(sizeof(struct family_link)); - memset (link, 0, sizeof(struct family_link)); - link->family = GEDCOM_XREF_PTR(parsed_value); - - switch (ctxt->ctxt_type) { - case REC_INDI: - individual_add_family_link(ctxt, elt, link); break; - default: - UNEXPECTED_CONTEXT(ctxt->ctxt_type); + if (! ctxt) + NO_CONTEXT; + else { + struct family_link *link + = (struct family_link *)malloc(sizeof(struct family_link)); + if (! link) + MEMORY_ERROR; + else { + memset (link, 0, sizeof(struct family_link)); + link->family = GEDCOM_XREF_PTR(parsed_value); + + switch (ctxt->ctxt_type) { + case REC_INDI: + individual_add_family_link(ctxt, elt, link); break; + default: + UNEXPECTED_CONTEXT(ctxt->ctxt_type); + } + result = MAKE_GOM_CTXT(elt, family_link, link); } } - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, family_link, link); + return (Gedcom_ctxt)result; } Gedcom_ctxt sub_fam_link_pedi_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; - struct family_link *link = SAFE_CTXT_CAST(family_link, ctxt); - struct pedigree *ped; - MAKE_CHAIN_ELT(pedigree, link->pedigree, ped); - ped->pedigree = strdup(GEDCOM_STRING(parsed_value)); - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, pedigree, ped); + Gom_ctxt result = NULL; + + if (! ctxt) + NO_CONTEXT; + else { + struct family_link *link = SAFE_CTXT_CAST(family_link, ctxt); + if (link) { + int err = 0; + struct pedigree *ped = NULL; + MAKE_CHAIN_ELT(pedigree, link->pedigree, ped); + if (ped) { + ped->pedigree = strdup(GEDCOM_STRING(parsed_value)); + if (! ped->pedigree) { + MEMORY_ERROR; + err = 1; + } + } + if (! err) + result = MAKE_GOM_CTXT(elt, pedigree, ped); + } + } + return (Gedcom_ctxt)result; } void family_link_subscribe() @@ -75,13 +100,15 @@ void family_link_subscribe() void family_link_add_note(Gom_ctxt ctxt, struct note_sub* note) { struct family_link *link = SAFE_CTXT_CAST(family_link, ctxt); - LINK_CHAIN_ELT(note_sub, link->note, note) + if (link) + LINK_CHAIN_ELT(note_sub, link->note, note); } void family_link_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct family_link *obj = SAFE_CTXT_CAST(family_link, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data); } void pedigree_cleanup(struct pedigree* ped) @@ -94,8 +121,8 @@ void pedigree_cleanup(struct pedigree* ped) void family_link_cleanup(struct family_link *link) { if (link) { - DESTROY_CHAIN_ELTS(pedigree, link->pedigree, pedigree_cleanup) - DESTROY_CHAIN_ELTS(note_sub, link->note, note_sub_cleanup) - DESTROY_CHAIN_ELTS(user_data, link->extra, user_data_cleanup) + DESTROY_CHAIN_ELTS(pedigree, link->pedigree, pedigree_cleanup); + DESTROY_CHAIN_ELTS(note_sub, link->note, note_sub_cleanup); + DESTROY_CHAIN_ELTS(user_data, link->extra, user_data_cleanup); } } diff --git a/gom/gom.c b/gom/gom.c index a0aa9d6..025541d 100644 --- a/gom/gom.c +++ b/gom/gom.c @@ -145,6 +145,12 @@ void gom_unexpected_context(char* file, int line, OBJ_TYPE found) file, line, found); } +void gom_no_context(char* file, int line) +{ + gedcom_warning(_("Internal error: No context at %s, line %d"), + file, line); +} + void gom_default_callback (Gedcom_elt elt, Gedcom_ctxt parent, int level, char* tag, char* raw_value, int parsed_tag) { @@ -198,10 +204,8 @@ char* concat_strings(NL_TYPE type, char *str1, const char *str2) if (type == WITH_NL) len++; newp = (char*) realloc(str1, len); - if (newp == NULL) { - free (str1); + if (newp == NULL) return NULL; - } wp = newp + len1; str1 = newp; if (type == WITH_NL) diff --git a/gom/gom_internal.h b/gom/gom_internal.h index 71c0bc6..6950b60 100644 --- a/gom/gom_internal.h +++ b/gom/gom_internal.h @@ -48,6 +48,12 @@ typedef enum { T_association, T_source_event, T_source_description } OBJ_TYPE; +/* Assumptions for context: + - In case of error, NULL is passed as context + - If not NULL, the ctxt_ptr of the context is not NULL also + - UNEXPECTED_CONTEXT is not treated as an error, but as a warning +*/ + struct Gom_ctxt_struct { int ctxt_type; OBJ_TYPE obj_type; @@ -59,6 +65,7 @@ typedef struct Gom_ctxt_struct *Gom_ctxt; Gom_ctxt make_gom_ctxt(int ctxt_type, OBJ_TYPE obj_type, void *ctxt_ptr); void destroy_gom_ctxt(Gom_ctxt ctxt); void gom_cast_error(char* file, int line, OBJ_TYPE expected, OBJ_TYPE found); +void gom_no_context(char* file, int line); void gom_unexpected_context(char* file, int line, OBJ_TYPE found); #define MAKE_GOM_CTXT(CTXT_TYPE, STRUCTTYPE, CTXT_PTR) \ @@ -79,6 +86,9 @@ void gom_unexpected_context(char* file, int line, OBJ_TYPE found); #define UNEXPECTED_CONTEXT(CTXT_TYPE) \ gom_unexpected_context(__FILE__, __LINE__, CTXT_TYPE) +#define NO_CONTEXT \ + gom_no_context(__FILE__, __LINE__) + void gom_mem_error(char *filename, int line); #define MEMORY_ERROR gom_mem_error(__FILE__, __LINE__) @@ -153,7 +163,10 @@ void NULL_DESTROY(void* anything); struct xref_value* xr = GEDCOM_XREF_PTR(xref); \ if (! xr->object) \ xr->object = (Gedcom_ctxt) FUNC(xr->string); \ - return (Gedcom_ctxt) MAKE_GOM_CTXT(rec, STRUCTTYPE, xr->object); \ + if (xr->object) \ + return (Gedcom_ctxt) MAKE_GOM_CTXT(rec, STRUCTTYPE, xr->object); \ + else \ + return NULL; \ } #define GET_REC_BY_XREF(STRUCTTYPE,XREF_TYPE,FUNC_NAME) \ @@ -169,83 +182,123 @@ void NULL_DESTROY(void* anything); #define STRING_CB(STRUCTTYPE,CB_NAME,FIELD) \ Gedcom_ctxt CB_NAME(_ELT_PARAMS_) \ { \ - char *str = GEDCOM_STRING(parsed_value); \ - struct STRUCTTYPE *obj \ - = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \ - if (obj) { \ - obj->FIELD = strdup(str); \ - if (! obj->FIELD) { \ - MEMORY_ERROR; \ - return NULL; \ + Gom_ctxt result = NULL; \ + if (! parent) \ + NO_CONTEXT; \ + else { \ + struct STRUCTTYPE *obj \ + = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \ + if (obj) { \ + char *str = GEDCOM_STRING(parsed_value); \ + obj->FIELD = strdup(str); \ + if (! obj->FIELD) \ + MEMORY_ERROR; \ + else \ + result = MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \ } \ } \ - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \ + return (Gedcom_ctxt)result; \ } #define DATE_CB(STRUCTTYPE,CB_NAME,FIELD) \ Gedcom_ctxt CB_NAME(_ELT_PARAMS_) \ { \ - struct date_value dv = GEDCOM_DATE(parsed_value); \ - struct STRUCTTYPE *obj \ - = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \ - if (obj) { \ - obj->FIELD = dup_date(dv); \ - if (! obj->FIELD) { \ - MEMORY_ERROR; \ - return NULL; \ + Gom_ctxt result = NULL; \ + if (! parent) \ + NO_CONTEXT; \ + else { \ + struct STRUCTTYPE *obj \ + = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \ + if (obj) { \ + struct date_value dv = GEDCOM_DATE(parsed_value); \ + obj->FIELD = dup_date(dv); \ + if (! obj->FIELD) \ + MEMORY_ERROR; \ + else \ + result = MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \ } \ } \ - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \ + return (Gedcom_ctxt)result; \ } #define AGE_CB(STRUCTTYPE,CB_NAME,FIELD) \ Gedcom_ctxt CB_NAME(_ELT_PARAMS_) \ { \ - struct age_value age = GEDCOM_AGE(parsed_value); \ - struct STRUCTTYPE *obj \ - = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \ - if (obj) { \ - obj->FIELD = dup_age(age); \ - if (! obj->FIELD) { \ - MEMORY_ERROR; \ - return NULL; \ + Gom_ctxt result = NULL; \ + if (! parent) \ + NO_CONTEXT; \ + else { \ + struct STRUCTTYPE *obj \ + = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \ + if (obj) { \ + struct age_value age = GEDCOM_AGE(parsed_value); \ + obj->FIELD = dup_age(age); \ + if (! obj->FIELD) \ + MEMORY_ERROR; \ + else \ + result = MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \ } \ } \ - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \ + return (Gedcom_ctxt)result; \ } #define XREF_CB(STRUCTTYPE,CB_NAME,FIELD,FUNC) \ Gedcom_ctxt CB_NAME(_ELT_PARAMS_) \ { \ - struct xref_value *xr = GEDCOM_XREF_PTR(parsed_value); \ - struct STRUCTTYPE *obj \ - = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \ - if (! xr->object) \ - xr->object = (Gedcom_ctxt) FUNC(xr->string); \ - if (obj) obj->FIELD = xr; \ - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \ + Gom_ctxt result = NULL; \ + if (! parent) \ + NO_CONTEXT; \ + else { \ + struct STRUCTTYPE *obj \ + = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \ + struct xref_value *xr = GEDCOM_XREF_PTR(parsed_value); \ + if (! xr->object) \ + xr->object = (Gedcom_ctxt) FUNC(xr->string); \ + if (obj) { \ + obj->FIELD = xr; \ + result = MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \ + } \ + } \ + return (Gedcom_ctxt)result; \ } #define XREF_LIST_CB(STRUCTTYPE,CB_NAME,FIELD,FUNC) \ Gedcom_ctxt CB_NAME(_ELT_PARAMS_) \ { \ - struct xref_value *xr = GEDCOM_XREF_PTR(parsed_value); \ - struct STRUCTTYPE *obj \ - = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \ - struct xref_list *xrl; \ - if (! xr->object) \ - xr->object = (Gedcom_ctxt) FUNC(xr->string); \ - MAKE_CHAIN_ELT(xref_list, obj->FIELD, xrl); \ - xrl->xref = xr; \ - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \ + Gom_ctxt result = NULL; \ + if (! parent) \ + NO_CONTEXT; \ + else { \ + struct STRUCTTYPE *obj \ + = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \ + struct xref_value *xr = GEDCOM_XREF_PTR(parsed_value); \ + struct xref_list *xrl; \ + if (! xr->object) \ + xr->object = (Gedcom_ctxt) FUNC(xr->string); \ + if (obj) { \ + MAKE_CHAIN_ELT(xref_list, obj->FIELD, xrl); \ + if (xrl) { \ + xrl->xref = xr; \ + result = MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \ + } \ + } \ + } \ + return (Gedcom_ctxt)result; \ } #define NULL_CB(STRUCTTYPE,CB_NAME) \ Gedcom_ctxt CB_NAME(_ELT_PARAMS_) \ { \ - struct STRUCTTYPE *obj \ - = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \ - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \ + Gom_ctxt result = NULL; \ + if (! parent) \ + NO_CONTEXT; \ + else { \ + struct STRUCTTYPE *obj \ + = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \ + if (obj) \ + result = MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \ + } \ + return (Gedcom_ctxt)result; \ } #endif /* __GOM_INTERNAL_H */ diff --git a/gom/header.c b/gom/header.c index ddc2589..1422ae2 100644 --- a/gom/header.c +++ b/gom/header.c @@ -65,31 +65,41 @@ STRING_CB(header, head_note_start, note) void header_add_address(Gom_ctxt ctxt, struct address* addr) { struct header *head = SAFE_CTXT_CAST(header, ctxt); - head->source.corporation.address = addr; + if (head) + head->source.corporation.address = addr; } void header_add_phone(Gom_ctxt ctxt, char* phone) { struct header *head = SAFE_CTXT_CAST(header, ctxt); - struct header_corporation *corp = &(head->source.corporation); - if (! corp->phone[0]) - corp->phone[0] = strdup(phone); - else if (! corp->phone[1]) - corp->phone[1] = strdup(phone); - else if (! corp->phone[2]) - corp->phone[2] = strdup(phone); + if (head) { + struct header_corporation *corp = &(head->source.corporation); + int i = 0; + while (i<2 && corp->phone[i]) i++; + if (! corp->phone[i]) { + corp->phone[i] = strdup(phone); + if (! corp->phone[i]) MEMORY_ERROR; + } + } } void header_add_to_note(NL_TYPE type, Gom_ctxt ctxt, char* str) { struct header *head = SAFE_CTXT_CAST(header, ctxt); - head->note = concat_strings (type, head->note, str); + if (head) { + char *newvalue = concat_strings(type, head->note, str); + if (newvalue) + head->note = newvalue; + else + MEMORY_ERROR; + } } void header_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct header *head = SAFE_CTXT_CAST(header, ctxt); - LINK_CHAIN_ELT(user_data, head->extra, data) + if (head) + LINK_CHAIN_ELT(user_data, head->extra, data); } void header_subscribe() @@ -156,7 +166,7 @@ void header_cleanup() SAFE_FREE(gom_header.language); SAFE_FREE(gom_header.place_hierarchy); SAFE_FREE(gom_header.note); - DESTROY_CHAIN_ELTS(user_data, gom_header.extra, user_data_cleanup) + DESTROY_CHAIN_ELTS(user_data, gom_header.extra, user_data_cleanup); } struct header* gom_get_header() diff --git a/gom/individual.c b/gom/individual.c index df279d9..4c7e860 100644 --- a/gom/individual.c +++ b/gom/individual.c @@ -71,117 +71,136 @@ void individual_subscribe() void individual_add_event(Gom_ctxt ctxt, struct event* evt) { struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt); - LINK_CHAIN_ELT(event, indiv->event, evt) + if (indiv) + LINK_CHAIN_ELT(event, indiv->event, evt); } void individual_add_attribute(Gom_ctxt ctxt, struct event* evt) { struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt); - LINK_CHAIN_ELT(event, indiv->attribute, evt) + if (indiv) + LINK_CHAIN_ELT(event, indiv->attribute, evt); } void individual_add_name(Gom_ctxt ctxt, struct personal_name* name) { struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt); - LINK_CHAIN_ELT(personal_name, indiv->name, name) + if (indiv) + LINK_CHAIN_ELT(personal_name, indiv->name, name); } void individual_add_lio(Gom_ctxt ctxt, struct lds_event* evt) { struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt); - LINK_CHAIN_ELT(lds_event, indiv->lds_individual_ordinance, evt) + if (indiv) + LINK_CHAIN_ELT(lds_event, indiv->lds_individual_ordinance, evt); } void individual_add_family_link(Gom_ctxt ctxt, int ctxt_type, struct family_link* link) { struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt); - switch (ctxt_type) { - case ELT_SUB_FAMC: - LINK_CHAIN_ELT(family_link, indiv->child_to_family, link) - break; - case ELT_SUB_FAMS: - LINK_CHAIN_ELT(family_link, indiv->spouse_to_family, link) - break; - default: - UNEXPECTED_CONTEXT(ctxt_type); + if (indiv) { + switch (ctxt_type) { + case ELT_SUB_FAMC: + LINK_CHAIN_ELT(family_link, indiv->child_to_family, link); + break; + case ELT_SUB_FAMS: + LINK_CHAIN_ELT(family_link, indiv->spouse_to_family, link); + break; + default: + UNEXPECTED_CONTEXT(ctxt_type); + } } } void individual_add_association(Gom_ctxt ctxt, struct association* assoc) { struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt); - LINK_CHAIN_ELT(association, indiv->association, assoc) + if (indiv) + LINK_CHAIN_ELT(association, indiv->association, assoc); } void individual_add_citation(Gom_ctxt ctxt, struct source_citation* cit) { struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt); - LINK_CHAIN_ELT(source_citation, indiv->citation, cit) + if (indiv) + LINK_CHAIN_ELT(source_citation, indiv->citation, cit); } void individual_add_mm_link(Gom_ctxt ctxt, struct multimedia_link* link) { struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt); - LINK_CHAIN_ELT(multimedia_link, indiv->mm_link, link) + if (indiv) + LINK_CHAIN_ELT(multimedia_link, indiv->mm_link, link); } void individual_add_note(Gom_ctxt ctxt, struct note_sub* note) { struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt); - LINK_CHAIN_ELT(note_sub, indiv->note, note) + if (indiv) + LINK_CHAIN_ELT(note_sub, indiv->note, note); } void individual_add_user_ref(Gom_ctxt ctxt, struct user_ref_number* ref) { struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt); - LINK_CHAIN_ELT(user_ref_number, indiv->ref, ref) + if (indiv) + LINK_CHAIN_ELT(user_ref_number, indiv->ref, ref); } void individual_set_record_id(Gom_ctxt ctxt, char *rin) { struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt); - indiv->record_id = strdup(rin); + if (indiv) { + indiv->record_id = strdup(rin); + if (! indiv->record_id) MEMORY_ERROR; + } } void individual_set_change_date(Gom_ctxt ctxt, struct change_date* chan) { struct individual *indiv = SAFE_CTXT_CAST(individual, ctxt); - indiv->change_date = chan; + if (indiv) + indiv->change_date = chan; } void individual_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct individual *obj = SAFE_CTXT_CAST(individual, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data); } void individual_cleanup(struct individual* indiv) { - SAFE_FREE(indiv->xrefstr); - SAFE_FREE(indiv->restriction_notice); - DESTROY_CHAIN_ELTS(personal_name, indiv->name, name_cleanup) - SAFE_FREE(indiv->sex); - DESTROY_CHAIN_ELTS(event, indiv->event, event_cleanup) - DESTROY_CHAIN_ELTS(event, indiv->attribute, event_cleanup) - DESTROY_CHAIN_ELTS(lds_event, indiv->lds_individual_ordinance, - lds_event_cleanup) - DESTROY_CHAIN_ELTS(family_link, indiv->child_to_family, family_link_cleanup) - DESTROY_CHAIN_ELTS(family_link, indiv->spouse_to_family, family_link_cleanup) - DESTROY_CHAIN_ELTS(xref_list, indiv->submitters, NULL_DESTROY) - DESTROY_CHAIN_ELTS(association, indiv->association, association_cleanup) - DESTROY_CHAIN_ELTS(xref_list, indiv->alias, NULL_DESTROY) - DESTROY_CHAIN_ELTS(xref_list, indiv->ancestor_interest, NULL_DESTROY) - DESTROY_CHAIN_ELTS(xref_list, indiv->descendant_interest, NULL_DESTROY) - DESTROY_CHAIN_ELTS(source_citation, indiv->citation, citation_cleanup) - DESTROY_CHAIN_ELTS(multimedia_link, indiv->mm_link, multimedia_link_cleanup) - DESTROY_CHAIN_ELTS(note_sub, indiv->note, note_sub_cleanup) - SAFE_FREE(indiv->record_file_nr); - SAFE_FREE(indiv->ancestral_file_nr); - DESTROY_CHAIN_ELTS(user_ref_number, indiv->ref, user_ref_cleanup) - SAFE_FREE(indiv->record_id); - change_date_cleanup(indiv->change_date); - DESTROY_CHAIN_ELTS(user_data, indiv->extra, user_data_cleanup) + if (indiv) { + SAFE_FREE(indiv->xrefstr); + SAFE_FREE(indiv->restriction_notice); + DESTROY_CHAIN_ELTS(personal_name, indiv->name, name_cleanup); + SAFE_FREE(indiv->sex); + DESTROY_CHAIN_ELTS(event, indiv->event, event_cleanup); + DESTROY_CHAIN_ELTS(event, indiv->attribute, event_cleanup); + DESTROY_CHAIN_ELTS(lds_event, indiv->lds_individual_ordinance, + lds_event_cleanup); + DESTROY_CHAIN_ELTS(family_link,indiv->child_to_family,family_link_cleanup); + DESTROY_CHAIN_ELTS(family_link,indiv->spouse_to_family, + family_link_cleanup); + DESTROY_CHAIN_ELTS(xref_list, indiv->submitters, NULL_DESTROY); + DESTROY_CHAIN_ELTS(association, indiv->association, association_cleanup); + DESTROY_CHAIN_ELTS(xref_list, indiv->alias, NULL_DESTROY); + DESTROY_CHAIN_ELTS(xref_list, indiv->ancestor_interest, NULL_DESTROY); + DESTROY_CHAIN_ELTS(xref_list, indiv->descendant_interest, NULL_DESTROY); + DESTROY_CHAIN_ELTS(source_citation, indiv->citation, citation_cleanup); + DESTROY_CHAIN_ELTS(multimedia_link,indiv->mm_link,multimedia_link_cleanup); + DESTROY_CHAIN_ELTS(note_sub, indiv->note, note_sub_cleanup); + SAFE_FREE(indiv->record_file_nr); + SAFE_FREE(indiv->ancestral_file_nr); + DESTROY_CHAIN_ELTS(user_ref_number, indiv->ref, user_ref_cleanup); + SAFE_FREE(indiv->record_id); + change_date_cleanup(indiv->change_date); + DESTROY_CHAIN_ELTS(user_data, indiv->extra, user_data_cleanup); + } } void individuals_cleanup() @@ -196,8 +215,11 @@ struct individual* gom_get_first_individual() struct individual* make_individual_record(char* xrefstr) { - struct individual* indiv; + struct individual* indiv = NULL; MAKE_CHAIN_ELT(individual, gom_first_individual, indiv); - indiv->xrefstr = strdup(xrefstr); + if (indiv) { + indiv->xrefstr = strdup(xrefstr); + if (! indiv->xrefstr) MEMORY_ERROR; + } return indiv; } diff --git a/gom/lds_event.c b/gom/lds_event.c index 578c0c8..5abaa2e 100644 --- a/gom/lds_event.c +++ b/gom/lds_event.c @@ -36,23 +36,31 @@ Gedcom_ctxt sub_lds_event_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; - struct lds_event *lds_evt = NULL; + Gom_ctxt result = NULL; - if (ctxt) { - lds_evt = (struct lds_event*)malloc(sizeof(struct lds_event)); - memset (lds_evt, 0, sizeof(struct lds_event)); - - switch (ctxt->ctxt_type) { - case REC_FAM: - family_add_lss(ctxt, lds_evt); break; - case REC_INDI: - individual_add_lio(ctxt, lds_evt); break; - default: - UNEXPECTED_CONTEXT(ctxt->ctxt_type); + if (! ctxt) + NO_CONTEXT; + else { + struct lds_event *lds_evt + = (struct lds_event*)malloc(sizeof(struct lds_event)); + if (! lds_evt) + MEMORY_ERROR; + else { + memset (lds_evt, 0, sizeof(struct lds_event)); + + switch (ctxt->ctxt_type) { + case REC_FAM: + family_add_lss(ctxt, lds_evt); break; + case REC_INDI: + individual_add_lio(ctxt, lds_evt); break; + default: + UNEXPECTED_CONTEXT(ctxt->ctxt_type); + } + result = MAKE_GOM_CTXT(elt, lds_event, lds_evt); } } - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, lds_event, lds_evt); + return (Gedcom_ctxt)result; } STRING_CB(lds_event, sub_lds_event_stat_start, date_status) @@ -92,19 +100,22 @@ void lds_event_subscribe() void lds_event_add_note(Gom_ctxt ctxt, struct note_sub* note) { struct lds_event *lds = SAFE_CTXT_CAST(lds_event, ctxt); - LINK_CHAIN_ELT(note_sub, lds->note, note) + if (lds) + LINK_CHAIN_ELT(note_sub, lds->note, note); } void lds_event_add_citation(Gom_ctxt ctxt, struct source_citation* cit) { struct lds_event *lds = SAFE_CTXT_CAST(lds_event, ctxt); - LINK_CHAIN_ELT(source_citation, lds->citation, cit) + if (lds) + LINK_CHAIN_ELT(source_citation, lds->citation, cit); } void lds_event_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct lds_event *obj = SAFE_CTXT_CAST(lds_event, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data); } void lds_event_cleanup(struct lds_event* lds) @@ -114,8 +125,8 @@ void lds_event_cleanup(struct lds_event* lds) SAFE_FREE(lds->date); SAFE_FREE(lds->temple_code); SAFE_FREE(lds->place_living_ordinance); - DESTROY_CHAIN_ELTS(source_citation, lds->citation, citation_cleanup) - DESTROY_CHAIN_ELTS(note_sub, lds->note, note_sub_cleanup) - DESTROY_CHAIN_ELTS(user_data, lds->extra, user_data_cleanup) + DESTROY_CHAIN_ELTS(source_citation, lds->citation, citation_cleanup); + DESTROY_CHAIN_ELTS(note_sub, lds->note, note_sub_cleanup); + DESTROY_CHAIN_ELTS(user_data, lds->extra, user_data_cleanup); } } diff --git a/gom/multimedia.c b/gom/multimedia.c index 43dd6b7..4faaf1f 100644 --- a/gom/multimedia.c +++ b/gom/multimedia.c @@ -44,13 +44,35 @@ XREF_CB(multimedia, obje_obje_start, continued, make_multimedia_record) Gedcom_ctxt obje_blob_cont_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; - struct multimedia *obj = SAFE_CTXT_CAST(multimedia, ctxt); - char *str = GEDCOM_STRING(parsed_value); - if (obj->data) - obj->data = concat_strings (WITHOUT_NL, obj->data, str); - else - obj->data = strdup(str); - return (Gedcom_ctxt) make_gom_ctxt(elt, ctxt->obj_type, ctxt->ctxt_ptr); + Gom_ctxt result = NULL; + + if (! ctxt) + NO_CONTEXT; + else { + struct multimedia *obj = SAFE_CTXT_CAST(multimedia, ctxt); + if (obj) { + char *str = GEDCOM_STRING(parsed_value); + if (obj->data) { + char *newvalue = concat_strings (WITHOUT_NL, obj->data, str); + if (newvalue) + obj->data = newvalue; + else { + free(obj->data); + obj->data = NULL; + } + } + else + obj->data = strdup(str); + + if (! obj->data) { + MEMORY_ERROR; + free(obj); + } + else + result = make_gom_ctxt(elt, ctxt->obj_type, ctxt->ctxt_ptr); + } + } + return (Gedcom_ctxt)result; } void multimedia_subscribe() @@ -67,44 +89,53 @@ void multimedia_subscribe() void multimedia_add_note(Gom_ctxt ctxt, struct note_sub* note) { struct multimedia* obj = SAFE_CTXT_CAST(multimedia, ctxt); - LINK_CHAIN_ELT(note_sub, obj->note, note) + if (obj) + LINK_CHAIN_ELT(note_sub, obj->note, note); } void multimedia_add_user_ref(Gom_ctxt ctxt, struct user_ref_number* ref) { struct multimedia *obj = SAFE_CTXT_CAST(multimedia, ctxt); - LINK_CHAIN_ELT(user_ref_number, obj->ref, ref) + if (obj) + LINK_CHAIN_ELT(user_ref_number, obj->ref, ref); } void multimedia_set_record_id(Gom_ctxt ctxt, char *rin) { struct multimedia *obj = SAFE_CTXT_CAST(multimedia, ctxt); - obj->record_id = strdup(rin); + if (obj) { + obj->record_id = strdup(rin); + if (! obj->record_id) MEMORY_ERROR; + } } void multimedia_set_change_date(Gom_ctxt ctxt, struct change_date* chan) { struct multimedia *obj = SAFE_CTXT_CAST(multimedia, ctxt); - obj->change_date = chan; + if (obj) + obj->change_date = chan; } void multimedia_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct multimedia *obj = SAFE_CTXT_CAST(multimedia, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data); } void multimedia_cleanup(struct multimedia* obj) { - SAFE_FREE(obj->xrefstr); - SAFE_FREE(obj->form); - SAFE_FREE(obj->title); - DESTROY_CHAIN_ELTS(note_sub, obj->note, note_sub_cleanup) - SAFE_FREE(obj->data); - DESTROY_CHAIN_ELTS(user_ref_number, obj->ref, user_ref_cleanup) - SAFE_FREE(obj->record_id); - change_date_cleanup(obj->change_date); - DESTROY_CHAIN_ELTS(user_data, obj->extra, user_data_cleanup) + if (obj) { + SAFE_FREE(obj->xrefstr); + SAFE_FREE(obj->form); + SAFE_FREE(obj->title); + DESTROY_CHAIN_ELTS(note_sub, obj->note, note_sub_cleanup); + SAFE_FREE(obj->data); + DESTROY_CHAIN_ELTS(user_ref_number, obj->ref, user_ref_cleanup); + SAFE_FREE(obj->record_id); + change_date_cleanup(obj->change_date); + DESTROY_CHAIN_ELTS(user_data, obj->extra, user_data_cleanup); + } } void multimedias_cleanup() @@ -119,8 +150,11 @@ struct multimedia* gom_get_first_multimedia() struct multimedia* make_multimedia_record(char* xrefstr) { - struct multimedia* multi; + struct multimedia* multi = NULL; MAKE_CHAIN_ELT(multimedia, gom_first_multimedia, multi); - multi->xrefstr = strdup(xrefstr); + if (multi) { + multi->xrefstr = strdup(xrefstr); + if (! multi->xrefstr) MEMORY_ERROR; + } return multi; } diff --git a/gom/multimedia_link.c b/gom/multimedia_link.c index d16b2dc..2b5a1f1 100644 --- a/gom/multimedia_link.c +++ b/gom/multimedia_link.c @@ -39,40 +39,48 @@ Gedcom_ctxt sub_obje_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; - struct multimedia_link *mm = NULL; + Gom_ctxt result = NULL; - if (ctxt) { - mm = (struct multimedia_link *)malloc(sizeof(struct multimedia_link)); - memset (mm, 0, sizeof(struct multimedia_link)); - if (GEDCOM_IS_XREF_PTR(parsed_value)) - mm->reference = GEDCOM_XREF_PTR(parsed_value); - - switch (ctxt->ctxt_type) { - case ELT_SUB_FAM_EVT: - case ELT_SUB_FAM_EVT_EVEN: - case ELT_SUB_INDIV_ATTR: - case ELT_SUB_INDIV_RESI: - case ELT_SUB_INDIV_BIRT: - case ELT_SUB_INDIV_GEN: - case ELT_SUB_INDIV_ADOP: - case ELT_SUB_INDIV_EVEN: - event_add_mm_link(ctxt, mm); break; - case ELT_SUB_SOUR: - citation_add_mm_link(ctxt, mm); break; - case REC_FAM: - family_add_mm_link(ctxt, mm); break; - case REC_INDI: - individual_add_mm_link(ctxt, mm); break; - case REC_SOUR: - source_add_mm_link(ctxt, mm); break; - case REC_SUBM: - submitter_add_mm_link(ctxt, mm); break; - default: - UNEXPECTED_CONTEXT(ctxt->ctxt_type); + if (! ctxt) + NO_CONTEXT; + else { + struct multimedia_link *mm + = (struct multimedia_link *)malloc(sizeof(struct multimedia_link)); + if (! mm) + MEMORY_ERROR; + else { + memset (mm, 0, sizeof(struct multimedia_link)); + if (GEDCOM_IS_XREF_PTR(parsed_value)) + mm->reference = GEDCOM_XREF_PTR(parsed_value); + + switch (ctxt->ctxt_type) { + case ELT_SUB_FAM_EVT: + case ELT_SUB_FAM_EVT_EVEN: + case ELT_SUB_INDIV_ATTR: + case ELT_SUB_INDIV_RESI: + case ELT_SUB_INDIV_BIRT: + case ELT_SUB_INDIV_GEN: + case ELT_SUB_INDIV_ADOP: + case ELT_SUB_INDIV_EVEN: + event_add_mm_link(ctxt, mm); break; + case ELT_SUB_SOUR: + citation_add_mm_link(ctxt, mm); break; + case REC_FAM: + family_add_mm_link(ctxt, mm); break; + case REC_INDI: + individual_add_mm_link(ctxt, mm); break; + case REC_SOUR: + source_add_mm_link(ctxt, mm); break; + case REC_SUBM: + submitter_add_mm_link(ctxt, mm); break; + default: + UNEXPECTED_CONTEXT(ctxt->ctxt_type); + } + result = MAKE_GOM_CTXT(elt, multimedia_link, mm); } } - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, multimedia_link, mm); + return (Gedcom_ctxt)result; } STRING_CB(multimedia_link, sub_obje_form_start, form) @@ -94,13 +102,15 @@ void multimedia_link_subscribe() void multimedia_link_add_note(Gom_ctxt ctxt, struct note_sub* note) { struct multimedia_link *mm = SAFE_CTXT_CAST(multimedia_link, ctxt); - LINK_CHAIN_ELT(note_sub, mm->note, note) + if (mm) + LINK_CHAIN_ELT(note_sub, mm->note, note); } void multimedia_link_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct multimedia_link *obj = SAFE_CTXT_CAST(multimedia_link, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data); } void multimedia_link_cleanup(struct multimedia_link* mm) @@ -109,7 +119,7 @@ void multimedia_link_cleanup(struct multimedia_link* mm) SAFE_FREE(mm->form); SAFE_FREE(mm->title); SAFE_FREE(mm->file); - DESTROY_CHAIN_ELTS(note_sub, mm->note, note_sub_cleanup) - DESTROY_CHAIN_ELTS(user_data, mm->extra, user_data_cleanup) + DESTROY_CHAIN_ELTS(note_sub, mm->note, note_sub_cleanup); + DESTROY_CHAIN_ELTS(user_data, mm->extra, user_data_cleanup); } } diff --git a/gom/note.c b/gom/note.c index 46e88e3..4443da2 100644 --- a/gom/note.c +++ b/gom/note.c @@ -39,14 +39,21 @@ struct note* gom_first_note = NULL; Gedcom_ctxt note_start(_REC_PARAMS_) { + Gom_ctxt result = NULL; struct xref_value* xr = GEDCOM_XREF_PTR(xref); struct note* note = (struct note*) xr->object; - if (! xr->object) { + if (! note) { note = make_note_record(xr->string); xr->object = (Gedcom_ctxt) note; } - note->text = strdup(GEDCOM_STRING(parsed_value)); - return (Gedcom_ctxt) MAKE_GOM_CTXT(rec, note, xr->object); + if (note) { + note->text = strdup(GEDCOM_STRING(parsed_value)); + if (! note->text) + MEMORY_ERROR; + else + result = MAKE_GOM_CTXT(rec, note, xr->object); + } + return (Gedcom_ctxt)result; } GET_REC_BY_XREF(note, XREF_NOTE, gom_get_note_by_xref) @@ -54,8 +61,11 @@ GET_REC_BY_XREF(note, XREF_NOTE, gom_get_note_by_xref) Gedcom_ctxt sub_cont_conc_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; + Gom_ctxt result = NULL; - if (ctxt) { + if (! ctxt) + NO_CONTEXT; + else { char *str = GEDCOM_STRING(parsed_value); NL_TYPE type = (elt == ELT_SUB_CONT ? WITH_NL : WITHOUT_NL); switch (ctxt->ctxt_type) { @@ -77,11 +87,9 @@ Gedcom_ctxt sub_cont_conc_start(_ELT_PARAMS_) default: UNEXPECTED_CONTEXT(ctxt->ctxt_type); } - return (Gedcom_ctxt) make_gom_ctxt(elt, ctxt->obj_type, ctxt->ctxt_ptr); - } - else { - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, NULL, NULL); + result = make_gom_ctxt(elt, ctxt->obj_type, ctxt->ctxt_ptr); } + return (Gedcom_ctxt)result; } void note_subscribe() @@ -94,48 +102,63 @@ void note_subscribe() void note_add_to_note(NL_TYPE type, Gom_ctxt ctxt, char* str) { struct note *note = SAFE_CTXT_CAST(note, ctxt); - note->text = concat_strings (type, note->text, str); + if (note) { + char *newvalue = concat_strings (type, note->text, str); + if (newvalue) + note->text = newvalue; + else + MEMORY_ERROR; + } } void note_add_citation(Gom_ctxt ctxt, struct source_citation* cit) { struct note *note = SAFE_CTXT_CAST(note, ctxt); - LINK_CHAIN_ELT(source_citation, note->citation, cit) + if (note) + LINK_CHAIN_ELT(source_citation, note->citation, cit); } void note_add_user_ref(Gom_ctxt ctxt, struct user_ref_number* ref) { struct note *note = SAFE_CTXT_CAST(note, ctxt); - LINK_CHAIN_ELT(user_ref_number, note->ref, ref) + if (note) + LINK_CHAIN_ELT(user_ref_number, note->ref, ref); } void note_set_record_id(Gom_ctxt ctxt, char *rin) { struct note *note = SAFE_CTXT_CAST(note, ctxt); - note->record_id = strdup(rin); + if (note) { + note->record_id = strdup(rin); + if (! note->record_id) MEMORY_ERROR; + } } void note_set_change_date(Gom_ctxt ctxt, struct change_date* chan) { struct note *note = SAFE_CTXT_CAST(note, ctxt); - note->change_date = chan; + if (note) + note->change_date = chan; } void note_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct note *obj = SAFE_CTXT_CAST(note, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data); } void note_cleanup(struct note* note) { - SAFE_FREE(note->xrefstr); - SAFE_FREE(note->text); - DESTROY_CHAIN_ELTS(source_citation, note->citation, citation_cleanup) - DESTROY_CHAIN_ELTS(user_ref_number, note->ref, user_ref_cleanup) - SAFE_FREE(note->record_id); - change_date_cleanup(note->change_date); - DESTROY_CHAIN_ELTS(user_data, note->extra, user_data_cleanup) + if (note) { + SAFE_FREE(note->xrefstr); + SAFE_FREE(note->text); + DESTROY_CHAIN_ELTS(source_citation, note->citation, citation_cleanup); + DESTROY_CHAIN_ELTS(user_ref_number, note->ref, user_ref_cleanup); + SAFE_FREE(note->record_id); + change_date_cleanup(note->change_date); + DESTROY_CHAIN_ELTS(user_data, note->extra, user_data_cleanup); + } } void notes_cleanup() @@ -150,8 +173,11 @@ struct note* gom_get_first_note() struct note* make_note_record(char* xrefstr) { - struct note* note; + struct note* note = NULL; MAKE_CHAIN_ELT(note, gom_first_note, note); - note->xrefstr = strdup(xrefstr); + if (note) { + note->xrefstr = strdup(xrefstr); + if (! note->xrefstr) MEMORY_ERROR; + } return note; } diff --git a/gom/note_sub.c b/gom/note_sub.c index 4f3aaec..008b9d0 100644 --- a/gom/note_sub.c +++ b/gom/note_sub.c @@ -47,65 +47,81 @@ Gedcom_ctxt sub_note_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; - struct note_sub *note = NULL; + Gom_ctxt result = NULL; - if (ctxt) { - note = (struct note_sub *)malloc(sizeof(struct note_sub)); - memset (note, 0, sizeof(struct note_sub)); - if (GEDCOM_IS_STRING(parsed_value)) - note->text = strdup(GEDCOM_STRING(parsed_value)); - else if (GEDCOM_IS_XREF_PTR(parsed_value)) - note->reference = GEDCOM_XREF_PTR(parsed_value); + if (! ctxt) + NO_CONTEXT; + else { + struct note_sub *note = (struct note_sub *)malloc(sizeof(struct note_sub)); + if (! note) + MEMORY_ERROR; + else { + int err = 0; + memset (note, 0, sizeof(struct note_sub)); + if (GEDCOM_IS_STRING(parsed_value)) { + note->text = strdup(GEDCOM_STRING(parsed_value)); + if (! note->text) { + MEMORY_ERROR; + free(note); + err = 1; + } + } + else if (GEDCOM_IS_XREF_PTR(parsed_value)) + note->reference = GEDCOM_XREF_PTR(parsed_value); - switch (ctxt->ctxt_type) { - case ELT_SUB_PLAC: - place_add_note(ctxt, note); break; - case ELT_SUB_FAM_EVT: - case ELT_SUB_FAM_EVT_EVEN: - case ELT_SUB_INDIV_ATTR: - case ELT_SUB_INDIV_RESI: - case ELT_SUB_INDIV_BIRT: - case ELT_SUB_INDIV_GEN: - case ELT_SUB_INDIV_ADOP: - case ELT_SUB_INDIV_EVEN: - event_add_note(ctxt, note); break; - case ELT_SUB_SOUR: - citation_add_note(ctxt, note); break; - case ELT_SUB_MULTIM_OBJE: - multimedia_link_add_note(ctxt, note); break; - case ELT_SUB_LSS_SLGS: - case ELT_SUB_LIO_BAPL: - case ELT_SUB_LIO_SLGC: - lds_event_add_note(ctxt, note); break; - case REC_FAM: - family_add_note(ctxt, note); break; - case ELT_SUB_CHAN: - change_date_add_note(ctxt, note); break; - case ELT_SUB_PERS_NAME: - name_add_note(ctxt, note); break; - case ELT_SUB_FAMC: - case ELT_SUB_FAMS: - family_link_add_note(ctxt, note); break; - case ELT_SUB_ASSO: - association_add_note(ctxt, note); break; - case REC_INDI: - individual_add_note(ctxt, note); break; - case REC_OBJE: - multimedia_add_note(ctxt, note); break; - case REC_REPO: - repository_add_note(ctxt, note); break; - case ELT_SOUR_DATA: - source_add_note_to_data(ctxt, note); break; - case ELT_SUB_REPO: - source_add_note_to_repo(ctxt, note); break; - case REC_SOUR: - source_add_note(ctxt, note); break; - default: - UNEXPECTED_CONTEXT(ctxt->ctxt_type); + if (! err) { + switch (ctxt->ctxt_type) { + case ELT_SUB_PLAC: + place_add_note(ctxt, note); break; + case ELT_SUB_FAM_EVT: + case ELT_SUB_FAM_EVT_EVEN: + case ELT_SUB_INDIV_ATTR: + case ELT_SUB_INDIV_RESI: + case ELT_SUB_INDIV_BIRT: + case ELT_SUB_INDIV_GEN: + case ELT_SUB_INDIV_ADOP: + case ELT_SUB_INDIV_EVEN: + event_add_note(ctxt, note); break; + case ELT_SUB_SOUR: + citation_add_note(ctxt, note); break; + case ELT_SUB_MULTIM_OBJE: + multimedia_link_add_note(ctxt, note); break; + case ELT_SUB_LSS_SLGS: + case ELT_SUB_LIO_BAPL: + case ELT_SUB_LIO_SLGC: + lds_event_add_note(ctxt, note); break; + case REC_FAM: + family_add_note(ctxt, note); break; + case ELT_SUB_CHAN: + change_date_add_note(ctxt, note); break; + case ELT_SUB_PERS_NAME: + name_add_note(ctxt, note); break; + case ELT_SUB_FAMC: + case ELT_SUB_FAMS: + family_link_add_note(ctxt, note); break; + case ELT_SUB_ASSO: + association_add_note(ctxt, note); break; + case REC_INDI: + individual_add_note(ctxt, note); break; + case REC_OBJE: + multimedia_add_note(ctxt, note); break; + case REC_REPO: + repository_add_note(ctxt, note); break; + case ELT_SOUR_DATA: + source_add_note_to_data(ctxt, note); break; + case ELT_SUB_REPO: + source_add_note_to_repo(ctxt, note); break; + case REC_SOUR: + source_add_note(ctxt, note); break; + default: + UNEXPECTED_CONTEXT(ctxt->ctxt_type); + } + result = MAKE_GOM_CTXT(elt, note_sub, note); + } } } - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, note_sub, note); + return (Gedcom_ctxt)result; } void note_sub_subscribe() @@ -116,26 +132,34 @@ void note_sub_subscribe() void note_sub_add_citation(Gom_ctxt ctxt, struct source_citation* cit) { struct note_sub *note = SAFE_CTXT_CAST(note_sub, ctxt); - LINK_CHAIN_ELT(source_citation, note->citation, cit) + if (note) + LINK_CHAIN_ELT(source_citation, note->citation, cit); } void note_sub_add_to_note(NL_TYPE type, Gom_ctxt ctxt, char* str) { struct note_sub *note = SAFE_CTXT_CAST(note_sub, ctxt); - note->text = concat_strings (type, note->text, str); + if (note) { + char *newvalue = concat_strings (type, note->text, str); + if (newvalue) + note->text = newvalue; + else + MEMORY_ERROR; + } } void note_sub_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct note_sub *obj = SAFE_CTXT_CAST(note_sub, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data);; } void note_sub_cleanup(struct note_sub* note) { if (note) { SAFE_FREE(note->text); - DESTROY_CHAIN_ELTS(source_citation, note->citation, citation_cleanup) - DESTROY_CHAIN_ELTS(user_data, note->extra, user_data_cleanup) + DESTROY_CHAIN_ELTS(source_citation, note->citation, citation_cleanup); + DESTROY_CHAIN_ELTS(user_data, note->extra, user_data_cleanup); } } diff --git a/gom/personal_name.c b/gom/personal_name.c index b859ba7..7efc916 100644 --- a/gom/personal_name.c +++ b/gom/personal_name.c @@ -35,22 +35,34 @@ Gedcom_ctxt sub_name_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; - struct personal_name *name = NULL; + Gom_ctxt result = NULL; if (ctxt) { - name = (struct personal_name *)malloc(sizeof(struct personal_name)); - memset (name, 0, sizeof(struct personal_name)); - name->name = strdup(GEDCOM_STRING(parsed_value)); + struct personal_name *name + = (struct personal_name *)malloc(sizeof(struct personal_name)); + if (! name) + MEMORY_ERROR; + else { + memset (name, 0, sizeof(struct personal_name)); + name->name = strdup(GEDCOM_STRING(parsed_value)); - switch (ctxt->ctxt_type) { - case REC_INDI: - individual_add_name(ctxt, name); break; - default: - UNEXPECTED_CONTEXT(ctxt->ctxt_type); + if (! name->name) { + MEMORY_ERROR; + free(name); + } + else { + switch (ctxt->ctxt_type) { + case REC_INDI: + individual_add_name(ctxt, name); break; + default: + UNEXPECTED_CONTEXT(ctxt->ctxt_type); + } + result = MAKE_GOM_CTXT(elt, personal_name, name); + } } } - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, personal_name, name); + return (Gedcom_ctxt)result; } STRING_CB(personal_name, sub_name_npfx_start, prefix) @@ -63,19 +75,22 @@ STRING_CB(personal_name, sub_name_nsfx_start, suffix) void name_add_citation(Gom_ctxt ctxt, struct source_citation* cit) { struct personal_name *name = SAFE_CTXT_CAST(personal_name, ctxt); - LINK_CHAIN_ELT(source_citation, name->citation, cit) + if (name) + LINK_CHAIN_ELT(source_citation, name->citation, cit); } void name_add_note(Gom_ctxt ctxt, struct note_sub* note) { struct personal_name *name = SAFE_CTXT_CAST(personal_name, ctxt); - LINK_CHAIN_ELT(note_sub, name->note, note) + if (name) + LINK_CHAIN_ELT(note_sub, name->note, note); } void name_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct personal_name *obj = SAFE_CTXT_CAST(personal_name, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data); } void name_subscribe() @@ -105,8 +120,8 @@ void name_cleanup(struct personal_name* name) SAFE_FREE(name->surname_prefix); SAFE_FREE(name->surname); SAFE_FREE(name->suffix); - DESTROY_CHAIN_ELTS(source_citation, name->citation, citation_cleanup) - DESTROY_CHAIN_ELTS(note_sub, name->note, note_sub_cleanup) - DESTROY_CHAIN_ELTS(user_data, name->extra, user_data_cleanup) + DESTROY_CHAIN_ELTS(source_citation, name->citation, citation_cleanup); + DESTROY_CHAIN_ELTS(note_sub, name->note, note_sub_cleanup); + DESTROY_CHAIN_ELTS(user_data, name->extra, user_data_cleanup); } } diff --git a/gom/place.c b/gom/place.c index a77ff91..bb6ead6 100644 --- a/gom/place.c +++ b/gom/place.c @@ -36,29 +36,42 @@ Gedcom_ctxt sub_place_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; - struct place *place = NULL; + Gom_ctxt result = NULL; - if (ctxt) { - place = (struct place *)malloc(sizeof(struct place)); - memset (place, 0, sizeof(struct place)); - place->value = strdup(GEDCOM_STRING(parsed_value)); - - switch (ctxt->ctxt_type) { - case ELT_SUB_FAM_EVT: - case ELT_SUB_FAM_EVT_EVEN: - case ELT_SUB_INDIV_ATTR: - case ELT_SUB_INDIV_RESI: - case ELT_SUB_INDIV_BIRT: - case ELT_SUB_INDIV_GEN: - case ELT_SUB_INDIV_ADOP: - case ELT_SUB_INDIV_EVEN: - event_add_place(ctxt, place); break; - default: - UNEXPECTED_CONTEXT(ctxt->ctxt_type); + if (! ctxt) + NO_CONTEXT; + else { + struct place *place = (struct place *)malloc(sizeof(struct place)); + if (! place) + MEMORY_ERROR; + else { + memset (place, 0, sizeof(struct place)); + place->value = strdup(GEDCOM_STRING(parsed_value)); + + if (!place->value) { + MEMORY_ERROR; + free(place); + } + else { + switch (ctxt->ctxt_type) { + case ELT_SUB_FAM_EVT: + case ELT_SUB_FAM_EVT_EVEN: + case ELT_SUB_INDIV_ATTR: + case ELT_SUB_INDIV_RESI: + case ELT_SUB_INDIV_BIRT: + case ELT_SUB_INDIV_GEN: + case ELT_SUB_INDIV_ADOP: + case ELT_SUB_INDIV_EVEN: + event_add_place(ctxt, place); break; + default: + UNEXPECTED_CONTEXT(ctxt->ctxt_type); + } + result = MAKE_GOM_CTXT(elt, place, place); + } } } - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, place, place); + return (Gedcom_ctxt)result; } STRING_CB(place, sub_place_form_start, place_hierarchy) @@ -66,19 +79,22 @@ STRING_CB(place, sub_place_form_start, place_hierarchy) void place_add_citation(Gom_ctxt ctxt, struct source_citation* cit) { struct place *place = SAFE_CTXT_CAST(place, ctxt); - LINK_CHAIN_ELT(source_citation, place->citation, cit) + if (place) + LINK_CHAIN_ELT(source_citation, place->citation, cit); } void place_add_note(Gom_ctxt ctxt, struct note_sub* note) { struct place *place = SAFE_CTXT_CAST(place, ctxt); - LINK_CHAIN_ELT(note_sub, place->note, note) + if (place) + LINK_CHAIN_ELT(note_sub, place->note, note); } void place_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct place *obj = SAFE_CTXT_CAST(place, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data); } void place_subscribe() @@ -93,9 +109,9 @@ void place_cleanup(struct place* place) if (place) { SAFE_FREE(place->value); SAFE_FREE(place->place_hierarchy); - DESTROY_CHAIN_ELTS(source_citation, place->citation, citation_cleanup) - DESTROY_CHAIN_ELTS(note_sub, place->note, note_sub_cleanup) - DESTROY_CHAIN_ELTS(user_data, place->extra, user_data_cleanup) + DESTROY_CHAIN_ELTS(source_citation, place->citation, citation_cleanup); + DESTROY_CHAIN_ELTS(note_sub, place->note, note_sub_cleanup); + DESTROY_CHAIN_ELTS(user_data, place->extra, user_data_cleanup); } SAFE_FREE(place); } diff --git a/gom/repository.c b/gom/repository.c index 5fd8883..a2f61dd 100644 --- a/gom/repository.c +++ b/gom/repository.c @@ -48,63 +48,75 @@ void repository_subscribe() void repository_add_address(Gom_ctxt ctxt, struct address* address) { struct repository *repo = SAFE_CTXT_CAST(repository, ctxt); - repo->address = address; + if (repo) + repo->address = address; } void repository_add_phone(Gom_ctxt ctxt, char *phone) { struct repository *repo = SAFE_CTXT_CAST(repository, ctxt); - if (! repo->phone[0]) - repo->phone[0] = strdup(phone); - else if (! repo->phone[1]) - repo->phone[1] = strdup(phone); - else if (! repo->phone[2]) - repo->phone[2] = strdup(phone); + if (repo) { + int i = 0; + while (i<2 && repo->phone[i]) i++; + if (! repo->phone[i]) { + repo->phone[i] = strdup(phone); + if (! repo->phone[i]) MEMORY_ERROR; + } + } } void repository_add_note(Gom_ctxt ctxt, struct note_sub* note) { struct repository *repo = SAFE_CTXT_CAST(repository, ctxt); - LINK_CHAIN_ELT(note_sub, repo->note, note) + if (repo) + LINK_CHAIN_ELT(note_sub, repo->note, note); } void repository_add_user_ref(Gom_ctxt ctxt, struct user_ref_number* ref) { struct repository *repo = SAFE_CTXT_CAST(repository, ctxt); - LINK_CHAIN_ELT(user_ref_number, repo->ref, ref) + if (repo) + LINK_CHAIN_ELT(user_ref_number, repo->ref, ref); } void repository_set_record_id(Gom_ctxt ctxt, char *rin) { struct repository *repo = SAFE_CTXT_CAST(repository, ctxt); - repo->record_id = strdup(rin); + if (repo) { + repo->record_id = strdup(rin); + if (! repo->record_id) MEMORY_ERROR; + } } void repository_set_change_date(Gom_ctxt ctxt, struct change_date* chan) { struct repository *repo = SAFE_CTXT_CAST(repository, ctxt); - repo->change_date = chan; + if (repo) + repo->change_date = chan; } void repository_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct repository *obj = SAFE_CTXT_CAST(repository, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data); } void repository_cleanup(struct repository* repo) { - SAFE_FREE(repo->xrefstr); - SAFE_FREE(repo->name); - address_cleanup(repo->address); - SAFE_FREE(repo->phone[0]); - SAFE_FREE(repo->phone[1]); - SAFE_FREE(repo->phone[2]); - DESTROY_CHAIN_ELTS(note_sub, repo->note, note_sub_cleanup) - DESTROY_CHAIN_ELTS(user_ref_number, repo->ref, user_ref_cleanup) - SAFE_FREE(repo->record_id); - change_date_cleanup(repo->change_date); - DESTROY_CHAIN_ELTS(user_data, repo->extra, user_data_cleanup) + if (repo) { + SAFE_FREE(repo->xrefstr); + SAFE_FREE(repo->name); + address_cleanup(repo->address); + SAFE_FREE(repo->phone[0]); + SAFE_FREE(repo->phone[1]); + SAFE_FREE(repo->phone[2]); + DESTROY_CHAIN_ELTS(note_sub, repo->note, note_sub_cleanup); + DESTROY_CHAIN_ELTS(user_ref_number, repo->ref, user_ref_cleanup); + SAFE_FREE(repo->record_id); + change_date_cleanup(repo->change_date); + DESTROY_CHAIN_ELTS(user_data, repo->extra, user_data_cleanup); + } } void repositories_cleanup() @@ -119,8 +131,11 @@ struct repository* gom_get_first_repository() struct repository* make_repository_record(char* xrefstr) { - struct repository* repo; + struct repository* repo = NULL; MAKE_CHAIN_ELT(repository, gom_first_repository, repo); - repo->xrefstr = strdup(xrefstr); + if (repo) { + repo->xrefstr = strdup(xrefstr); + if (! repo->xrefstr) MEMORY_ERROR; + } return repo; } diff --git a/gom/source.c b/gom/source.c index f306784..34a7c9e 100644 --- a/gom/source.c +++ b/gom/source.c @@ -66,100 +66,137 @@ void source_subscribe() void source_add_event(Gom_ctxt ctxt, struct source_event* evt) { struct source *sour = SAFE_CTXT_CAST(source, ctxt); - LINK_CHAIN_ELT(source_event, sour->data.event, evt) + if (sour) + LINK_CHAIN_ELT(source_event, sour->data.event, evt); } void source_add_note_to_data(Gom_ctxt ctxt, struct note_sub* note) { struct source *sour = SAFE_CTXT_CAST(source, ctxt); - LINK_CHAIN_ELT(note_sub, sour->data.note, note) + if (sour) + LINK_CHAIN_ELT(note_sub, sour->data.note, note); } void source_add_note_to_repo(Gom_ctxt ctxt, struct note_sub* note) { struct source *sour = SAFE_CTXT_CAST(source, ctxt); - LINK_CHAIN_ELT(note_sub, sour->repository.note, note) + if (sour) + LINK_CHAIN_ELT(note_sub, sour->repository.note, note); } void source_add_description(Gom_ctxt ctxt, struct source_description* desc) { struct source *sour = SAFE_CTXT_CAST(source, ctxt); - LINK_CHAIN_ELT(source_description, sour->repository.description, desc) + if (sour) + LINK_CHAIN_ELT(source_description, sour->repository.description, desc); } void source_add_to_value(NL_TYPE type, Gom_ctxt ctxt, char* str) { struct source *sour = SAFE_CTXT_CAST(source, ctxt); - switch (ctxt->ctxt_type) { - case ELT_SOUR_AUTH: - sour->author = concat_strings (type, sour->author, str); break; - case ELT_SOUR_TITL: - sour->title = concat_strings (type, sour->title, str); break; - case ELT_SOUR_PUBL: - sour->publication = concat_strings (type, sour->publication, str); break; - case ELT_SOUR_TEXT: - sour->text = concat_strings (type, sour->text, str); break; - default: - UNEXPECTED_CONTEXT(ctxt->ctxt_type); + if (sour) { + switch (ctxt->ctxt_type) { + char *newvalue; + case ELT_SOUR_AUTH: + newvalue = concat_strings (type, sour->author, str); + if (newvalue) + sour->author = newvalue; + else + MEMORY_ERROR; + break; + case ELT_SOUR_TITL: + newvalue = concat_strings (type, sour->title, str); + if (newvalue) + sour->title = newvalue; + else + MEMORY_ERROR; + break; + case ELT_SOUR_PUBL: + newvalue = concat_strings (type, sour->publication, str); + if (newvalue) + sour->publication = newvalue; + else + MEMORY_ERROR; + break; + case ELT_SOUR_TEXT: + newvalue = concat_strings (type, sour->text, str); + if (newvalue) + sour->text = newvalue; + else + MEMORY_ERROR; + break; + default: + UNEXPECTED_CONTEXT(ctxt->ctxt_type); + } } } void source_add_mm_link(Gom_ctxt ctxt, struct multimedia_link* link) { struct source *sour = SAFE_CTXT_CAST(source, ctxt); - LINK_CHAIN_ELT(multimedia_link, sour->mm_link, link) + if (sour) + LINK_CHAIN_ELT(multimedia_link, sour->mm_link, link); } void source_add_note(Gom_ctxt ctxt, struct note_sub* note) { struct source *sour = SAFE_CTXT_CAST(source, ctxt); - LINK_CHAIN_ELT(note_sub, sour->note, note) + if (sour) + LINK_CHAIN_ELT(note_sub, sour->note, note); } void source_add_user_ref(Gom_ctxt ctxt, struct user_ref_number* ref) { struct source *sour = SAFE_CTXT_CAST(source, ctxt); - LINK_CHAIN_ELT(user_ref_number, sour->ref, ref) + if (sour) + LINK_CHAIN_ELT(user_ref_number, sour->ref, ref); } void source_set_record_id(Gom_ctxt ctxt, char *rin) { struct source *sour = SAFE_CTXT_CAST(source, ctxt); - sour->record_id = strdup(rin); + if (sour) { + sour->record_id = strdup(rin); + if (! sour->record_id) MEMORY_ERROR; + } } void source_set_change_date(Gom_ctxt ctxt, struct change_date* chan) { struct source *sour = SAFE_CTXT_CAST(source, ctxt); - sour->change_date = chan; + if (sour) + sour->change_date = chan; } void source_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct source *obj = SAFE_CTXT_CAST(source, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data); } void source_cleanup(struct source* sour) { - SAFE_FREE(sour->xrefstr); - DESTROY_CHAIN_ELTS(source_event, sour->data.event, source_event_cleanup) - SAFE_FREE(sour->data.agency) - DESTROY_CHAIN_ELTS(note_sub, sour->data.note, note_sub_cleanup) - SAFE_FREE(sour->author); - SAFE_FREE(sour->title); - SAFE_FREE(sour->abbreviation); - SAFE_FREE(sour->publication); - SAFE_FREE(sour->text); - DESTROY_CHAIN_ELTS(note_sub, sour->repository.note, note_sub_cleanup) - DESTROY_CHAIN_ELTS(source_description, sour->repository.description, - source_description_cleanup) - DESTROY_CHAIN_ELTS(multimedia_link, sour->mm_link, multimedia_link_cleanup) - DESTROY_CHAIN_ELTS(note_sub, sour->note, note_sub_cleanup) - DESTROY_CHAIN_ELTS(user_ref_number, sour->ref, user_ref_cleanup) - SAFE_FREE(sour->record_id); - change_date_cleanup(sour->change_date); - DESTROY_CHAIN_ELTS(user_data, sour->extra, user_data_cleanup) + if (sour) { + SAFE_FREE(sour->xrefstr); + DESTROY_CHAIN_ELTS(source_event, sour->data.event, source_event_cleanup); + SAFE_FREE(sour->data.agency) + DESTROY_CHAIN_ELTS(note_sub, sour->data.note, note_sub_cleanup); + SAFE_FREE(sour->author); + SAFE_FREE(sour->title); + SAFE_FREE(sour->abbreviation); + SAFE_FREE(sour->publication); + SAFE_FREE(sour->text); + DESTROY_CHAIN_ELTS(note_sub, sour->repository.note, note_sub_cleanup); + DESTROY_CHAIN_ELTS(source_description, sour->repository.description, + source_description_cleanup); + DESTROY_CHAIN_ELTS(multimedia_link, sour->mm_link,multimedia_link_cleanup); + DESTROY_CHAIN_ELTS(note_sub, sour->note, note_sub_cleanup); + DESTROY_CHAIN_ELTS(user_ref_number, sour->ref, user_ref_cleanup); + SAFE_FREE(sour->record_id); + change_date_cleanup(sour->change_date); + DESTROY_CHAIN_ELTS(user_data, sour->extra, user_data_cleanup); + } } void sources_cleanup() @@ -174,8 +211,11 @@ struct source* gom_get_first_source() struct source* make_source_record(char* xrefstr) { - struct source* src; + struct source* src = NULL; MAKE_CHAIN_ELT(source, gom_first_source, src); - src->xrefstr = strdup(xrefstr); + if (src) { + src->xrefstr = strdup(xrefstr); + if (! src->xrefstr) MEMORY_ERROR; + } return src; } diff --git a/gom/source_citation.c b/gom/source_citation.c index 4708129..0d7fb96 100644 --- a/gom/source_citation.c +++ b/gom/source_citation.c @@ -42,60 +42,95 @@ Gedcom_ctxt sub_citation_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; - struct source_citation *cit = NULL; - - if (ctxt) { - cit = (struct source_citation *)malloc(sizeof(struct source_citation)); - memset (cit, 0, sizeof(struct source_citation)); - if (GEDCOM_IS_STRING(parsed_value)) - cit->description = strdup(GEDCOM_STRING(parsed_value)); - else if (GEDCOM_IS_XREF_PTR(parsed_value)) - cit->reference = GEDCOM_XREF_PTR(parsed_value); - - switch (ctxt->ctxt_type) { - case ELT_SUB_PLAC: - place_add_citation(ctxt, cit); break; - case ELT_SUB_FAM_EVT: - case ELT_SUB_FAM_EVT_EVEN: - case ELT_SUB_INDIV_ATTR: - case ELT_SUB_INDIV_RESI: - case ELT_SUB_INDIV_BIRT: - case ELT_SUB_INDIV_GEN: - case ELT_SUB_INDIV_ADOP: - case ELT_SUB_INDIV_EVEN: - event_add_citation(ctxt, cit); break; - case ELT_SUB_NOTE: - note_sub_add_citation(ctxt, cit); break; - case ELT_SUB_LSS_SLGS: - case ELT_SUB_LIO_BAPL: - case ELT_SUB_LIO_SLGC: - lds_event_add_citation(ctxt, cit); break; - case REC_FAM: - family_add_citation(ctxt, cit); break; - case ELT_SUB_PERS_NAME: - name_add_citation(ctxt, cit); break; - case REC_INDI: - individual_add_citation(ctxt, cit); break; - case ELT_SUB_ASSO: - association_add_citation(ctxt, cit); break; - case REC_NOTE: - note_add_citation(ctxt, cit); break; - default: - UNEXPECTED_CONTEXT(ctxt->ctxt_type); + Gom_ctxt result = NULL; + + if (! ctxt) + NO_CONTEXT; + else { + struct source_citation *cit + = (struct source_citation *)malloc(sizeof(struct source_citation)); + + if (! cit) + MEMORY_ERROR; + else { + int err = 0; + memset (cit, 0, sizeof(struct source_citation)); + if (GEDCOM_IS_STRING(parsed_value)) { + cit->description = strdup(GEDCOM_STRING(parsed_value)); + if (! cit->description) { + MEMORY_ERROR; + free(cit); + err = 1; + } + } + else if (GEDCOM_IS_XREF_PTR(parsed_value)) + cit->reference = GEDCOM_XREF_PTR(parsed_value); + + if (! err) { + switch (ctxt->ctxt_type) { + case ELT_SUB_PLAC: + place_add_citation(ctxt, cit); break; + case ELT_SUB_FAM_EVT: + case ELT_SUB_FAM_EVT_EVEN: + case ELT_SUB_INDIV_ATTR: + case ELT_SUB_INDIV_RESI: + case ELT_SUB_INDIV_BIRT: + case ELT_SUB_INDIV_GEN: + case ELT_SUB_INDIV_ADOP: + case ELT_SUB_INDIV_EVEN: + event_add_citation(ctxt, cit); break; + case ELT_SUB_NOTE: + note_sub_add_citation(ctxt, cit); break; + case ELT_SUB_LSS_SLGS: + case ELT_SUB_LIO_BAPL: + case ELT_SUB_LIO_SLGC: + lds_event_add_citation(ctxt, cit); break; + case REC_FAM: + family_add_citation(ctxt, cit); break; + case ELT_SUB_PERS_NAME: + name_add_citation(ctxt, cit); break; + case REC_INDI: + individual_add_citation(ctxt, cit); break; + case ELT_SUB_ASSO: + association_add_citation(ctxt, cit); break; + case REC_NOTE: + note_add_citation(ctxt, cit); break; + default: + UNEXPECTED_CONTEXT(ctxt->ctxt_type); + } + result = MAKE_GOM_CTXT(elt, source_citation, cit); + } } } - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, source_citation, cit); + return (Gedcom_ctxt)result; } Gedcom_ctxt sub_cit_text_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; - struct source_citation *cit = SAFE_CTXT_CAST(source_citation, ctxt); - struct text *t; - MAKE_CHAIN_ELT(text, cit->text, t); - t->text = strdup(GEDCOM_STRING(parsed_value)); - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, text, t); + Gom_ctxt result = NULL; + + if (! ctxt) + NO_CONTEXT; + else { + struct source_citation *cit = SAFE_CTXT_CAST(source_citation, ctxt); + if (cit) { + struct text *t = NULL; + MAKE_CHAIN_ELT(text, cit->text, t); + if (t) { + t->text = strdup(GEDCOM_STRING(parsed_value)); + if (! t->text) { + MEMORY_ERROR; + free(t); + } + else + result = MAKE_GOM_CTXT(elt, text, t); + } + } + } + + return (Gedcom_ctxt)result; } STRING_CB(source_citation, sub_cit_page_start, page) @@ -127,31 +162,46 @@ void citation_subscribe() void citation_add_note(Gom_ctxt ctxt, struct note_sub* note) { struct source_citation *cit = SAFE_CTXT_CAST(source_citation, ctxt); - LINK_CHAIN_ELT(note_sub, cit->note, note) + if (cit) + LINK_CHAIN_ELT(note_sub, cit->note, note); } void citation_add_mm_link(Gom_ctxt ctxt, struct multimedia_link* mm) { struct source_citation *cit = SAFE_CTXT_CAST(source_citation, ctxt); - LINK_CHAIN_ELT(multimedia_link, cit->mm_link, mm) + if (cit) + LINK_CHAIN_ELT(multimedia_link, cit->mm_link, mm); } void citation_add_to_desc(NL_TYPE type, Gom_ctxt ctxt, char* str) { struct source_citation *cit = SAFE_CTXT_CAST(source_citation, ctxt); - cit->description = concat_strings (type, cit->description, str); + if (cit) { + char *newvalue = concat_strings (type, cit->description, str); + if (newvalue) + cit->description = newvalue; + else + MEMORY_ERROR; + } } void citation_add_to_text(NL_TYPE type, Gom_ctxt ctxt, char* str) { struct text *t = SAFE_CTXT_CAST(text, ctxt); - t->text = concat_strings (type, t->text, str); + if (t) { + char *newvalue = concat_strings (type, t->text, str); + if (newvalue) + t->text = newvalue; + else + MEMORY_ERROR; + } } void citation_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct source_citation *obj = SAFE_CTXT_CAST(source_citation, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data); } void text_cleanup(struct text* t) @@ -169,10 +219,10 @@ void citation_cleanup(struct source_citation* cit) SAFE_FREE(cit->event); SAFE_FREE(cit->role); SAFE_FREE(cit->date); - DESTROY_CHAIN_ELTS(text, cit->text, text_cleanup) + DESTROY_CHAIN_ELTS(text, cit->text, text_cleanup); SAFE_FREE(cit->quality); - DESTROY_CHAIN_ELTS(multimedia_link, cit->mm_link, multimedia_link_cleanup) - DESTROY_CHAIN_ELTS(note_sub, cit->note, note_sub_cleanup) - DESTROY_CHAIN_ELTS(user_data, cit->extra, user_data_cleanup) + DESTROY_CHAIN_ELTS(multimedia_link, cit->mm_link, multimedia_link_cleanup); + DESTROY_CHAIN_ELTS(note_sub, cit->note, note_sub_cleanup); + DESTROY_CHAIN_ELTS(user_data, cit->extra, user_data_cleanup); } } diff --git a/gom/source_description.c b/gom/source_description.c index 6dea145..ecec1dc 100644 --- a/gom/source_description.c +++ b/gom/source_description.c @@ -33,23 +33,36 @@ Gedcom_ctxt sub_sour_caln_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; - struct source_description *desc = NULL; + Gom_ctxt result = NULL; - if (ctxt) { - desc + if (! ctxt) + NO_CONTEXT; + else { + struct source_description *desc = (struct source_description *)malloc(sizeof(struct source_description)); - memset (desc, 0, sizeof(struct source_description)); - desc->call_number = strdup(GEDCOM_STRING(parsed_value)); + if (! desc) + MEMORY_ERROR; + else { + memset (desc, 0, sizeof(struct source_description)); + desc->call_number = strdup(GEDCOM_STRING(parsed_value)); - switch (ctxt->ctxt_type) { - case ELT_SUB_REPO: - source_add_description(ctxt, desc); break; - default: - UNEXPECTED_CONTEXT(ctxt->ctxt_type); + if (! desc->call_number) { + MEMORY_ERROR; + free(desc); + } + else { + switch (ctxt->ctxt_type) { + case ELT_SUB_REPO: + source_add_description(ctxt, desc); break; + default: + UNEXPECTED_CONTEXT(ctxt->ctxt_type); + } + result = MAKE_GOM_CTXT(elt, source_description, desc); + } } } - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, source_description, desc); + return (Gedcom_ctxt)result; } STRING_CB(source_description, sub_sour_caln_medi_start, media) @@ -65,7 +78,8 @@ void source_description_subscribe() void source_description_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct source_description *obj = SAFE_CTXT_CAST(source_description, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data); } void source_description_cleanup(struct source_description* desc) @@ -73,6 +87,6 @@ void source_description_cleanup(struct source_description* desc) if (desc) { SAFE_FREE(desc->call_number); SAFE_FREE(desc->media); - DESTROY_CHAIN_ELTS(user_data, desc->extra, user_data_cleanup) + DESTROY_CHAIN_ELTS(user_data, desc->extra, user_data_cleanup); } } diff --git a/gom/source_event.c b/gom/source_event.c index c351384..f7c7a8d 100644 --- a/gom/source_event.c +++ b/gom/source_event.c @@ -33,22 +33,36 @@ Gedcom_ctxt sub_sour_even_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; - struct source_event *evt = NULL; + Gom_ctxt result = NULL; - if (ctxt) { - evt = (struct source_event *)malloc(sizeof(struct source_event)); - memset (evt, 0, sizeof(struct source_event)); - evt->recorded_events = strdup(GEDCOM_STRING(parsed_value)); + if (! ctxt) + NO_CONTEXT; + else { + struct source_event *evt + = (struct source_event *)malloc(sizeof(struct source_event)); + if (! evt) + MEMORY_ERROR; + else { + memset (evt, 0, sizeof(struct source_event)); + evt->recorded_events = strdup(GEDCOM_STRING(parsed_value)); - switch (ctxt->ctxt_type) { - case ELT_SOUR_DATA: - source_add_event(ctxt, evt); break; - default: - UNEXPECTED_CONTEXT(ctxt->ctxt_type); + if (! evt->recorded_events) { + MEMORY_ERROR; + free(evt); + } + else { + switch (ctxt->ctxt_type) { + case ELT_SOUR_DATA: + source_add_event(ctxt, evt); break; + default: + UNEXPECTED_CONTEXT(ctxt->ctxt_type); + } + result = MAKE_GOM_CTXT(elt, source_event, evt); + } } } - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, source_event, evt); + return (Gedcom_ctxt)result; } DATE_CB(source_event, sub_sour_even_date_start, date_period) @@ -67,7 +81,8 @@ void source_event_subscribe() void source_event_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct source_event *obj = SAFE_CTXT_CAST(source_event, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data); } void source_event_cleanup(struct source_event* evt) @@ -76,6 +91,6 @@ void source_event_cleanup(struct source_event* evt) SAFE_FREE(evt->recorded_events); SAFE_FREE(evt->date_period); SAFE_FREE(evt->jurisdiction); - DESTROY_CHAIN_ELTS(user_data, evt->extra, user_data_cleanup) + DESTROY_CHAIN_ELTS(user_data, evt->extra, user_data_cleanup); } } diff --git a/gom/submission.c b/gom/submission.c index 1c84088..a72df9a 100644 --- a/gom/submission.c +++ b/gom/submission.c @@ -56,7 +56,8 @@ void submission_subscribe() void submission_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct submission *obj = SAFE_CTXT_CAST(submission, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data); } void submission_cleanup() @@ -69,7 +70,7 @@ void submission_cleanup() SAFE_FREE(gom_submission->nr_of_descendant_gens); SAFE_FREE(gom_submission->ordinance_process_flag); SAFE_FREE(gom_submission->record_id); - DESTROY_CHAIN_ELTS(user_data, gom_submission->extra, user_data_cleanup) + DESTROY_CHAIN_ELTS(user_data, gom_submission->extra, user_data_cleanup); SAFE_FREE(gom_submission); } } @@ -83,8 +84,13 @@ struct submission* make_submission_record(char* xref) { if (! gom_submission) { gom_submission = (struct submission*)malloc(sizeof(struct submission)); - memset(gom_submission, 0, sizeof(struct submission)); - gom_submission->xrefstr = strdup(xref); + if (! gom_submission) + MEMORY_ERROR; + else { + memset(gom_submission, 0, sizeof(struct submission)); + gom_submission->xrefstr = strdup(xref); + if (!gom_submission->xrefstr) MEMORY_ERROR; + } } return gom_submission; diff --git a/gom/submitter.c b/gom/submitter.c index b33914d..39046ab 100644 --- a/gom/submitter.c +++ b/gom/submitter.c @@ -43,17 +43,32 @@ STRING_CB(submitter, subm_rin_start, record_id) Gedcom_ctxt subm_lang_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; - struct submitter *subm = SAFE_CTXT_CAST(submitter, ctxt); - char *str = GEDCOM_STRING(parsed_value); - - if (! subm->language[0]) - subm->language[0] = strdup(str); - else if (! subm->language[1]) - subm->language[1] = strdup(str); - else if (! subm->language[2]) - subm->language[2] = strdup(str); + Gom_ctxt result = NULL; + + if (! ctxt) + NO_CONTEXT; + else { + struct submitter *subm = SAFE_CTXT_CAST(submitter, ctxt); + + if (subm) { + int err = 0; + char *str = GEDCOM_STRING(parsed_value); + int i = 0; + + while (i<2 && subm->language[i]) i++; + if (! subm->language[i]) { + subm->language[i] = strdup(str); + if (! subm->language[i]) { + MEMORY_ERROR; + err = 1; + } + } + if (! err) + result = MAKE_GOM_CTXT(elt, submitter, subm); + } + } - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, submitter, subm); + return (Gedcom_ctxt)result; } void submitter_subscribe() @@ -68,54 +83,62 @@ void submitter_subscribe() void submitter_add_address(Gom_ctxt ctxt, struct address* address) { struct submitter *subm = SAFE_CTXT_CAST(submitter, ctxt); - subm->address = address; + if (subm) + subm->address = address; } void submitter_add_phone(Gom_ctxt ctxt, char *phone) { struct submitter *subm = SAFE_CTXT_CAST(submitter, ctxt); - if (! subm->phone[0]) - subm->phone[0] = strdup(phone); - else if (! subm->phone[1]) - subm->phone[1] = strdup(phone); - else if (! subm->phone[2]) - subm->phone[2] = strdup(phone); + if (subm) { + int i = 0; + while (i<2 && subm->phone[i]) i++; + if (! subm->phone[i]) { + subm->phone[i] = strdup(phone); + if (! subm->phone[i]) MEMORY_ERROR; + } + } } void submitter_add_mm_link(Gom_ctxt ctxt, struct multimedia_link* link) { struct submitter *subm = SAFE_CTXT_CAST(submitter, ctxt); - LINK_CHAIN_ELT(multimedia_link, subm->mm_link, link) + if (subm) + LINK_CHAIN_ELT(multimedia_link, subm->mm_link, link); } void submitter_set_change_date(Gom_ctxt ctxt, struct change_date* chan) { struct submitter *subm = SAFE_CTXT_CAST(submitter, ctxt); - subm->change_date = chan; + if (subm) + subm->change_date = chan; } void submitter_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct submitter *obj = SAFE_CTXT_CAST(submitter, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data); } void submitter_cleanup(struct submitter* rec) { - SAFE_FREE(rec->xrefstr); - SAFE_FREE(rec->name); - address_cleanup(rec->address); - SAFE_FREE(rec->phone[0]); - SAFE_FREE(rec->phone[1]); - SAFE_FREE(rec->phone[2]); - DESTROY_CHAIN_ELTS(multimedia_link, rec->mm_link, multimedia_link_cleanup) - SAFE_FREE(rec->language[0]); - SAFE_FREE(rec->language[1]); - SAFE_FREE(rec->language[2]); - SAFE_FREE(rec->record_file_nr); - SAFE_FREE(rec->record_id); - change_date_cleanup(rec->change_date); - DESTROY_CHAIN_ELTS(user_data, rec->extra, user_data_cleanup) + if (rec) { + SAFE_FREE(rec->xrefstr); + SAFE_FREE(rec->name); + address_cleanup(rec->address); + SAFE_FREE(rec->phone[0]); + SAFE_FREE(rec->phone[1]); + SAFE_FREE(rec->phone[2]); + DESTROY_CHAIN_ELTS(multimedia_link, rec->mm_link, multimedia_link_cleanup); + SAFE_FREE(rec->language[0]); + SAFE_FREE(rec->language[1]); + SAFE_FREE(rec->language[2]); + SAFE_FREE(rec->record_file_nr); + SAFE_FREE(rec->record_id); + change_date_cleanup(rec->change_date); + DESTROY_CHAIN_ELTS(user_data, rec->extra, user_data_cleanup); + } } void submitters_cleanup() @@ -130,8 +153,11 @@ struct submitter* gom_get_first_submitter() struct submitter* make_submitter_record(char* xrefstr) { - struct submitter* subm; + struct submitter* subm = NULL; MAKE_CHAIN_ELT(submitter, gom_first_submitter, subm); - subm->xrefstr = strdup(xrefstr); + if (subm) { + subm->xrefstr = strdup(xrefstr); + if (!subm->xrefstr) MEMORY_ERROR; + } return subm; } diff --git a/gom/user_rec.c b/gom/user_rec.c index 6581c8a..7c05d15 100644 --- a/gom/user_rec.c +++ b/gom/user_rec.c @@ -57,7 +57,10 @@ Gedcom_ctxt user_rec_start(_REC_PARAMS_) { struct user_rec* user = NULL; struct xref_value* xr = NULL; + Gom_ctxt result = NULL; Gedcom_ctxt ctxt = NULL; + int err = 0; + if (GEDCOM_IS_XREF_PTR(xref)) xr = GEDCOM_XREF_PTR(xref); if (xr) { @@ -74,14 +77,28 @@ Gedcom_ctxt user_rec_start(_REC_PARAMS_) user = make_user_record(NULL); ctxt = (Gedcom_ctxt) user; } + + if (user) { + user->tag = strdup(tag); + if (! user->tag) { + MEMORY_ERROR; + err = 1; + } + else if (GEDCOM_IS_STRING(parsed_value)) { + user->str_value = strdup(GEDCOM_STRING(parsed_value)); + if (!user->str_value) { + MEMORY_ERROR; + err = 1; + } + } + else if (GEDCOM_IS_XREF_PTR(parsed_value)) + user->xref_value = GEDCOM_XREF_PTR(parsed_value); + + if (! err) + result = MAKE_GOM_CTXT(rec, user_rec, ctxt); + } - user->tag = strdup(tag); - if (GEDCOM_IS_STRING(parsed_value)) - user->str_value = strdup(GEDCOM_STRING(parsed_value)); - else if (GEDCOM_IS_XREF_PTR(parsed_value)) - user->xref_value = GEDCOM_XREF_PTR(parsed_value); - - return (Gedcom_ctxt) MAKE_GOM_CTXT(rec, user_rec, ctxt); + return (Gedcom_ctxt)result; } GET_REC_BY_XREF(user_rec, XREF_USER, gom_get_user_rec_by_xref) @@ -89,72 +106,98 @@ GET_REC_BY_XREF(user_rec, XREF_USER, gom_get_user_rec_by_xref) Gedcom_ctxt user_elt_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; - struct user_data *data = (struct user_data *)malloc(sizeof(struct user_data)); - memset (data, 0, sizeof(struct user_data)); - - data->level = level; - data->tag = strdup(tag); - if (GEDCOM_IS_STRING(parsed_value)) - data->str_value = strdup(GEDCOM_STRING(parsed_value)); - else if (GEDCOM_IS_XREF_PTR(parsed_value)) - data->xref_value = GEDCOM_XREF_PTR(parsed_value); - - if (ctxt) { - switch (ctxt->obj_type) { - case T_header: - header_add_user_data(ctxt, data); break; - case T_submission: - submission_add_user_data(ctxt, data); break; - case T_submitter: - submitter_add_user_data(ctxt, data); break; - case T_family: - family_add_user_data(ctxt, data); break; - case T_individual: - individual_add_user_data(ctxt, data); break; - case T_multimedia: - multimedia_add_user_data(ctxt, data); break; - case T_note: - note_add_user_data(ctxt, data); break; - case T_repository: - repository_add_user_data(ctxt, data); break; - case T_source: - source_add_user_data(ctxt, data); break; - case T_user_rec: - user_rec_add_user_data(ctxt, data); break; - case T_address: - address_add_user_data(ctxt, data); break; - case T_event: - event_add_user_data(ctxt, data); break; - case T_place: - place_add_user_data(ctxt, data); break; - case T_source_citation: - citation_add_user_data(ctxt, data); break; - case T_note_sub: - note_sub_add_user_data(ctxt, data); break; - case T_multimedia_link: - multimedia_link_add_user_data(ctxt, data); break; - case T_lds_event: - lds_event_add_user_data(ctxt, data); break; - case T_user_ref_number: - user_ref_add_user_data(ctxt, data); break; - case T_change_date: - change_date_add_user_data(ctxt, data); break; - case T_personal_name: - name_add_user_data(ctxt, data); break; - case T_family_link: - family_link_add_user_data(ctxt, data); break; - case T_association: - association_add_user_data(ctxt, data); break; - case T_source_event: - source_event_add_user_data(ctxt, data); break; - case T_source_description: - source_description_add_user_data(ctxt, data); break; - default: - UNEXPECTED_CONTEXT(ctxt->ctxt_type); + Gom_ctxt result = NULL; + int err = 0; + + if (! ctxt) + NO_CONTEXT; + else { + struct user_data *data + = (struct user_data *)malloc(sizeof(struct user_data)); + + if (! data) + MEMORY_ERROR; + else { + memset (data, 0, sizeof(struct user_data)); + + data->level = level; + data->tag = strdup(tag); + if (! data->tag) { + MEMORY_ERROR; + free(data); + err = 1; + } + else if (GEDCOM_IS_STRING(parsed_value)) { + data->str_value = strdup(GEDCOM_STRING(parsed_value)); + if (! data->str_value) { + MEMORY_ERROR; + free(data->tag); + free(data->str_value); + err = 1; + } + } + else if (GEDCOM_IS_XREF_PTR(parsed_value)) + data->xref_value = GEDCOM_XREF_PTR(parsed_value); + + if (! err) { + switch (ctxt->obj_type) { + case T_header: + header_add_user_data(ctxt, data); break; + case T_submission: + submission_add_user_data(ctxt, data); break; + case T_submitter: + submitter_add_user_data(ctxt, data); break; + case T_family: + family_add_user_data(ctxt, data); break; + case T_individual: + individual_add_user_data(ctxt, data); break; + case T_multimedia: + multimedia_add_user_data(ctxt, data); break; + case T_note: + note_add_user_data(ctxt, data); break; + case T_repository: + repository_add_user_data(ctxt, data); break; + case T_source: + source_add_user_data(ctxt, data); break; + case T_user_rec: + user_rec_add_user_data(ctxt, data); break; + case T_address: + address_add_user_data(ctxt, data); break; + case T_event: + event_add_user_data(ctxt, data); break; + case T_place: + place_add_user_data(ctxt, data); break; + case T_source_citation: + citation_add_user_data(ctxt, data); break; + case T_note_sub: + note_sub_add_user_data(ctxt, data); break; + case T_multimedia_link: + multimedia_link_add_user_data(ctxt, data); break; + case T_lds_event: + lds_event_add_user_data(ctxt, data); break; + case T_user_ref_number: + user_ref_add_user_data(ctxt, data); break; + case T_change_date: + change_date_add_user_data(ctxt, data); break; + case T_personal_name: + name_add_user_data(ctxt, data); break; + case T_family_link: + family_link_add_user_data(ctxt, data); break; + case T_association: + association_add_user_data(ctxt, data); break; + case T_source_event: + source_event_add_user_data(ctxt, data); break; + case T_source_description: + source_description_add_user_data(ctxt, data); break; + default: + UNEXPECTED_CONTEXT(ctxt->ctxt_type); + } + result = make_gom_ctxt(elt, ctxt->obj_type, ctxt->ctxt_ptr); + } } } - return (Gedcom_ctxt) make_gom_ctxt(elt, ctxt->obj_type, ctxt->ctxt_ptr); + return (Gedcom_ctxt)result; } void user_rec_subscribe() @@ -166,21 +209,26 @@ void user_rec_subscribe() void user_rec_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct user_rec *obj = SAFE_CTXT_CAST(user_rec, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data); } void user_data_cleanup(struct user_data* data) { - SAFE_FREE(data->tag); - SAFE_FREE(data->str_value); + if (data) { + SAFE_FREE(data->tag); + SAFE_FREE(data->str_value); + } } void user_rec_cleanup(struct user_rec* rec) { - SAFE_FREE(rec->xrefstr); - SAFE_FREE(rec->tag); - SAFE_FREE(rec->str_value); - DESTROY_CHAIN_ELTS(user_data, rec->extra, user_data_cleanup); + if (rec) { + SAFE_FREE(rec->xrefstr); + SAFE_FREE(rec->tag); + SAFE_FREE(rec->str_value); + DESTROY_CHAIN_ELTS(user_data, rec->extra, user_data_cleanup); + } } void user_recs_cleanup() @@ -195,9 +243,11 @@ struct user_rec* gom_get_first_user_rec() struct user_rec* make_user_record(char* xrefstr) { - struct user_rec* rec; + struct user_rec* rec = NULL; MAKE_CHAIN_ELT(user_rec, gom_first_user_rec, rec); - if (xrefstr) + if (rec && xrefstr) { rec->xrefstr = strdup(xrefstr); + if (! rec->xrefstr) MEMORY_ERROR; + } return rec; } diff --git a/gom/user_ref.c b/gom/user_ref.c index d0bcc7e..e83c82d 100644 --- a/gom/user_ref.c +++ b/gom/user_ref.c @@ -38,32 +38,47 @@ Gedcom_ctxt sub_user_ref_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; - struct user_ref_number *refn = NULL; + Gom_ctxt result = NULL; - if (ctxt) { - refn = (struct user_ref_number *)malloc(sizeof(struct user_ref_number)); - memset (refn, 0, sizeof(struct user_ref_number)); - refn->value = strdup(GEDCOM_STRING(parsed_value)); + if (! ctxt) + NO_CONTEXT; + else { + struct user_ref_number *refn + = (struct user_ref_number *)malloc(sizeof(struct user_ref_number)); - switch (ctxt->ctxt_type) { - case REC_FAM: - family_add_user_ref(ctxt, refn); break; - case REC_INDI: - individual_add_user_ref(ctxt, refn); break; - case REC_OBJE: - multimedia_add_user_ref(ctxt, refn); break; - case REC_NOTE: - note_add_user_ref(ctxt, refn); break; - case REC_REPO: - repository_add_user_ref(ctxt, refn); break; - case REC_SOUR: - source_add_user_ref(ctxt, refn); break; - default: - UNEXPECTED_CONTEXT(ctxt->ctxt_type); + if (! refn) + MEMORY_ERROR; + else { + memset (refn, 0, sizeof(struct user_ref_number)); + refn->value = strdup(GEDCOM_STRING(parsed_value)); + if (! refn->value) { + MEMORY_ERROR; + free(refn); + } + else { + switch (ctxt->ctxt_type) { + case REC_FAM: + family_add_user_ref(ctxt, refn); break; + case REC_INDI: + individual_add_user_ref(ctxt, refn); break; + case REC_OBJE: + multimedia_add_user_ref(ctxt, refn); break; + case REC_NOTE: + note_add_user_ref(ctxt, refn); break; + case REC_REPO: + repository_add_user_ref(ctxt, refn); break; + case REC_SOUR: + source_add_user_ref(ctxt, refn); break; + default: + UNEXPECTED_CONTEXT(ctxt->ctxt_type); + } + + result = MAKE_GOM_CTXT(elt, user_ref_number, refn); + } } } - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, user_ref_number, refn); + return (Gedcom_ctxt)result; } STRING_CB(user_ref_number, sub_user_ref_type_start, type) @@ -71,7 +86,11 @@ STRING_CB(user_ref_number, sub_user_ref_type_start, type) Gedcom_ctxt sub_user_rin_start(_ELT_PARAMS_) { Gom_ctxt ctxt = (Gom_ctxt)parent; - if (ctxt) { + Gom_ctxt result = NULL; + + if (! ctxt) + NO_CONTEXT; + else { char *str = GEDCOM_STRING(parsed_value); switch (ctxt->ctxt_type) { @@ -90,8 +109,9 @@ Gedcom_ctxt sub_user_rin_start(_ELT_PARAMS_) default: UNEXPECTED_CONTEXT(ctxt->ctxt_type); } + result = make_gom_ctxt(elt, ctxt->obj_type, ctxt->ctxt_ptr); } - return (Gedcom_ctxt) make_gom_ctxt(elt, ctxt->obj_type, ctxt->ctxt_ptr); + return (Gedcom_ctxt)result; } void user_ref_subscribe() @@ -107,7 +127,8 @@ void user_ref_subscribe() void user_ref_add_user_data(Gom_ctxt ctxt, struct user_data* data) { struct user_ref_number *obj = SAFE_CTXT_CAST(user_ref_number, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (obj) + LINK_CHAIN_ELT(user_data, obj->extra, data); } void user_ref_cleanup(struct user_ref_number* refn) @@ -115,6 +136,6 @@ void user_ref_cleanup(struct user_ref_number* refn) if (refn) { SAFE_FREE(refn->value); SAFE_FREE(refn->type); - DESTROY_CHAIN_ELTS(user_data, refn->extra, user_data_cleanup) + DESTROY_CHAIN_ELTS(user_data, refn->extra, user_data_cleanup); } } -- 2.30.2