renamed the package to libgedcom-dev
[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       int type = ctxt_type(ctxt);
53       if (GEDCOM_IS_XREF_PTR(parsed_value))
54         cit->reference = GEDCOM_XREF_PTR(parsed_value);
55
56       switch (type) {
57         case ELT_SUB_PLAC:
58           ADDFUNC2(place,source_citation)(ctxt, cit); break;
59         case ELT_SUB_FAM_EVT:
60         case ELT_SUB_FAM_EVT_EVEN:
61         case ELT_SUB_INDIV_ATTR:
62         case ELT_SUB_INDIV_RESI:
63         case ELT_SUB_INDIV_BIRT:
64         case ELT_SUB_INDIV_GEN:
65         case ELT_SUB_INDIV_ADOP:
66         case ELT_SUB_INDIV_EVEN:
67           ADDFUNC2(event,source_citation)(ctxt, cit); break;
68         case ELT_SUB_NOTE:
69           ADDFUNC2(note_sub,source_citation)(ctxt, cit); break;
70         case ELT_SUB_LSS_SLGS:
71         case ELT_SUB_LIO_BAPL:
72         case ELT_SUB_LIO_SLGC:
73           ADDFUNC2(lds_event,source_citation)(ctxt, cit); break;
74         case REC_FAM:
75           ADDFUNC2(family,source_citation)(ctxt, cit); break;
76         case ELT_SUB_PERS_NAME:
77           ADDFUNC2(personal_name,source_citation)(ctxt, cit); break;
78         case REC_INDI:
79           ADDFUNC2(individual,source_citation)(ctxt, cit); break;
80         case ELT_SUB_ASSO:
81           ADDFUNC2(association,source_citation)(ctxt, cit); break;
82         case REC_NOTE:
83           ADDFUNC2(note,source_citation)(ctxt, cit); break;
84         default:
85           UNEXPECTED_CONTEXT(type);
86       }
87       result = MAKE_GOM_CTXT(elt, source_citation, cit);
88     }
89   }
90
91   return (Gedcom_ctxt)result;
92 }
93
94 void sub_citation_end(_ELT_END_PARAMS_)
95 {
96   Gom_ctxt ctxt = (Gom_ctxt)self;
97
98   if (! ctxt)
99     NO_CONTEXT;
100   else {
101     if (GEDCOM_IS_STRING(parsed_value)) {
102       struct source_citation *cit = SAFE_CTXT_CAST(source_citation, ctxt);
103       if (cit) {
104         char *str = GEDCOM_STRING(parsed_value);
105         char *newvalue = strdup(str);
106         if (! newvalue)
107           MEMORY_ERROR;
108         else
109           cit->description = newvalue;
110       }
111     }
112     def_elt_end(elt, parent, self, parsed_value);
113   }
114 }
115
116 Gedcom_ctxt sub_cit_text_start(_ELT_PARAMS_)
117 {
118   Gom_ctxt ctxt = (Gom_ctxt)parent;
119   Gom_ctxt result = NULL;
120
121   if (! ctxt)
122     NO_CONTEXT;
123   else {
124     struct source_citation *cit = SAFE_CTXT_CAST(source_citation, ctxt);
125     if (cit) {
126       struct text *t = NULL;
127       MAKE_CHAIN_ELT(text, cit->text, t);
128       if (t)
129         result = MAKE_GOM_CTXT(elt, text, t);
130     }
131   }
132   
133   return (Gedcom_ctxt)result;
134 }
135
136 DEFINE_SUB_MAKEFUNC(source_citation)
137 DEFINE_SUB_ADDFUNC(source_citation)
138 DEFINE_SUB_FINDFUNC(source_citation)
139 DEFINE_SUB_REMOVEFUNC(source_citation)
140 DEFINE_SUB_MOVEFUNC(source_citation)
141      
142 DEFINE_STRING_CB(source_citation, sub_cit_page_start, page)
143 DEFINE_STRING_CB(source_citation, sub_cit_even_start, event)
144 DEFINE_STRING_CB(source_citation, sub_cit_even_role_start, role)
145 DEFINE_NULL_CB(source_citation, sub_cit_data_start)
146 DEFINE_DATE_CB(source_citation, sub_cit_data_date_start, date)
147 DEFINE_STRING_CB(source_citation, sub_cit_quay_start, quality)
148 DEFINE_STRING_END_CB(text, sub_cit_text_end, text)
149
150 DEFINE_ADDFUNC2(source_citation, note_sub, note)
151 DEFINE_ADDFUNC2(source_citation, multimedia_link, mm_link)
152 DEFINE_ADDFUNC2(source_citation, user_data, extra)
153      
154 void citation_subscribe()
155 {
156   gedcom_subscribe_to_element(ELT_SUB_SOUR, sub_citation_start,
157                               sub_citation_end);
158   gedcom_subscribe_to_element(ELT_SUB_SOUR_PAGE, sub_cit_page_start,
159                               def_elt_end);
160   gedcom_subscribe_to_element(ELT_SUB_SOUR_EVEN, sub_cit_even_start,
161                               def_elt_end);
162   gedcom_subscribe_to_element(ELT_SUB_SOUR_EVEN_ROLE, sub_cit_even_role_start,
163                               def_elt_end);
164   gedcom_subscribe_to_element(ELT_SUB_SOUR_DATA, sub_cit_data_start,
165                               def_elt_end);
166   gedcom_subscribe_to_element(ELT_SUB_SOUR_DATA_DATE, sub_cit_data_date_start,
167                               def_elt_end);
168   gedcom_subscribe_to_element(ELT_SUB_SOUR_TEXT, sub_cit_text_start,
169                               sub_cit_text_end);
170   gedcom_subscribe_to_element(ELT_SUB_SOUR_QUAY, sub_cit_quay_start,
171                               def_elt_end);
172 }
173
174 void UNREFALLFUNC(text)(struct text* obj)
175 {
176   if (obj) {
177     struct text* runner;
178     for (runner = obj; runner; runner = runner->next)
179       UNREFALLFUNC(user_data)(runner->extra);
180   }
181 }
182
183 void CLEANFUNC(text)(struct text* t)
184 {
185   if (t) {
186     SAFE_FREE(t->text);
187   }
188 }
189
190 DEFINE_SUB_MAKEFUNC(text)
191 DEFINE_SUB_ADDFUNC(text)
192 DEFINE_SUB_FINDFUNC(text)
193 DEFINE_SUB_REMOVEFUNC(text)
194 DEFINE_SUB_MOVEFUNC(text)
195      
196 void UNREFALLFUNC(source_citation)(struct source_citation* obj)
197 {
198   if (obj) {
199     struct source_citation* runner;
200     for (runner = obj; runner; runner = runner->next) {
201       unref_xref_value(runner->reference);
202       UNREFALLFUNC(text)(runner->text);
203       UNREFALLFUNC(multimedia_link)(runner->mm_link);
204       UNREFALLFUNC(note_sub)(runner->note);
205       UNREFALLFUNC(user_data)(runner->extra);
206     }
207   }
208 }
209
210 void CLEANFUNC(source_citation)(struct source_citation* cit)
211 {
212   if (cit) {
213     SAFE_FREE(cit->description);
214     SAFE_FREE(cit->page);
215     SAFE_FREE(cit->event);
216     SAFE_FREE(cit->role);
217     SAFE_FREE(cit->date);
218     DESTROY_CHAIN_ELTS(text, cit->text);
219     SAFE_FREE(cit->quality);
220     DESTROY_CHAIN_ELTS(multimedia_link, cit->mm_link);
221     DESTROY_CHAIN_ELTS(note_sub, cit->note);
222     DESTROY_CHAIN_ELTS(user_data, cit->extra);
223   }
224 }
225
226 int write_texts(Gedcom_write_hndl hndl, int parent, struct text* t)
227 {
228   int result = 0;
229   struct text* obj;
230   
231   if (!t) return 1;
232
233   for (obj = t; obj; obj = obj->next) {
234     result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_TEXT, 0, parent,
235                                        obj->text);
236     if (obj->extra)
237       result |= write_user_data(hndl, obj->extra);    
238   }
239   
240   return result;
241 }
242
243 int write_citations(Gedcom_write_hndl hndl, int parent,
244                     struct source_citation* cit)
245 {
246   int result = 0;
247   struct source_citation* obj;
248   
249   if (!cit) return 1;
250
251   for (obj = cit; obj; obj = obj->next) {
252     if (obj->reference) {
253       result |= gedcom_write_element_xref(hndl, ELT_SUB_SOUR, 0, parent,
254                                           obj->reference);
255       if (obj->page)
256         result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_PAGE, 0,
257                                            ELT_SUB_SOUR, obj->page);
258       if (obj->event)
259         result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_EVEN, 0,
260                                            ELT_SUB_SOUR, obj->event);
261       if (obj->role)
262         result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_EVEN_ROLE, 0,
263                                            ELT_SUB_SOUR_EVEN, obj->role);
264       if (obj->date || obj->text)
265         result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_DATA, 0,
266                                            ELT_SUB_SOUR, NULL);
267       if (obj->date)
268         result |= gedcom_write_element_date(hndl, ELT_SUB_SOUR_DATA_DATE, 0,
269                                             ELT_SUB_SOUR_DATA, obj->date);
270       if (obj->text)
271         result |= write_texts(hndl, ELT_SUB_SOUR_DATA, obj->text);
272       if (obj->quality)
273         result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_QUAY, 0,
274                                            ELT_SUB_SOUR, obj->quality);
275       if (obj->mm_link)
276         result |= write_multimedia_links(hndl, ELT_SUB_SOUR, obj->mm_link);
277     }
278     else {
279       result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR, 0, parent,
280                                          obj->description);
281       if (obj->text)
282         result |= write_texts(hndl, ELT_SUB_SOUR, obj->text);
283     }
284     if (obj->note)
285       result |= write_note_subs(hndl, ELT_SUB_SOUR, obj->note);
286     if (obj->extra)
287       result |= write_user_data(hndl, obj->extra);    
288   }
289   
290   return result;
291 }