Added functions to add, remove and move substructs.
[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 DEFINE_SUB_ADDFUNC(source_citation)
137 DEFINE_SUB_FINDFUNC(source_citation)
138 DEFINE_SUB_REMOVEFUNC(source_citation)
139 DEFINE_SUB_MOVEFUNC(source_citation)
140      
141 DEFINE_STRING_CB(source_citation, sub_cit_page_start, page)
142 DEFINE_STRING_CB(source_citation, sub_cit_even_start, event)
143 DEFINE_STRING_CB(source_citation, sub_cit_even_role_start, role)
144 DEFINE_NULL_CB(source_citation, sub_cit_data_start)
145 DEFINE_DATE_CB(source_citation, sub_cit_data_date_start, date)
146 DEFINE_STRING_CB(source_citation, sub_cit_quay_start, quality)
147 DEFINE_STRING_END_CB(text, sub_cit_text_end, text)
148
149 DEFINE_ADDFUNC2(source_citation, note_sub, note)
150 DEFINE_ADDFUNC2(source_citation, multimedia_link, mm_link)
151 DEFINE_ADDFUNC2(source_citation, user_data, extra)
152      
153 void citation_subscribe()
154 {
155   gedcom_subscribe_to_element(ELT_SUB_SOUR, sub_citation_start,
156                               sub_citation_end);
157   gedcom_subscribe_to_element(ELT_SUB_SOUR_PAGE, sub_cit_page_start,
158                               def_elt_end);
159   gedcom_subscribe_to_element(ELT_SUB_SOUR_EVEN, sub_cit_even_start,
160                               def_elt_end);
161   gedcom_subscribe_to_element(ELT_SUB_SOUR_EVEN_ROLE, sub_cit_even_role_start,
162                               def_elt_end);
163   gedcom_subscribe_to_element(ELT_SUB_SOUR_DATA, sub_cit_data_start,
164                               def_elt_end);
165   gedcom_subscribe_to_element(ELT_SUB_SOUR_DATA_DATE, sub_cit_data_date_start,
166                               def_elt_end);
167   gedcom_subscribe_to_element(ELT_SUB_SOUR_TEXT, sub_cit_text_start,
168                               sub_cit_text_end);
169   gedcom_subscribe_to_element(ELT_SUB_SOUR_QUAY, sub_cit_quay_start,
170                               def_elt_end);
171 }
172
173 void UNREFALLFUNC(text)(struct text* obj)
174 {
175   if (obj) {
176     struct text* runner;
177     for (runner = obj; runner; runner = runner->next)
178       UNREFALLFUNC(user_data)(runner->extra);
179   }
180 }
181
182 void CLEANFUNC(text)(struct text* t)
183 {
184   if (t) {
185     SAFE_FREE(t->text);
186   }
187 }
188
189 DEFINE_SUB_MAKEFUNC(text)
190 DEFINE_SUB_ADDFUNC(text)
191 DEFINE_SUB_FINDFUNC(text)
192 DEFINE_SUB_REMOVEFUNC(text)
193 DEFINE_SUB_MOVEFUNC(text)
194      
195 void UNREFALLFUNC(source_citation)(struct source_citation* obj)
196 {
197   if (obj) {
198     struct source_citation* runner;
199     for (runner = obj; runner; runner = runner->next) {
200       unref_xref_value(runner->reference);
201       UNREFALLFUNC(text)(runner->text);
202       UNREFALLFUNC(multimedia_link)(runner->mm_link);
203       UNREFALLFUNC(note_sub)(runner->note);
204       UNREFALLFUNC(user_data)(runner->extra);
205     }
206   }
207 }
208
209 void CLEANFUNC(source_citation)(struct source_citation* cit)
210 {
211   if (cit) {
212     SAFE_FREE(cit->description);
213     SAFE_FREE(cit->page);
214     SAFE_FREE(cit->event);
215     SAFE_FREE(cit->role);
216     SAFE_FREE(cit->date);
217     DESTROY_CHAIN_ELTS(text, cit->text);
218     SAFE_FREE(cit->quality);
219     DESTROY_CHAIN_ELTS(multimedia_link, cit->mm_link);
220     DESTROY_CHAIN_ELTS(note_sub, cit->note);
221     DESTROY_CHAIN_ELTS(user_data, cit->extra);
222   }
223 }
224
225 int write_texts(Gedcom_write_hndl hndl, int parent, struct text* t)
226 {
227   int result = 0;
228   struct text* obj;
229   
230   if (!t) return 1;
231
232   for (obj = t; obj; obj = obj->next) {
233     result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_TEXT, 0, parent,
234                                        obj->text);
235     if (obj->extra)
236       result |= write_user_data(hndl, obj->extra);    
237   }
238   
239   return result;
240 }
241
242 int write_citations(Gedcom_write_hndl hndl, int parent,
243                     struct source_citation* cit)
244 {
245   int result = 0;
246   struct source_citation* obj;
247   
248   if (!cit) return 1;
249
250   for (obj = cit; obj; obj = obj->next) {
251     if (obj->reference) {
252       result |= gedcom_write_element_xref(hndl, ELT_SUB_SOUR, 0, parent,
253                                           obj->reference);
254       if (obj->page)
255         result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_PAGE, 0,
256                                            ELT_SUB_SOUR, obj->page);
257       if (obj->event)
258         result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_EVEN, 0,
259                                            ELT_SUB_SOUR, obj->event);
260       if (obj->role)
261         result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_EVEN_ROLE, 0,
262                                            ELT_SUB_SOUR_EVEN, obj->role);
263       if (obj->date || obj->text)
264         result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_DATA, 0,
265                                            ELT_SUB_SOUR, NULL);
266       if (obj->date)
267         result |= gedcom_write_element_date(hndl, ELT_SUB_SOUR_DATA_DATE, 0,
268                                             ELT_SUB_SOUR_DATA, obj->date);
269       if (obj->text)
270         result |= write_texts(hndl, ELT_SUB_SOUR_DATA, obj->text);
271       if (obj->quality)
272         result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_QUAY, 0,
273                                            ELT_SUB_SOUR, obj->quality);
274       if (obj->mm_link)
275         result |= write_multimedia_links(hndl, ELT_SUB_SOUR, obj->mm_link);
276     }
277     else {
278       result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR, 0, parent,
279                                          obj->description);
280       if (obj->text)
281         result |= write_texts(hndl, ELT_SUB_SOUR, obj->text);
282     }
283     if (obj->note)
284       result |= write_note_subs(hndl, ELT_SUB_SOUR, obj->note);
285     if (obj->extra)
286       result |= write_user_data(hndl, obj->extra);    
287   }
288   
289   return result;
290 }