+#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; \
+ }
+