Reworked the xref functions.
[gedcom-parse.git] / gom / source_citation.c
1 /* Source citation sub-structure in 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.
5
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.
10
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.
15
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
19    02111-1307 USA.  */
20
21 /* $Id$ */
22 /* $Name$ */
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include "source_citation.h"
27 #include "place.h"
28 #include "event.h"
29 #include "note_sub.h"
30 #include "multimedia_link.h"
31 #include "lds_event.h"
32 #include "family.h"
33 #include "personal_name.h"
34 #include "individual.h"
35 #include "association.h"
36 #include "note.h"
37 #include "user_rec.h"
38 #include "gom.h"
39 #include "gedcom.h"
40 #include "gom_internal.h"
41
42 Gedcom_ctxt sub_citation_start(_ELT_PARAMS_)
43 {
44   Gom_ctxt ctxt = (Gom_ctxt)parent;
45   Gom_ctxt result = NULL;
46
47   if (! ctxt)
48     NO_CONTEXT;
49   else {
50     struct source_citation *cit = SUB_MAKEFUNC(source_citation)();
51     if (cit) {
52       if (GEDCOM_IS_XREF_PTR(parsed_value))
53         cit->reference = GEDCOM_XREF_PTR(parsed_value);
54
55       switch (ctxt->ctxt_type) {
56         case ELT_SUB_PLAC:
57           ADDFUNC2(place,source_citation)(ctxt, cit); break;
58         case ELT_SUB_FAM_EVT:
59         case ELT_SUB_FAM_EVT_EVEN:
60         case ELT_SUB_INDIV_ATTR:
61         case ELT_SUB_INDIV_RESI:
62         case ELT_SUB_INDIV_BIRT:
63         case ELT_SUB_INDIV_GEN:
64         case ELT_SUB_INDIV_ADOP:
65         case ELT_SUB_INDIV_EVEN:
66           ADDFUNC2(event,source_citation)(ctxt, cit); break;
67         case ELT_SUB_NOTE:
68           ADDFUNC2(note_sub,source_citation)(ctxt, cit); break;
69         case ELT_SUB_LSS_SLGS:
70         case ELT_SUB_LIO_BAPL:
71         case ELT_SUB_LIO_SLGC:
72           ADDFUNC2(lds_event,source_citation)(ctxt, cit); break;
73         case REC_FAM:
74           ADDFUNC2(family,source_citation)(ctxt, cit); break;
75         case ELT_SUB_PERS_NAME:
76           ADDFUNC2(personal_name,source_citation)(ctxt, cit); break;
77         case REC_INDI:
78           ADDFUNC2(individual,source_citation)(ctxt, cit); break;
79         case ELT_SUB_ASSO:
80           ADDFUNC2(association,source_citation)(ctxt, cit); break;
81         case REC_NOTE:
82           ADDFUNC2(note,source_citation)(ctxt, cit); break;
83         default:
84           UNEXPECTED_CONTEXT(ctxt->ctxt_type);
85       }
86       result = MAKE_GOM_CTXT(elt, source_citation, cit);
87     }
88   }
89
90   return (Gedcom_ctxt)result;
91 }
92
93 void sub_citation_end(_ELT_END_PARAMS_)
94 {
95   Gom_ctxt ctxt = (Gom_ctxt)self;
96
97   if (! ctxt)
98     NO_CONTEXT;
99   else {
100     if (GEDCOM_IS_STRING(parsed_value)) {
101       struct source_citation *cit = SAFE_CTXT_CAST(source_citation, ctxt);
102       if (cit) {
103         char *str = GEDCOM_STRING(parsed_value);
104         char *newvalue = strdup(str);
105         if (! newvalue)
106           MEMORY_ERROR;
107         else
108           cit->description = newvalue;
109       }
110     }
111     destroy_gom_ctxt(ctxt);
112   }
113 }
114
115 Gedcom_ctxt sub_cit_text_start(_ELT_PARAMS_)
116 {
117   Gom_ctxt ctxt = (Gom_ctxt)parent;
118   Gom_ctxt result = NULL;
119
120   if (! ctxt)
121     NO_CONTEXT;
122   else {
123     struct source_citation *cit = SAFE_CTXT_CAST(source_citation, ctxt);
124     if (cit) {
125       struct text *t = NULL;
126       MAKE_CHAIN_ELT(text, cit->text, t);
127       if (t)
128         result = MAKE_GOM_CTXT(elt, text, t);
129     }
130   }
131   
132   return (Gedcom_ctxt)result;
133 }
134
135 DEFINE_SUB_MAKEFUNC(source_citation)
136      
137 DEFINE_STRING_CB(source_citation, sub_cit_page_start, page)
138 DEFINE_STRING_CB(source_citation, sub_cit_even_start, event)
139 DEFINE_STRING_CB(source_citation, sub_cit_even_role_start, role)
140 DEFINE_NULL_CB(source_citation, sub_cit_data_start)
141 DEFINE_DATE_CB(source_citation, sub_cit_data_date_start, date)
142 DEFINE_STRING_CB(source_citation, sub_cit_quay_start, quality)
143 DEFINE_STRING_END_CB(text, sub_cit_text_end, text)
144
145 DEFINE_ADDFUNC2(source_citation, note_sub, note)
146 DEFINE_ADDFUNC2(source_citation, multimedia_link, mm_link)
147 DEFINE_ADDFUNC2(source_citation, user_data, extra)
148      
149 void citation_subscribe()
150 {
151   gedcom_subscribe_to_element(ELT_SUB_SOUR, sub_citation_start,
152                               sub_citation_end);
153   gedcom_subscribe_to_element(ELT_SUB_SOUR_PAGE, sub_cit_page_start,
154                               def_elt_end);
155   gedcom_subscribe_to_element(ELT_SUB_SOUR_EVEN, sub_cit_even_start,
156                               def_elt_end);
157   gedcom_subscribe_to_element(ELT_SUB_SOUR_EVEN_ROLE, sub_cit_even_role_start,
158                               def_elt_end);
159   gedcom_subscribe_to_element(ELT_SUB_SOUR_DATA, sub_cit_data_start,
160                               def_elt_end);
161   gedcom_subscribe_to_element(ELT_SUB_SOUR_DATA_DATE, sub_cit_data_date_start,
162                               def_elt_end);
163   gedcom_subscribe_to_element(ELT_SUB_SOUR_TEXT, sub_cit_text_start,
164                               sub_cit_text_end);
165   gedcom_subscribe_to_element(ELT_SUB_SOUR_QUAY, sub_cit_quay_start,
166                               def_elt_end);
167 }
168
169 void CLEANFUNC(text)(struct text* t)
170 {
171   if (t) {
172     SAFE_FREE(t->text);
173   }
174 }
175
176 void CLEANFUNC(source_citation)(struct source_citation* cit)
177 {
178   if (cit) {
179     SAFE_FREE(cit->description);
180     SAFE_FREE(cit->page);
181     SAFE_FREE(cit->event);
182     SAFE_FREE(cit->role);
183     SAFE_FREE(cit->date);
184     DESTROY_CHAIN_ELTS(text, cit->text);
185     SAFE_FREE(cit->quality);
186     DESTROY_CHAIN_ELTS(multimedia_link, cit->mm_link);
187     DESTROY_CHAIN_ELTS(note_sub, cit->note);
188     DESTROY_CHAIN_ELTS(user_data, cit->extra);
189   }
190 }
191
192 int write_texts(Gedcom_write_hndl hndl, int parent, struct text* t)
193 {
194   int result = 0;
195   struct text* obj;
196   
197   if (!t) return 1;
198
199   for (obj = t; obj; obj = obj->next) {
200     result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_TEXT, 0, parent,
201                                        obj->text);
202     if (obj->extra)
203       result |= write_user_data(hndl, obj->extra);    
204   }
205   
206   return result;
207 }
208
209 int write_citations(Gedcom_write_hndl hndl, int parent,
210                     struct source_citation* cit)
211 {
212   int result = 0;
213   struct source_citation* obj;
214   
215   if (!cit) return 1;
216
217   for (obj = cit; obj; obj = obj->next) {
218     if (obj->reference) {
219       result |= gedcom_write_element_xref(hndl, ELT_SUB_SOUR, 0, parent,
220                                           obj->reference);
221       if (obj->page)
222         result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_PAGE, 0,
223                                            ELT_SUB_SOUR, obj->page);
224       if (obj->event)
225         result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_EVEN, 0,
226                                            ELT_SUB_SOUR, obj->event);
227       if (obj->role)
228         result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_EVEN_ROLE, 0,
229                                            ELT_SUB_SOUR_EVEN, obj->role);
230       if (obj->date || obj->text)
231         result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_DATA, 0,
232                                            ELT_SUB_SOUR, NULL);
233       if (obj->date)
234         result |= gedcom_write_element_date(hndl, ELT_SUB_SOUR_DATA_DATE, 0,
235                                             ELT_SUB_SOUR_DATA, obj->date);
236       if (obj->text)
237         result |= write_texts(hndl, ELT_SUB_SOUR_DATA, obj->text);
238       if (obj->quality)
239         result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_QUAY, 0,
240                                            ELT_SUB_SOUR, obj->quality);
241       if (obj->mm_link)
242         result |= write_multimedia_links(hndl, ELT_SUB_SOUR, obj->mm_link);
243     }
244     else {
245       result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR, 0, parent,
246                                          obj->description);
247       if (obj->text)
248         result |= write_texts(hndl, ELT_SUB_SOUR, obj->text);
249     }
250     if (obj->note)
251       result |= write_note_subs(hndl, ELT_SUB_SOUR, obj->note);
252     if (obj->extra)
253       result |= write_user_data(hndl, obj->extra);    
254   }
255   
256   return result;
257 }