X-Git-Url: https://git.dlugolecki.net.pl/?a=blobdiff_plain;f=gom%2Fgom_internal.c;h=48e9d62e581280053a2c54dd7794502004f7e5a0;hb=60162324857b1e8d84b8346d99f8b7dce07d0d40;hp=359ec871a00a36307aca591b0e4b690f977de396;hpb=381d8830b72c656367e4acea20f0a53fb61735d5;p=gedcom-parse.git diff --git a/gom/gom_internal.c b/gom/gom_internal.c index 359ec87..48e9d62 100644 --- a/gom/gom_internal.c +++ b/gom/gom_internal.c @@ -37,6 +37,24 @@ const char* ctxt_names[] = "association", "source_event", "source_description" }; +/* 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 + + The context chain keeps contexts until the end of the record, so that + elements out of context can be handled. +*/ + +struct Gom_ctxt_struct { + int ctxt_type; + OBJ_TYPE obj_type; + void* ctxt_ptr; + struct Gom_ctxt_struct* next; +}; + +struct Gom_ctxt_struct* ctxt_chain = NULL; + Gom_ctxt make_gom_ctxt(int ctxt_type, OBJ_TYPE obj_type, void *ctxt_ptr) { Gom_ctxt ctxt = (Gom_ctxt)malloc(sizeof(struct Gom_ctxt_struct)); @@ -46,10 +64,35 @@ Gom_ctxt make_gom_ctxt(int ctxt_type, OBJ_TYPE obj_type, void *ctxt_ptr) ctxt->ctxt_type = ctxt_type; ctxt->obj_type = obj_type; ctxt->ctxt_ptr = ctxt_ptr; + ctxt->next = ctxt_chain; + ctxt_chain = ctxt; } return ctxt; } +Gom_ctxt dup_gom_ctxt(Gom_ctxt ctxt, int ctxt_type) +{ + return make_gom_ctxt(ctxt_type, ctxt->obj_type, ctxt->ctxt_ptr); +} + +int ctxt_type(Gom_ctxt ctxt) +{ + return ctxt->ctxt_type; +} + +OBJ_TYPE ctxt_obj_type(Gom_ctxt ctxt) +{ + return ctxt->obj_type; +} + +void* safe_ctxt_cast(Gom_ctxt ctxt, OBJ_TYPE type, const char* file, int line) +{ + if (ctxt->obj_type != type) { + gom_cast_error(file, line, type, ctxt->obj_type); + } + return ctxt->ctxt_ptr; +} + void NULL_DESTROY(void* anything UNUSED) { } @@ -74,16 +117,6 @@ void gom_cast_error(const char* file, int line, abort(); } -void gom_mem_error(const char *filename, int line) -{ - gedcom_error(_("Could not allocate memory at %s, %d"), filename, line); -} - -void gom_xref_already_in_use(const char *xrefstr) -{ - gedcom_error(_("Cross-reference key '%s' is already in use"), xrefstr); -} - void gom_unexpected_context(const char* file, int line, OBJ_TYPE found) { const char* found_name = ""; @@ -99,27 +132,18 @@ void gom_no_context(const char* file, int line) file, line); } -void gom_move_error(const char* type) -{ - gedcom_warning(_("Could not move struct of type %s"), type); -} - -void gom_find_error(const char* type) -{ - gedcom_warning(_("Could not find struct of type %s in chain"), type); -} - -void def_rec_end(Gedcom_rec rec UNUSED, Gedcom_ctxt self, +void def_rec_end(Gedcom_rec rec UNUSED, Gedcom_ctxt self UNUSED, Gedcom_val parsed_value UNUSED) { - Gom_ctxt ctxt = (Gom_ctxt)self; - destroy_gom_ctxt(ctxt); + Gom_ctxt ctxt; + while (ctxt_chain) { + ctxt = ctxt_chain; + ctxt_chain = ctxt->next; + destroy_gom_ctxt(ctxt); + } } -/* TODO: do this in a way so that elements out of context can be handled */ void def_elt_end(Gedcom_elt elt UNUSED, Gedcom_ctxt parent UNUSED, - Gedcom_ctxt self, Gedcom_val parsed_value UNUSED) + Gedcom_ctxt self UNUSED, Gedcom_val parsed_value UNUSED) { - Gom_ctxt ctxt = (Gom_ctxt)self; - destroy_gom_ctxt(ctxt); }