1 /* General header for the Gedcom object model.
2 Copyright (C) 2002 The Genes Development Team
3 This file is part of the Gedcom parser library.
4 Contributed by Peter Verthez <Peter.Verthez@advalvas.be>, 2002.
6 The Gedcom parser library is free software; you can redistribute it
7 and/or modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The Gedcom parser library is distributed in the hope that it will be
12 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the Gedcom parser library; if not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 #ifndef __GOM_INTERNAL_H
25 #define __GOM_INTERNAL_H
37 #define _(string) dgettext(PACKAGE, string)
38 #define N_(string) (string)
41 #define UNUSED __attribute__((unused))
49 T_header, T_submission, T_submitter, T_family, T_individual,
50 T_multimedia, T_note, T_repository, T_source, T_user_rec,
52 T_address, T_event, T_place, T_source_citation, T_text,
53 T_note_sub, T_multimedia_link, T_lds_event, T_user_ref_number,
54 T_change_date, T_personal_name, T_family_link, T_pedigree,
55 T_association, T_source_event, T_source_description
58 /* Assumptions for context:
59 - In case of error, NULL is passed as context
60 - If not NULL, the ctxt_ptr of the context is not NULL also
61 - UNEXPECTED_CONTEXT is not treated as an error, but as a warning
64 struct Gom_ctxt_struct {
70 typedef struct Gom_ctxt_struct *Gom_ctxt;
72 Gom_ctxt make_gom_ctxt(int ctxt_type, OBJ_TYPE obj_type, void *ctxt_ptr);
73 void destroy_gom_ctxt(Gom_ctxt ctxt);
74 void gom_cast_error(const char* file, int line,
75 OBJ_TYPE expected, OBJ_TYPE found);
76 void gom_no_context(const char* file, int line);
77 void gom_unexpected_context(const char* file, int line, OBJ_TYPE found);
79 int gom_write_xref_list(Gedcom_write_hndl hndl,
80 Gedcom_elt elt, int tag, int parent_rec_or_elt,
81 struct xref_list* val);
83 #define MAKE_GOM_CTXT(CTXT_TYPE, STRUCTTYPE, CTXT_PTR) \
84 make_gom_ctxt(CTXT_TYPE, T_ ## STRUCTTYPE, CTXT_PTR)
86 #define SAFE_CTXT_CAST(STRUCTTYPE, VAL) \
87 (((VAL)->obj_type == T_ ## STRUCTTYPE) ? \
89 (gom_cast_error(__FILE__, __LINE__, T_ ## STRUCTTYPE, (VAL)->obj_type), \
92 #define SAFE_FREE(PTR) \
98 #define UNEXPECTED_CONTEXT(CTXT_TYPE) \
99 gom_unexpected_context(__FILE__, __LINE__, CTXT_TYPE)
102 gom_no_context(__FILE__, __LINE__)
104 void gom_mem_error(const char *filename, int line);
106 #define MEMORY_ERROR gom_mem_error(__FILE__, __LINE__)
108 void def_rec_end(Gedcom_rec rec, Gedcom_ctxt self, Gedcom_val parsed_value);
109 void def_elt_end(Gedcom_elt elt, Gedcom_ctxt parent,
110 Gedcom_ctxt self, Gedcom_val parsed_value);
111 void set_xref_type(struct xref_value *xr, const char* str);
113 int update_date(struct date_value** dv, struct tm* tm_ptr);
114 int update_time(char** tv, struct tm* tm_ptr);
116 /* Doubly-linked list, but last rec->next is NULL (doesn't go to first rec) */
117 #define LINK_CHAIN_ELT(STRUCTTYPE, FIRSTVAL, VAL) \
119 struct STRUCTTYPE *_local_obj = VAL; \
122 VAL->previous = _local_obj; \
127 FIRSTVAL->previous->next = VAL; \
128 VAL->previous = FIRSTVAL->previous; \
129 FIRSTVAL->previous = VAL; \
133 #define MAKE_CHAIN_ELT(STRUCTTYPE, FIRSTVAL, VAL) \
135 VAL = (struct STRUCTTYPE*) malloc(sizeof(struct STRUCTTYPE)); \
139 memset (VAL, 0, sizeof(struct STRUCTTYPE)); \
140 LINK_CHAIN_ELT(STRUCTTYPE, FIRSTVAL, VAL) \
144 void NULL_DESTROY(void* anything);
146 #define DESTROY_CHAIN_ELTS(STRUCTTYPE, FIRSTVAL, DESTROYFUNC) \
149 struct STRUCTTYPE *runner, *next; \
152 next = runner->next; \
153 DESTROYFUNC(runner); \
160 #define _REC_PARAMS_ Gedcom_rec rec UNUSED, int level UNUSED, \
161 Gedcom_val xref UNUSED, char *tag UNUSED, \
162 char *raw_value UNUSED, int parsed_tag UNUSED, \
163 Gedcom_val parsed_value UNUSED
165 #define _REC_END_PARAMS_ Gedcom_rec rec UNUSED, Gedcom_ctxt self UNUSED, \
166 Gedcom_val parsed_value UNUSED
168 #define _ELT_PARAMS_ Gedcom_elt elt UNUSED, Gedcom_ctxt parent UNUSED, \
169 int level UNUSED, char *tag UNUSED, \
170 char *raw_value UNUSED, int parsed_tag UNUSED, \
171 Gedcom_val parsed_value UNUSED
173 #define _ELT_END_PARAMS_ Gedcom_elt elt UNUSED, Gedcom_ctxt parent UNUSED, \
174 Gedcom_ctxt self UNUSED, \
175 Gedcom_val parsed_value UNUSED
177 #define REC_CB(STRUCTTYPE,CB_NAME,FUNC) \
178 Gedcom_ctxt CB_NAME(_REC_PARAMS_) \
180 struct xref_value* xr = GEDCOM_XREF_PTR(xref); \
182 xr->object = (Gedcom_ctxt) FUNC(xr->string); \
184 return (Gedcom_ctxt) MAKE_GOM_CTXT(rec, STRUCTTYPE, xr->object); \
189 #define GET_REC_BY_XREF(STRUCTTYPE,XREF_TYPE,FUNC_NAME) \
190 struct STRUCTTYPE *FUNC_NAME(const char *xrefstr) \
192 struct xref_value* xr = gedcom_get_by_xref(xrefstr); \
193 if (xr && (xr->type == XREF_TYPE) && xr->object) \
194 return (struct STRUCTTYPE*)(xr->object); \
199 #define STRING_CB(STRUCTTYPE,CB_NAME,FIELD) \
200 Gedcom_ctxt CB_NAME(_ELT_PARAMS_) \
202 Gom_ctxt result = NULL; \
206 struct STRUCTTYPE *obj \
207 = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \
209 char *str = GEDCOM_STRING(parsed_value); \
210 obj->FIELD = strdup(str); \
214 result = MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \
217 return (Gedcom_ctxt)result; \
220 #define STRING_END_CB(STRUCTTYPE,CB_NAME,FIELD) \
221 void CB_NAME(_ELT_END_PARAMS_) \
223 Gom_ctxt ctxt = (Gom_ctxt)self; \
227 struct STRUCTTYPE *obj = SAFE_CTXT_CAST(STRUCTTYPE, ctxt); \
229 char *str = GEDCOM_STRING(parsed_value); \
230 char *newvalue = strdup(str); \
234 obj->FIELD = newvalue; \
236 destroy_gom_ctxt(ctxt); \
240 #define STRING_END_REC_CB(STRUCTTYPE,CB_NAME,FIELD) \
241 void CB_NAME(_REC_END_PARAMS_) \
243 Gom_ctxt ctxt = (Gom_ctxt)self; \
247 struct STRUCTTYPE *obj = SAFE_CTXT_CAST(STRUCTTYPE, ctxt); \
249 char *str = GEDCOM_STRING(parsed_value); \
250 char *newvalue = strdup(str); \
254 obj->FIELD = newvalue; \
256 destroy_gom_ctxt(ctxt); \
260 #define DATE_CB(STRUCTTYPE,CB_NAME,FIELD) \
261 Gedcom_ctxt CB_NAME(_ELT_PARAMS_) \
263 Gom_ctxt result = NULL; \
267 struct STRUCTTYPE *obj \
268 = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \
270 struct date_value dv = GEDCOM_DATE(parsed_value); \
271 obj->FIELD = gedcom_new_date_value(&dv); \
275 result = MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \
278 return (Gedcom_ctxt)result; \
281 #define AGE_CB(STRUCTTYPE,CB_NAME,FIELD) \
282 Gedcom_ctxt CB_NAME(_ELT_PARAMS_) \
284 Gom_ctxt result = NULL; \
288 struct STRUCTTYPE *obj \
289 = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \
291 struct age_value age = GEDCOM_AGE(parsed_value); \
292 obj->FIELD = gedcom_new_age_value(&age); \
296 result = MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \
299 return (Gedcom_ctxt)result; \
302 #define XREF_CB(STRUCTTYPE,CB_NAME,FIELD,FUNC) \
303 Gedcom_ctxt CB_NAME(_ELT_PARAMS_) \
305 Gom_ctxt result = NULL; \
309 struct STRUCTTYPE *obj \
310 = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \
311 struct xref_value *xr = GEDCOM_XREF_PTR(parsed_value); \
313 xr->object = (Gedcom_ctxt) FUNC(xr->string); \
316 result = MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \
319 return (Gedcom_ctxt)result; \
322 #define XREF_LIST_CB(STRUCTTYPE,CB_NAME,FIELD,FUNC) \
323 Gedcom_ctxt CB_NAME(_ELT_PARAMS_) \
325 Gom_ctxt result = NULL; \
329 struct STRUCTTYPE *obj \
330 = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \
331 struct xref_value *xr = GEDCOM_XREF_PTR(parsed_value); \
332 struct xref_list *xrl; \
334 xr->object = (Gedcom_ctxt) FUNC(xr->string); \
336 MAKE_CHAIN_ELT(xref_list, obj->FIELD, xrl); \
339 result = MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \
343 return (Gedcom_ctxt)result; \
346 #define NULL_CB(STRUCTTYPE,CB_NAME) \
347 Gedcom_ctxt CB_NAME(_ELT_PARAMS_) \
349 Gom_ctxt result = NULL; \
353 struct STRUCTTYPE *obj \
354 = SAFE_CTXT_CAST(STRUCTTYPE, (Gom_ctxt)parent); \
356 result = MAKE_GOM_CTXT(elt, STRUCTTYPE, obj); \
358 return (Gedcom_ctxt)result; \
361 #endif /* __GOM_INTERNAL_H */