#define __FUNC_TEMPLATE_H
#define MAKEFUNC(STRUCTTYPE) make_ ## STRUCTTYPE ## _record
+#define SUB_MAKEFUNC(STRUCTTYPE) make_ ## STRUCTTYPE
#define DESTROYFUNC(STRUCTTYPE) destroy_ ## STRUCTTYPE ## _record
#define GETXREFFUNC(STRUCTTYPE) gom_get_ ## STRUCTTYPE ## _by_xref
#define CLEANFUNC(STRUCTTYPE) STRUCTTYPE ## _cleanup
-#define ADDFUNC(STRUCTTYPE) gom_add_ ## STRUCTTYPE
+#define ADDFUNC(STRUCTTYPE) gom_new_ ## STRUCTTYPE
+#define SUB_SETFUNC(STRUCTTYPE) gom_set_new_ ## STRUCTTYPE
+#define SUB_ADDFUNC(STRUCTTYPE) gom_add_new_ ## STRUCTTYPE
+#define UNREFALLFUNC(STRUCTTYPE) STRUCTTYPE ## _unref_all
#define DELETEFUNC(STRUCTTYPE) gom_delete_ ## STRUCTTYPE
+#define SUB_DELETEFUNC(STRUCTTYPE) gom_delete_ ## STRUCTTYPE
+#define SUB_FINDFUNC(STRUCTTYPE) find_ ## STRUCTTYPE
+#define SUB_REMOVEFUNC(STRUCTTYPE) gom_remove_ ## STRUCTTYPE
+#define SUB_MOVEFUNC(STRUCTTYPE) gom_move_ ## STRUCTTYPE
#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)
#define DECLARE_MAKEFUNC(STRUCTTYPE) \
struct STRUCTTYPE* MAKEFUNC(STRUCTTYPE)(const char* xref)
+#define DECLARE_SUB_MAKEFUNC(STRUCTTYPE) \
+ struct STRUCTTYPE* SUB_MAKEFUNC(STRUCTTYPE)()
+
#define DECLARE_CLEANFUNC(STRUCTTYPE) \
void CLEANFUNC(STRUCTTYPE)(struct STRUCTTYPE* obj)
+#define DECLARE_UNREFALLFUNC(STRUCTTYPE) \
+ void UNREFALLFUNC(STRUCTTYPE)(struct STRUCTTYPE* obj)
+
#define DECLARE_ADDFUNC2(STRUCTTYPE,T2) \
void ADDFUNC2(STRUCTTYPE,T2)(Gom_ctxt ctxt, struct T2* obj)
} \
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 MOVE_CHAIN_ELT(STRUCTTYPE, DIR, FIRSTVAL, VAL) \
+ { \
+ struct STRUCTTYPE *first, *second; \
+ if (DIR == MOVE_UP) { \
+ first = VAL->previous; \
+ second = VAL; \
+ } \
+ else { \
+ first = VAL; \
+ second = VAL->next; \
+ } \
+ if (second && (second != FIRSTVAL)) { \
+ if (first != FIRSTVAL) \
+ first->previous->next = second; \
+ else \
+ FIRSTVAL = second; \
+ \
+ if (second->next) \
+ second->next->previous = first; \
+ else \
+ (FIRSTVAL)->previous = first; \
+ \
+ first->next = second->next; \
+ second->next = first; \
+ \
+ second->previous = first->previous; \
+ first->previous = second; \
+ } \
+ else { \
+ gom_move_error(#STRUCTTYPE); \
+ } \
}
#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); \
return obj; \
}
+#define DEFINE_SUB_MAKEFUNC(STRUCTTYPE) \
+ struct STRUCTTYPE* SUB_MAKEFUNC(STRUCTTYPE)() { \
+ struct STRUCTTYPE* obj = NULL; \
+ obj = (struct STRUCTTYPE*) malloc(sizeof(struct STRUCTTYPE)); \
+ if (!obj) \
+ MEMORY_ERROR; \
+ else \
+ memset(obj, 0, sizeof(struct STRUCTTYPE)); \
+ return obj; \
+ }
+
#define DEFINE_DESTROYFUNC(STRUCTTYPE,FIRSTVAL) \
- void CLEANFUNC(STRUCTTYPE)(struct STRUCTTYPE* obj); \
+ DECLARE_CLEANFUNC(STRUCTTYPE); \
void DESTROYFUNC(STRUCTTYPE)(struct STRUCTTYPE* obj) { \
if (obj) { \
CLEANFUNC(STRUCTTYPE)(obj); \
UNLINK_CHAIN_ELT(STRUCTTYPE, FIRSTVAL, obj); \
- free(obj); \
+ SAFE_FREE(obj); \
} \
}
return obj; \
}
+#define DEFINE_SUB_SETFUNC(STRUCTTYPE) \
+ struct STRUCTTYPE *SUB_SETFUNC(STRUCTTYPE)(struct STRUCTTYPE** addto) \
+ { \
+ struct STRUCTTYPE *obj = NULL; \
+ if (addto && ! *addto) { \
+ obj = SUB_MAKEFUNC(STRUCTTYPE)(); \
+ if (obj) *addto = obj; \
+ } \
+ return obj; \
+ }
+
+#define DEFINE_SUB_ADDFUNC(STRUCTTYPE) \
+ struct STRUCTTYPE *SUB_ADDFUNC(STRUCTTYPE)(struct STRUCTTYPE** addto) \
+ { \
+ struct STRUCTTYPE *obj = NULL; \
+ if (addto) { \
+ MAKE_CHAIN_ELT(STRUCTTYPE, *addto, obj); \
+ } \
+ return obj; \
+ }
+
#define DEFINE_DELETEFUNC(STRUCTTYPE) \
+ DECLARE_UNREFALLFUNC(STRUCTTYPE); \
int DELETEFUNC(STRUCTTYPE)(struct STRUCTTYPE* obj) \
{ \
int result = 1; \
if (obj) { \
result = gedcom_delete_xref(obj->xrefstr); \
- if (result == 0) \
+ if (result == 0) { \
+ UNREFALLFUNC(STRUCTTYPE)(obj); \
DESTROYFUNC(STRUCTTYPE)(obj); \
+ } \
+ } \
+ return result; \
+ }
+
+#define DEFINE_SUB_DELETEFUNC(STRUCTTYPE) \
+ int SUB_DELETEFUNC(STRUCTTYPE)(struct STRUCTTYPE** obj) \
+ { \
+ int result = 1; \
+ if (obj && *obj) { \
+ UNREFALLFUNC(STRUCTTYPE)(*obj); \
+ CLEANFUNC(STRUCTTYPE)(*obj); \
+ SAFE_FREE(*obj); \
+ result = 0; \
+ } \
+ return result; \
+ }
+
+#define DEFINE_SUB_FINDFUNC(STRUCTTYPE) \
+ struct STRUCTTYPE* SUB_FINDFUNC(STRUCTTYPE)(struct STRUCTTYPE** data, \
+ struct STRUCTTYPE* obj) \
+ { \
+ struct STRUCTTYPE* result = NULL; \
+ struct STRUCTTYPE* runner; \
+ for (runner = *data ; runner ; runner = runner->next) { \
+ if (runner == obj) { \
+ result = runner; \
+ break; \
+ } \
+ } \
+ if (! result) \
+ gom_find_error(#STRUCTTYPE); \
+ return result; \
+ }
+
+#define DEFINE_SUB_REMOVEFUNC(STRUCTTYPE) \
+ int SUB_REMOVEFUNC(STRUCTTYPE) (struct STRUCTTYPE** data, \
+ struct STRUCTTYPE* obj) \
+ { \
+ int result = 1; \
+ if (data && obj) { \
+ struct STRUCTTYPE* toremove = SUB_FINDFUNC(STRUCTTYPE)(data, obj); \
+ if (toremove) { \
+ UNLINK_CHAIN_ELT(STRUCTTYPE, *data, toremove); \
+ CLEANFUNC(STRUCTTYPE)(toremove); \
+ SAFE_FREE(toremove); \
+ result = 0; \
+ } \
+ } \
+ return result; \
+ }
+
+#define DEFINE_SUB_MOVEFUNC(STRUCTTYPE) \
+ int SUB_MOVEFUNC(STRUCTTYPE)(Gom_direction dir, struct STRUCTTYPE** data, \
+ struct STRUCTTYPE* obj) \
+ { \
+ int result = 1; \
+ if (data && obj) { \
+ struct STRUCTTYPE* tomove = SUB_FINDFUNC(STRUCTTYPE)(data, obj); \
+ if (tomove) { \
+ MOVE_CHAIN_ELT(STRUCTTYPE, dir, *data, tomove); \
+ result = 0; \
+ } \
} \
return result; \
}
else \
obj->FIELD = newvalue; \
} \
- destroy_gom_ctxt(ctxt); \
+ def_elt_end(elt, parent, self, parsed_value); \
} \
}
else \
obj->FIELD = newvalue; \
} \
- destroy_gom_ctxt(ctxt); \
+ def_rec_end(rec, self, parsed_value); \
} \
}