Functions for moving an xref in a list.
[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 UNREFALLFUNC(text)(struct text* obj)
170 {
171   if (obj) {
172     struct text* runner;
173     for (runner = obj; runner; runner = runner->next)
174       UNREFALLFUNC(user_data)(runner->extra);
175   }
176 }
177
178 void CLEANFUNC(text)(struct text* t)
179 {
180   if (t) {
181     SAFE_FREE(t->text);
182   }
183 }
184
185 void UNREFALLFUNC(source_citation)(struct source_citation* obj)
186 {
187   if (obj) {
188     struct source_citation* runner;
189     for (runner = obj; runner; runner = runner->next) {
190       unref_xref_value(runner->reference);
191       UNREFALLFUNC(text)(runner->text);
192       UNREFALLFUNC(multimedia_link)(runner->mm_link);
193       UNREFALLFUNC(note_sub)(runner->note);
194       UNREFALLFUNC(user_data)(runner->extra);
195     }
196   }
197 }
198
199 void CLEANFUNC(source_citation)(struct source_citation* cit)
200 {
201   if (cit) {
202     SAFE_FREE(cit->description);
203     SAFE_FREE(cit->page);
204     SAFE_FREE(cit->event);
205     SAFE_FREE(cit->role);
206     SAFE_FREE(cit->date);
207     DESTROY_CHAIN_ELTS(text, cit->text);
208     SAFE_FREE(cit->quality);
209     DESTROY_CHAIN_ELTS(multimedia_link, cit->mm_link);
210     DESTROY_CHAIN_ELTS(note_sub, cit->note);
211     DESTROY_CHAIN_ELTS(user_data, cit->extra);
212   }
213 }
214
215 int write_texts(Gedcom_write_hndl hndl, int parent, struct text* t)
216 {
217   int result = 0;
218   struct text* obj;
219   
220   if (!t) return 1;
221
222   for (obj = t; obj; obj = obj->next) {
223     result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_TEXT, 0, parent,
224                                        obj->text);
225     if (obj->extra)
226       result |= write_user_data(hndl, obj->extra);    
227   }
228   
229   return result;
230 }
231
232 int write_citations(Gedcom_write_hndl hndl, int parent,
233                     struct source_citation* cit)
234 {
235   int result = 0;
236   struct source_citation* obj;
237   
238   if (!cit) return 1;
239
240   for (obj = cit; obj; obj = obj->next) {
241     if (obj->reference) {
242       result |= gedcom_write_element_xref(hndl, ELT_SUB_SOUR, 0, parent,
243                                           obj->reference);
244       if (obj->page)
245         result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_PAGE, 0,
246                                            ELT_SUB_SOUR, obj->page);
247       if (obj->event)
248         result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_EVEN, 0,
249                                            ELT_SUB_SOUR, obj->event);
250       if (obj->role)
251         result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_EVEN_ROLE, 0,
252                                            ELT_SUB_SOUR_EVEN, obj->role);
253       if (obj->date || obj->text)
254         result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_DATA, 0,
255                                            ELT_SUB_SOUR, NULL);
256       if (obj->date)
257         result |= gedcom_write_element_date(hndl, ELT_SUB_SOUR_DATA_DATE, 0,
258                                             ELT_SUB_SOUR_DATA, obj->date);
259       if (obj->text)
260         result |= write_texts(hndl, ELT_SUB_SOUR_DATA, obj->text);
261       if (obj->quality)
262         result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR_QUAY, 0,
263                                            ELT_SUB_SOUR, obj->quality);
264       if (obj->mm_link)
265         result |= write_multimedia_links(hndl, ELT_SUB_SOUR, obj->mm_link);
266     }
267     else {
268       result |= gedcom_write_element_str(hndl, ELT_SUB_SOUR, 0, parent,
269                                          obj->description);
270       if (obj->text)
271         result |= write_texts(hndl, ELT_SUB_SOUR, obj->text);
272     }
273     if (obj->note)
274       result |= write_note_subs(hndl, ELT_SUB_SOUR, obj->note);
275     if (obj->extra)
276       result |= write_user_data(hndl, obj->extra);    
277   }
278   
279   return result;
280 }