X-Git-Url: https://git.dlugolecki.net.pl/?a=blobdiff_plain;f=gom%2Fsource_citation.c;h=406972a7b57a5df92eceee4765bb2e44fe8b2f7f;hb=866835ac8928d7e40919c2ca59799cb37023856f;hp=470812925bf041d59aba517b1cad8243ab77076f;hpb=7ea4ef8cae7b52f2bf66371a5e7b493cbd12900e;p=gedcom-parse.git diff --git a/gom/source_citation.c b/gom/source_citation.c index 4708129..406972a 100644 --- a/gom/source_citation.c +++ b/gom/source_citation.c @@ -42,72 +42,119 @@ 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 = SUB_MAKEFUNC(source_citation)(); + if (cit) { + int type = ctxt_type(ctxt); + if (GEDCOM_IS_XREF_PTR(parsed_value)) + cit->reference = GEDCOM_XREF_PTR(parsed_value); + + switch (type) { + case ELT_SUB_PLAC: + ADDFUNC2(place,source_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: + ADDFUNC2(event,source_citation)(ctxt, cit); break; + case ELT_SUB_NOTE: + ADDFUNC2(note_sub,source_citation)(ctxt, cit); break; + case ELT_SUB_LSS_SLGS: + case ELT_SUB_LIO_BAPL: + case ELT_SUB_LIO_SLGC: + ADDFUNC2(lds_event,source_citation)(ctxt, cit); break; + case REC_FAM: + ADDFUNC2(family,source_citation)(ctxt, cit); break; + case ELT_SUB_PERS_NAME: + ADDFUNC2(personal_name,source_citation)(ctxt, cit); break; + case REC_INDI: + ADDFUNC2(individual,source_citation)(ctxt, cit); break; + case ELT_SUB_ASSO: + ADDFUNC2(association,source_citation)(ctxt, cit); break; + case REC_NOTE: + ADDFUNC2(note,source_citation)(ctxt, cit); break; + default: + UNEXPECTED_CONTEXT(type); + } + result = MAKE_GOM_CTXT(elt, source_citation, cit); } } - return (Gedcom_ctxt) MAKE_GOM_CTXT(elt, source_citation, cit); + return (Gedcom_ctxt)result; +} + +void sub_citation_end(_ELT_END_PARAMS_) +{ + Gom_ctxt ctxt = (Gom_ctxt)self; + + if (! ctxt) + NO_CONTEXT; + else { + if (GEDCOM_IS_STRING(parsed_value)) { + struct source_citation *cit = SAFE_CTXT_CAST(source_citation, ctxt); + if (cit) { + char *str = GEDCOM_STRING(parsed_value); + char *newvalue = strdup(str); + if (! newvalue) + MEMORY_ERROR; + else + cit->description = newvalue; + } + } + def_elt_end(elt, parent, self, parsed_value); + } } 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) + result = MAKE_GOM_CTXT(elt, text, t); + } + } + + return (Gedcom_ctxt)result; } -STRING_CB(source_citation, sub_cit_page_start, page) -STRING_CB(source_citation, sub_cit_even_start, event) -STRING_CB(source_citation, sub_cit_even_role_start, role) -NULL_CB(source_citation, sub_cit_data_start) -DATE_CB(source_citation, sub_cit_data_date_start, date) -STRING_CB(source_citation, sub_cit_quay_start, quality) +DEFINE_SUB_MAKEFUNC(source_citation) +DEFINE_SUB_ADDFUNC(source_citation) +DEFINE_SUB_FINDFUNC(source_citation) +DEFINE_SUB_REMOVEFUNC(source_citation) +DEFINE_SUB_MOVEFUNC(source_citation) + +DEFINE_STRING_CB(source_citation, sub_cit_page_start, page) +DEFINE_STRING_CB(source_citation, sub_cit_even_start, event) +DEFINE_STRING_CB(source_citation, sub_cit_even_role_start, role) +DEFINE_NULL_CB(source_citation, sub_cit_data_start) +DEFINE_DATE_CB(source_citation, sub_cit_data_date_start, date) +DEFINE_STRING_CB(source_citation, sub_cit_quay_start, quality) +DEFINE_STRING_END_CB(text, sub_cit_text_end, text) + +DEFINE_ADDFUNC2(source_citation, note_sub, note) +DEFINE_ADDFUNC2(source_citation, multimedia_link, mm_link) +DEFINE_ADDFUNC2(source_citation, user_data, extra) void citation_subscribe() { - gedcom_subscribe_to_element(ELT_SUB_SOUR, sub_citation_start, def_elt_end); + gedcom_subscribe_to_element(ELT_SUB_SOUR, sub_citation_start, + sub_citation_end); gedcom_subscribe_to_element(ELT_SUB_SOUR_PAGE, sub_cit_page_start, def_elt_end); gedcom_subscribe_to_element(ELT_SUB_SOUR_EVEN, sub_cit_even_start, @@ -119,49 +166,48 @@ void citation_subscribe() gedcom_subscribe_to_element(ELT_SUB_SOUR_DATA_DATE, sub_cit_data_date_start, def_elt_end); gedcom_subscribe_to_element(ELT_SUB_SOUR_TEXT, sub_cit_text_start, - def_elt_end); + sub_cit_text_end); gedcom_subscribe_to_element(ELT_SUB_SOUR_QUAY, sub_cit_quay_start, def_elt_end); } -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) -} - -void citation_add_mm_link(Gom_ctxt ctxt, struct multimedia_link* mm) +void UNREFALLFUNC(text)(struct text* obj) { - struct source_citation *cit = SAFE_CTXT_CAST(source_citation, ctxt); - 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); -} - -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 (obj) { + struct text* runner; + for (runner = obj; runner; runner = runner->next) + UNREFALLFUNC(user_data)(runner->extra); + } } -void citation_add_user_data(Gom_ctxt ctxt, struct user_data* data) +void CLEANFUNC(text)(struct text* t) { - struct source_citation *obj = SAFE_CTXT_CAST(source_citation, ctxt); - LINK_CHAIN_ELT(user_data, obj->extra, data) + if (t) { + SAFE_FREE(t->text); + } } -void text_cleanup(struct text* t) +DEFINE_SUB_MAKEFUNC(text) +DEFINE_SUB_ADDFUNC(text) +DEFINE_SUB_FINDFUNC(text) +DEFINE_SUB_REMOVEFUNC(text) +DEFINE_SUB_MOVEFUNC(text) + +void UNREFALLFUNC(source_citation)(struct source_citation* obj) { - if (t) { - SAFE_FREE(t->text); + if (obj) { + struct source_citation* runner; + for (runner = obj; runner; runner = runner->next) { + unref_xref_value(runner->reference); + UNREFALLFUNC(text)(runner->text); + UNREFALLFUNC(multimedia_link)(runner->mm_link); + UNREFALLFUNC(note_sub)(runner->note); + UNREFALLFUNC(user_data)(runner->extra); + } } } -void citation_cleanup(struct source_citation* cit) +void CLEANFUNC(source_citation)(struct source_citation* cit) { if (cit) { SAFE_FREE(cit->description); @@ -169,10 +215,77 @@ 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); 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); + DESTROY_CHAIN_ELTS(note_sub, cit->note); + DESTROY_CHAIN_ELTS(user_data, cit->extra); + } +} + +int write_texts(Gedcom_write_hndl hndl, int parent, struct text* t) +{ + int result = 0; + struct text* obj; + + if (!t) return 1; + + for (obj = t; obj; obj = obj->next) { + result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_TEXT, 0, parent, + obj->text); + if (obj->extra) + result |= write_user_data(hndl, obj->extra); + } + + return result; +} + +int write_citations(Gedcom_write_hndl hndl, int parent, + struct source_citation* cit) +{ + int result = 0; + struct source_citation* obj; + + if (!cit) return 1; + + for (obj = cit; obj; obj = obj->next) { + if (obj->reference) { + result |= gedcom_write_element_xref(hndl, ELT_SUB_SOUR, 0, parent, + obj->reference); + if (obj->page) + result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_PAGE, 0, + ELT_SUB_SOUR, obj->page); + if (obj->event) + result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_EVEN, 0, + ELT_SUB_SOUR, obj->event); + if (obj->role) + result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_EVEN_ROLE, 0, + ELT_SUB_SOUR_EVEN, obj->role); + if (obj->date || obj->text) + result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_DATA, 0, + ELT_SUB_SOUR, NULL); + if (obj->date) + result |= gedcom_write_element_date(hndl, ELT_SUB_SOUR_DATA_DATE, 0, + ELT_SUB_SOUR_DATA, obj->date); + if (obj->text) + result |= write_texts(hndl, ELT_SUB_SOUR_DATA, obj->text); + if (obj->quality) + result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_QUAY, 0, + ELT_SUB_SOUR, obj->quality); + if (obj->mm_link) + result |= write_multimedia_links(hndl, ELT_SUB_SOUR, obj->mm_link); + } + else { + result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR, 0, parent, + obj->description); + if (obj->text) + result |= write_texts(hndl, ELT_SUB_SOUR, obj->text); + } + if (obj->note) + result |= write_note_subs(hndl, ELT_SUB_SOUR, obj->note); + if (obj->extra) + result |= write_user_data(hndl, obj->extra); } + + return result; }