Use complete concatenated text instead of concatenating the texts itself.
[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           place_add_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           event_add_citation(ctxt, cit); break;
72         case ELT_SUB_NOTE:
73           note_sub_add_citation(ctxt, cit); break;
74         case ELT_SUB_LSS_SLGS:
75         case ELT_SUB_LIO_BAPL:
76         case ELT_SUB_LIO_SLGC:
77           lds_event_add_citation(ctxt, cit); break;
78         case REC_FAM:
79           family_add_citation(ctxt, cit); break;
80         case ELT_SUB_PERS_NAME:
81           name_add_citation(ctxt, cit); break;
82         case REC_INDI:
83           individual_add_citation(ctxt, cit); break;
84         case ELT_SUB_ASSO:
85           association_add_citation(ctxt, cit); break;
86         case REC_NOTE:
87           note_add_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   }
117 }
118
119 Gedcom_ctxt sub_cit_text_start(_ELT_PARAMS_)
120 {
121   Gom_ctxt ctxt = (Gom_ctxt)parent;
122   Gom_ctxt result = NULL;
123
124   if (! ctxt)
125     NO_CONTEXT;
126   else {
127     struct source_citation *cit = SAFE_CTXT_CAST(source_citation, ctxt);
128     if (cit) {
129       struct text *t = NULL;
130       MAKE_CHAIN_ELT(text, cit->text, t);
131       if (t)
132         result = MAKE_GOM_CTXT(elt, text, t);
133     }
134   }
135   
136   return (Gedcom_ctxt)result;
137 }
138
139 void sub_cit_text_end(_ELT_END_PARAMS_)
140 {
141   Gom_ctxt ctxt = (Gom_ctxt)self;
142
143   if (! ctxt)
144     NO_CONTEXT;
145   else {
146     if (GEDCOM_IS_STRING(parsed_value)) {
147       struct text *t = SAFE_CTXT_CAST(text, ctxt);
148       if (t) {
149         char *str = GEDCOM_STRING(parsed_value);
150         char *newvalue = strdup(str);
151         if (! newvalue)
152           MEMORY_ERROR;
153         else
154           t->text = newvalue;
155       }
156     }
157   }
158 }
159
160 STRING_CB(source_citation, sub_cit_page_start, page)
161 STRING_CB(source_citation, sub_cit_even_start, event)
162 STRING_CB(source_citation, sub_cit_even_role_start, role)
163 NULL_CB(source_citation, sub_cit_data_start)
164 DATE_CB(source_citation, sub_cit_data_date_start, date)
165 STRING_CB(source_citation, sub_cit_quay_start, quality)
166      
167 void citation_subscribe()
168 {
169   gedcom_subscribe_to_element(ELT_SUB_SOUR, sub_citation_start,
170                               sub_citation_end);
171   gedcom_subscribe_to_element(ELT_SUB_SOUR_PAGE, sub_cit_page_start,
172                               def_elt_end);
173   gedcom_subscribe_to_element(ELT_SUB_SOUR_EVEN, sub_cit_even_start,
174                               def_elt_end);
175   gedcom_subscribe_to_element(ELT_SUB_SOUR_EVEN_ROLE, sub_cit_even_role_start,
176                               def_elt_end);
177   gedcom_subscribe_to_element(ELT_SUB_SOUR_DATA, sub_cit_data_start,
178                               def_elt_end);
179   gedcom_subscribe_to_element(ELT_SUB_SOUR_DATA_DATE, sub_cit_data_date_start,
180                               def_elt_end);
181   gedcom_subscribe_to_element(ELT_SUB_SOUR_TEXT, sub_cit_text_start,
182                               sub_cit_text_end);
183   gedcom_subscribe_to_element(ELT_SUB_SOUR_QUAY, sub_cit_quay_start,
184                               def_elt_end);
185 }
186
187 void citation_add_note(Gom_ctxt ctxt, struct note_sub* note)
188 {
189   struct source_citation *cit = SAFE_CTXT_CAST(source_citation, ctxt);
190   if (cit)
191     LINK_CHAIN_ELT(note_sub, cit->note, note);    
192 }
193
194 void citation_add_mm_link(Gom_ctxt ctxt, struct multimedia_link* mm)
195 {
196   struct source_citation *cit = SAFE_CTXT_CAST(source_citation, ctxt);
197   if (cit)
198     LINK_CHAIN_ELT(multimedia_link, cit->mm_link, mm);    
199 }
200
201 void citation_add_user_data(Gom_ctxt ctxt, struct user_data* data)
202 {
203   struct source_citation *obj = SAFE_CTXT_CAST(source_citation, ctxt);
204   if (obj)
205     LINK_CHAIN_ELT(user_data, obj->extra, data);
206 }
207
208 void text_cleanup(struct text* t)
209 {
210   if (t) {
211     SAFE_FREE(t->text);
212   }
213 }
214
215 void citation_cleanup(struct source_citation* cit)
216 {
217   if (cit) {
218     SAFE_FREE(cit->description);
219     SAFE_FREE(cit->page);
220     SAFE_FREE(cit->event);
221     SAFE_FREE(cit->role);
222     SAFE_FREE(cit->date);
223     DESTROY_CHAIN_ELTS(text, cit->text, text_cleanup);
224     SAFE_FREE(cit->quality);
225     DESTROY_CHAIN_ELTS(multimedia_link, cit->mm_link, multimedia_link_cleanup);
226     DESTROY_CHAIN_ELTS(note_sub, cit->note, note_sub_cleanup);
227     DESTROY_CHAIN_ELTS(user_data, cit->extra, user_data_cleanup);
228   }
229 }