#include <stdlib.h>
#include <string.h>
#include <libintl.h>
+#include <time.h>
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
#include "gom.h"
#include "gedcom.h"
-#ifdef WITH_DMALLOC
-#include <dmalloc.h>
-#endif
-#define _(string) gettext(string)
+#define _(string) dgettext(PACKAGE, string)
#define N_(string) (string)
+#ifdef __GNUC__
+#define UNUSED __attribute__((unused))
+#else
+#define UNUSED
+#endif
+
typedef enum {
T_NULL,
T_address, T_event, T_place, T_source_citation, T_text,
T_note_sub, T_multimedia_link, T_lds_event, T_user_ref_number,
T_change_date, T_personal_name, T_family_link, T_pedigree,
- T_association, T_source_event, T_source_description
-} OBJ_TYPE;
+ T_association, T_source_event, T_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
-*/
-
-struct Gom_ctxt_struct {
- int ctxt_type;
- OBJ_TYPE obj_type;
- void* ctxt_ptr;
-};
+ T_LAST
+} OBJ_TYPE;
+struct Gom_ctxt_struct;
typedef struct Gom_ctxt_struct *Gom_ctxt;
Gom_ctxt make_gom_ctxt(int ctxt_type, OBJ_TYPE obj_type, void *ctxt_ptr);
-void destroy_gom_ctxt(Gom_ctxt ctxt);
-void gom_cast_error(char* file, int line, OBJ_TYPE expected, OBJ_TYPE found);
-void gom_no_context(char* file, int line);
-void gom_unexpected_context(char* file, int line, OBJ_TYPE found);
+Gom_ctxt dup_gom_ctxt(Gom_ctxt ctxt, int ctxt_type);
+void* safe_ctxt_cast(Gom_ctxt ctxt, OBJ_TYPE type, const char* file, int line);
+int ctxt_type(Gom_ctxt ctxt);
+OBJ_TYPE ctxt_obj_type(Gom_ctxt ctxt);
+
+void gom_cast_error(const char* file, int line,
+ OBJ_TYPE expected, OBJ_TYPE found);
+void gom_no_context(const char* file, int line);
+void gom_unexpected_context(const char* file, int line, OBJ_TYPE found);
+void gom_xref_already_in_use(const char *xrefstr);
+void gom_move_error(const char* type);
+void gom_find_error(const char* type);
+void unref_xref_value(struct xref_value *xref);
+
+int gom_write_xref_list(Gedcom_write_hndl hndl,
+ Gedcom_elt elt, int tag, int parent_rec_or_elt,
+ struct xref_list* val);
#define MAKE_GOM_CTXT(CTXT_TYPE, STRUCTTYPE, CTXT_PTR) \
make_gom_ctxt(CTXT_TYPE, T_ ## STRUCTTYPE, CTXT_PTR)
#define SAFE_CTXT_CAST(STRUCTTYPE, VAL) \
- (((VAL)->obj_type == T_ ## STRUCTTYPE) ? \
- (VAL)->ctxt_ptr : \
- (gom_cast_error(__FILE__, __LINE__, T_ ## STRUCTTYPE, (VAL)->obj_type), \
- (VAL)->ctxt_ptr))
+ safe_ctxt_cast(VAL, T_ ## STRUCTTYPE, __FILE__, __LINE__)
#define SAFE_FREE(PTR) \
if (PTR) { \
#define NO_CONTEXT \
gom_no_context(__FILE__, __LINE__)
-void gom_mem_error(char *filename, int line);
+void gom_mem_error(const char *filename, int line);
#define MEMORY_ERROR gom_mem_error(__FILE__, __LINE__)
-void def_rec_end(Gedcom_rec rec, Gedcom_ctxt self);
-void def_elt_end(Gedcom_elt elt, Gedcom_ctxt parent, Gedcom_ctxt self,
- Gedcom_val parsed_value);
-void set_xref_type(struct xref_value *xr, char* str);
-
-typedef enum {
- WITHOUT_NL,
- WITH_NL
-} NL_TYPE;
+void def_rec_end(Gedcom_rec rec, Gedcom_ctxt self, Gedcom_val parsed_value);
+void def_elt_end(Gedcom_elt elt, Gedcom_ctxt parent,
+ Gedcom_ctxt self, Gedcom_val parsed_value);
+void set_xref_type(struct xref_value *xr, const char* str);
-char* concat_strings(NL_TYPE type, char *str1, const char *str2);
-struct date_value* dup_date(struct date_value dv);
-struct age_value* dup_age(struct age_value age);
-
-/* Doubly-linked list, but last rec->next is NULL (doesn't go to first rec) */
-#define LINK_CHAIN_ELT(STRUCTTYPE, FIRSTVAL, VAL) \
- { \
- struct STRUCTTYPE *_local_obj = VAL; \
- if (! FIRSTVAL) { \
- VAL->next = NULL; \
- VAL->previous = _local_obj; \
- FIRSTVAL = VAL; \
- } \
- else { \
- VAL->next = NULL; \
- FIRSTVAL->previous->next = VAL; \
- VAL->previous = FIRSTVAL->previous; \
- FIRSTVAL->previous = VAL; \
- } \
- }
-
-#define MAKE_CHAIN_ELT(STRUCTTYPE, FIRSTVAL, VAL) \
- { \
- VAL = (struct STRUCTTYPE*) malloc(sizeof(struct STRUCTTYPE)); \
- if (! VAL) \
- MEMORY_ERROR; \
- else { \
- memset (VAL, 0, sizeof(struct STRUCTTYPE)); \
- LINK_CHAIN_ELT(STRUCTTYPE, FIRSTVAL, VAL) \
- } \
- }
+int update_date(struct date_value** dv, struct tm* tm_ptr);
+int update_time(char** tv, struct tm* tm_ptr);
void NULL_DESTROY(void* anything);
-#define DESTROY_CHAIN_ELTS(STRUCTTYPE, FIRSTVAL, DESTROYFUNC) \
- { \
- if (FIRSTVAL) { \
- struct STRUCTTYPE *runner, *next; \
- runner = FIRSTVAL; \
- while (runner) { \
- next = runner->next; \
- DESTROYFUNC(runner); \
- SAFE_FREE(runner); \
- runner = next; \
- } \
- } \
- }
-
-#define _REC_PARAMS_ Gedcom_rec rec, int level, Gedcom_val xref, char *tag, \
- char *raw_value, int parsed_tag, Gedcom_val parsed_value
-
-#define _ELT_PARAMS_ Gedcom_elt elt, Gedcom_ctxt parent, int level, char *tag,\
- char *raw_value, int parsed_tag, Gedcom_val parsed_value
-
-#define REC_CB(STRUCTTYPE,CB_NAME,FUNC) \
- Gedcom_ctxt CB_NAME(_REC_PARAMS_) \
- { \
- struct xref_value* xr = GEDCOM_XREF_PTR(xref); \
- if (! xr->object) \
- xr->object = (Gedcom_ctxt) FUNC(xr->string); \
- if (xr->object) \
- return (Gedcom_ctxt) MAKE_GOM_CTXT(rec, STRUCTTYPE, xr->object); \
- else \
- return NULL; \
- }
-
-#define GET_REC_BY_XREF(STRUCTTYPE,XREF_TYPE,FUNC_NAME) \
- struct STRUCTTYPE *FUNC_NAME(char *xrefstr) \
- { \
- struct xref_value* xr = gedcom_get_by_xref(xrefstr); \
- if (xr && (xr->type == XREF_TYPE) && xr->object) \
- return (struct STRUCTTYPE*)(xr->object); \
- else \
- return NULL; \
- }
-
-#define STRING_CB(STRUCTTYPE,CB_NAME,FIELD) \
- Gedcom_ctxt CB_NAME(_ELT_PARAMS_) \
- { \
- Gom_ctxt result = NULL; \
- if (! parent) \
- NO_CONTEXT; \
- else { \
- struct STRUCTTYPE *obj \
- = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \
- if (obj) { \
- char *str = GEDCOM_STRING(parsed_value); \
- obj->FIELD = strdup(str); \
- if (! obj->FIELD) \
- MEMORY_ERROR; \
- else \
- result = MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \
- } \
- } \
- return (Gedcom_ctxt)result; \
- }
-
-#define DATE_CB(STRUCTTYPE,CB_NAME,FIELD) \
- Gedcom_ctxt CB_NAME(_ELT_PARAMS_) \
- { \
- Gom_ctxt result = NULL; \
- if (! parent) \
- NO_CONTEXT; \
- else { \
- struct STRUCTTYPE *obj \
- = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \
- if (obj) { \
- struct date_value dv = GEDCOM_DATE(parsed_value); \
- obj->FIELD = dup_date(dv); \
- if (! obj->FIELD) \
- MEMORY_ERROR; \
- else \
- result = MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \
- } \
- } \
- return (Gedcom_ctxt)result; \
- }
-
-#define AGE_CB(STRUCTTYPE,CB_NAME,FIELD) \
- Gedcom_ctxt CB_NAME(_ELT_PARAMS_) \
- { \
- Gom_ctxt result = NULL; \
- if (! parent) \
- NO_CONTEXT; \
- else { \
- struct STRUCTTYPE *obj \
- = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \
- if (obj) { \
- struct age_value age = GEDCOM_AGE(parsed_value); \
- obj->FIELD = dup_age(age); \
- if (! obj->FIELD) \
- MEMORY_ERROR; \
- else \
- result = MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \
- } \
- } \
- return (Gedcom_ctxt)result; \
- }
-
-#define XREF_CB(STRUCTTYPE,CB_NAME,FIELD,FUNC) \
- Gedcom_ctxt CB_NAME(_ELT_PARAMS_) \
- { \
- Gom_ctxt result = NULL; \
- if (! parent) \
- NO_CONTEXT; \
- else { \
- struct STRUCTTYPE *obj \
- = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \
- struct xref_value *xr = GEDCOM_XREF_PTR(parsed_value); \
- if (! xr->object) \
- xr->object = (Gedcom_ctxt) FUNC(xr->string); \
- if (obj) { \
- obj->FIELD = xr; \
- result = MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \
- } \
- } \
- return (Gedcom_ctxt)result; \
- }
-
-#define XREF_LIST_CB(STRUCTTYPE,CB_NAME,FIELD,FUNC) \
- Gedcom_ctxt CB_NAME(_ELT_PARAMS_) \
- { \
- Gom_ctxt result = NULL; \
- if (! parent) \
- NO_CONTEXT; \
- else { \
- struct STRUCTTYPE *obj \
- = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \
- struct xref_value *xr = GEDCOM_XREF_PTR(parsed_value); \
- struct xref_list *xrl; \
- if (! xr->object) \
- xr->object = (Gedcom_ctxt) FUNC(xr->string); \
- if (obj) { \
- MAKE_CHAIN_ELT(xref_list, obj->FIELD, xrl); \
- if (xrl) { \
- xrl->xref = xr; \
- result = MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \
- } \
- } \
- } \
- return (Gedcom_ctxt)result; \
- }
-
-#define NULL_CB(STRUCTTYPE,CB_NAME) \
- Gedcom_ctxt CB_NAME(_ELT_PARAMS_) \
- { \
- Gom_ctxt result = NULL; \
- if (! parent) \
- NO_CONTEXT; \
- else { \
- struct STRUCTTYPE *obj \
- = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \
- if (obj) \
- result = MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \
- } \
- return (Gedcom_ctxt)result; \
- }
+#include "func_template.h"
+DECLARE_UNREFALLFUNC(xref_list);
+DECLARE_CLEANFUNC(xref_list);
+
#endif /* __GOM_INTERNAL_H */