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