DEFINE_ADDFUNC(family, XREF_FAM)
DEFINE_DELETEFUNC(family)
DEFINE_GETXREFFUNC(family, XREF_FAM)
-DEFINE_MAKELINKFUNC(family, XREF_FAM)
DEFINE_REC_CB(family, fam_start)
DEFINE_XREF_CB(family, fam_husb_start, husband, individual)
#define SUB_ADDFUNC(STRUCTTYPE) gom_add_ ## STRUCTTYPE
#define DELETEFUNC(STRUCTTYPE) gom_delete_ ## STRUCTTYPE
#define SUB_DELETEFUNC(STRUCTTYPE) gom_delete_ ## STRUCTTYPE
-#define MAKELINKFUNC(STRUCTTYPE) gom_make_ ## STRUCTTYPE ## _link
#define ADDFUNC2(T1,T2) T1 ## _add_ ## T2
#define ADDFUNC2_TOVAR(T1,T2,F) T1 ## _add_ ## T2 ## _to_ ## F
#define ADDFUNC2_NOLIST(T1,T2) ADDFUNC2(T1,T2)
} \
else { \
VAL->next = NULL; \
- FIRSTVAL->previous->next = VAL; \
- VAL->previous = FIRSTVAL->previous; \
- FIRSTVAL->previous = VAL; \
+ (FIRSTVAL)->previous->next = VAL; \
+ VAL->previous = (FIRSTVAL)->previous; \
+ (FIRSTVAL)->previous = VAL; \
} \
}
VAL->previous->next = VAL->next; \
if (VAL->next) \
VAL->next->previous = VAL->previous; \
+ else if (FIRSTVAL) \
+ (FIRSTVAL)->previous = VAL->previous; \
}
#define MAKE_CHAIN_ELT(STRUCTTYPE, FIRSTVAL, VAL) \
if (FIRSTVAL) { \
struct STRUCTTYPE *runner, *next; \
runner = FIRSTVAL; \
+ FIRSTVAL = NULL; \
while (runner) { \
next = runner->next; \
CLEANFUNC(STRUCTTYPE)(runner); \
if (obj) { \
CLEANFUNC(STRUCTTYPE)(obj); \
UNLINK_CHAIN_ELT(STRUCTTYPE, FIRSTVAL, obj); \
- free(obj); \
+ SAFE_FREE(obj); \
} \
}
return obj; \
}
+/* TODO: Check whether there are still xrefs linked in */
#define DEFINE_DELETEFUNC(STRUCTTYPE) \
int DELETEFUNC(STRUCTTYPE)(struct STRUCTTYPE* obj) \
{ \
int result = 1; \
if (obj && *obj) { \
CLEANFUNC(STRUCTTYPE)(*obj); \
- free(*obj); \
- *obj = NULL; \
+ SAFE_FREE(*obj); \
result = 0; \
} \
return result; \
}
-#define DEFINE_MAKELINKFUNC(STRUCTTYPE,XREF_TYPE) \
- struct xref_value* MAKELINKFUNC(STRUCTTYPE)(struct STRUCTTYPE* obj) \
- { \
- struct xref_value* xr = NULL; \
- if (obj && obj->xrefstr) { \
- xr = gedcom_get_by_xref(obj->xrefstr); \
- } \
- return xr; \
- }
-
#define DEFINE_ADDFUNC2(STRUCTTYPE,T2,FIELD) \
void ADDFUNC2(STRUCTTYPE,T2)(Gom_ctxt ctxt, struct T2* addobj) \
{ \
void NULL_DESTROY(void* anything);
-#define xref_list_cleanup NULL_DESTROY
-
#include "func_template.h"
+DECLARE_CLEANFUNC(xref_list);
+
#endif /* __GOM_INTERNAL_H */
#include <stdlib.h>
#include <string.h>
#include "utf8tools.h"
+#include "user_rec.h"
#include "gom.h"
#include "gom_internal.h"
return result;
}
-struct xref_value* gom_set_xref_value(struct xref_value** data,
- struct xref_value* newval)
+void CLEANFUNC(xref_list)(struct xref_list *obj)
+{
+ if (obj) {
+ DESTROY_CHAIN_ELTS(user_data, obj->extra);
+ }
+}
+
+struct xref_value* gom_set_xref(struct xref_value** data, const char* xref)
{
struct xref_value* result = NULL;
+ struct xref_value* newval = NULL;
+
if (data) {
+ if (xref) {
+ newval = gedcom_get_by_xref(xref);
+ if (!newval)
+ gedcom_error(_("No record found for xref '%s'"), xref);
+ }
+
/* Unreference the old value if not NULL */
if (*data)
result = gedcom_unlink_xref((*data)->type, (*data)->string);
else
result = newval;
-
+
/* Reference the new value if not NULL */
if (result != NULL && newval) {
result = gedcom_link_xref(newval->type, newval->string);
}
return result;
}
+
+struct xref_list* gom_add_xref(struct xref_list** data, const char* xref)
+{
+ struct xref_value* result = NULL;
+ struct xref_value* newval = NULL;
+ struct xref_list* xrl = NULL;
+
+ if (data && xref) {
+ newval = gedcom_get_by_xref(xref);
+ if (!newval)
+ gedcom_error(_("No record found for xref '%s'"), xref);
+ else {
+ result = gedcom_link_xref(newval->type, newval->string);
+ if (result != NULL) {
+ MAKE_CHAIN_ELT(xref_list, *data, xrl);
+ if (xrl) xrl->xref = newval;
+ }
+ }
+ }
+
+ return xrl;
+}
+
+int gom_remove_xref(struct xref_list** data, const char* xref)
+{
+ struct xref_value* xr = NULL;
+ int result = 1;
+
+ if (data && xref) {
+ xr = gedcom_get_by_xref(xref);
+ if (!xr)
+ gedcom_error(_("No record found for xref '%s'"), xref);
+ else {
+ struct xref_list* xrl = NULL;
+ for (xrl = *data ; xrl ; xrl = xrl->next) {
+ if (xrl->xref == xr) {
+ UNLINK_CHAIN_ELT(xref_list, *data, xrl);
+ gedcom_unlink_xref(xr->type, xr->string);
+ CLEANFUNC(xref_list)(xrl);
+ SAFE_FREE(xrl);
+ result = 0;
+ break;
+ }
+ }
+ if (result == 1)
+ gedcom_error(_("Xref '%s' to remove not part of chain"), xref);
+ }
+ }
+
+ return result;
+}
DEFINE_ADDFUNC(individual, XREF_INDI)
DEFINE_DELETEFUNC(individual)
DEFINE_GETXREFFUNC(individual, XREF_INDI)
-DEFINE_MAKELINKFUNC(individual, XREF_INDI)
DEFINE_REC_CB(individual, indi_start)
DEFINE_STRING_CB(individual, indi_resn_start, restriction_notice)
DEFINE_ADDFUNC(multimedia, XREF_OBJE)
DEFINE_DELETEFUNC(multimedia)
DEFINE_GETXREFFUNC(multimedia, XREF_OBJE)
-DEFINE_MAKELINKFUNC(multimedia, XREF_OBJE)
DEFINE_REC_CB(multimedia, obje_start)
DEFINE_STRING_CB(multimedia, obje_form_start, form)
DEFINE_ADDFUNC(note, XREF_NOTE)
DEFINE_DELETEFUNC(note)
DEFINE_GETXREFFUNC(note, XREF_NOTE)
-DEFINE_MAKELINKFUNC(note, XREF_NOTE)
DEFINE_STRING_END_REC_CB(note, note_end, text)
DEFINE_ADDFUNC(repository, XREF_REPO)
DEFINE_DELETEFUNC(repository)
DEFINE_GETXREFFUNC(repository, XREF_REPO)
-DEFINE_MAKELINKFUNC(repository, XREF_REPO)
DEFINE_REC_CB(repository, repo_start)
DEFINE_STRING_CB(repository, repo_name_start, name)
DEFINE_ADDFUNC(source, XREF_SOUR)
DEFINE_DELETEFUNC(source)
DEFINE_GETXREFFUNC(source, XREF_SOUR)
-DEFINE_MAKELINKFUNC(source, XREF_SOUR)
DEFINE_REC_CB(source, sour_start)
DEFINE_NULL_CB(source, sour_data_start)
struct submission* gom_submission = NULL;
-DEFINE_MAKELINKFUNC(submission, XREF_SUBN)
-
DEFINE_REC_CB(submission, subn_start)
DEFINE_XREF_CB(submission, subn_subm_start, submitter, submitter)
DEFINE_STRING_CB(submission, subn_famf_start, family_file)
DEFINE_ADDFUNC(submitter, XREF_SUBM)
DEFINE_DELETEFUNC(submitter)
DEFINE_GETXREFFUNC(submitter, XREF_SUBM)
-DEFINE_MAKELINKFUNC(submitter, XREF_SUBM)
DEFINE_REC_CB(submitter, subm_start)
DEFINE_STRING_CB(submitter, subm_name_start, name)