Use complete concatenated text instead of concatenating the texts itself.
[gedcom-parse.git] / gom / source.c
1 /* Source object 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.h"
27 #include "source_event.h"
28 #include "note_sub.h"
29 #include "source_description.h"
30 #include "repository.h"
31 #include "multimedia_link.h"
32 #include "user_ref.h"
33 #include "change_date.h"
34 #include "user_rec.h"
35 #include "gom.h"
36 #include "gedcom.h"
37 #include "gom_internal.h"
38
39 struct source* gom_first_source = NULL;
40
41 REC_CB(source, sour_start, make_source_record)
42 GET_REC_BY_XREF(source, XREF_SOUR, gom_get_source_by_xref)
43 NULL_CB(source, sour_data_start)
44 STRING_CB(source, sour_data_agnc_start, data.agency)
45 NULL_CB(source, sour_auth_start)  /* value set by end callback */
46 NULL_CB(source, sour_titl_start)  /* value set by end callback */
47 STRING_CB(source, sour_abbr_start, abbreviation)
48 NULL_CB(source, sour_publ_start)  /* value set by end callback */
49 NULL_CB(source, sour_text_start)  /* value set by end callback */
50 XREF_CB(source, sour_repo_start, repository.link, make_repository_record)
51
52 void sour_auth_end(_ELT_END_PARAMS_)
53 {
54   Gom_ctxt ctxt = (Gom_ctxt)self;
55
56   if (! ctxt)
57     NO_CONTEXT;
58   else {
59     struct source *sour = SAFE_CTXT_CAST(source, ctxt);
60     if (sour) {
61       char *str = GEDCOM_STRING(parsed_value);
62       char *newvalue = strdup(str);
63       if (! newvalue)
64         MEMORY_ERROR;
65       else
66         sour->author = newvalue;
67     }
68   }
69 }
70
71 void sour_titl_end(_ELT_END_PARAMS_)
72 {
73   Gom_ctxt ctxt = (Gom_ctxt)self;
74
75   if (! ctxt)
76     NO_CONTEXT;
77   else {
78     struct source *sour = SAFE_CTXT_CAST(source, ctxt);
79     if (sour) {
80       char *str = GEDCOM_STRING(parsed_value);
81       char *newvalue = strdup(str);
82       if (! newvalue)
83         MEMORY_ERROR;
84       else
85         sour->title = newvalue;
86     }
87   }
88 }
89
90 void sour_publ_end(_ELT_END_PARAMS_)
91 {
92   Gom_ctxt ctxt = (Gom_ctxt)self;
93
94   if (! ctxt)
95     NO_CONTEXT;
96   else {
97     struct source *sour = SAFE_CTXT_CAST(source, ctxt);
98     if (sour) {
99       char *str = GEDCOM_STRING(parsed_value);
100       char *newvalue = strdup(str);
101       if (! newvalue)
102         MEMORY_ERROR;
103       else
104         sour->publication = newvalue;
105     }
106   }
107 }
108
109 void sour_text_end(_ELT_END_PARAMS_)
110 {
111   Gom_ctxt ctxt = (Gom_ctxt)self;
112
113   if (! ctxt)
114     NO_CONTEXT;
115   else {
116     struct source *sour = SAFE_CTXT_CAST(source, ctxt);
117     if (sour) {
118       char *str = GEDCOM_STRING(parsed_value);
119       char *newvalue = strdup(str);
120       if (! newvalue)
121         MEMORY_ERROR;
122       else
123         sour->text = newvalue;
124     }
125   }
126 }
127
128 void source_subscribe()
129 {
130   gedcom_subscribe_to_record(REC_SOUR, sour_start, def_rec_end);
131   gedcom_subscribe_to_element(ELT_SOUR_DATA, sour_data_start, def_elt_end);
132   gedcom_subscribe_to_element(ELT_SOUR_DATA_AGNC, sour_data_agnc_start,
133                               def_elt_end);
134   gedcom_subscribe_to_element(ELT_SOUR_AUTH, sour_auth_start, sour_auth_end);
135   gedcom_subscribe_to_element(ELT_SOUR_TITL, sour_titl_start, sour_titl_end);
136   gedcom_subscribe_to_element(ELT_SOUR_ABBR, sour_abbr_start, def_elt_end);
137   gedcom_subscribe_to_element(ELT_SOUR_PUBL, sour_publ_start, sour_publ_end);
138   gedcom_subscribe_to_element(ELT_SOUR_TEXT, sour_text_start, sour_text_end);
139   gedcom_subscribe_to_element(ELT_SUB_REPO, sour_repo_start, def_elt_end);
140 }
141
142 void source_add_event(Gom_ctxt ctxt, struct source_event* evt)
143 {
144   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
145   if (sour)
146     LINK_CHAIN_ELT(source_event, sour->data.event, evt);  
147 }
148
149 void source_add_note_to_data(Gom_ctxt ctxt, struct note_sub* note)
150 {
151   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
152   if (sour)
153     LINK_CHAIN_ELT(note_sub, sour->data.note, note);  
154 }
155
156 void source_add_note_to_repo(Gom_ctxt ctxt, struct note_sub* note)
157 {
158   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
159   if (sour)
160     LINK_CHAIN_ELT(note_sub, sour->repository.note, note);  
161 }
162
163 void source_add_description(Gom_ctxt ctxt, struct source_description* desc)
164 {
165   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
166   if (sour)
167     LINK_CHAIN_ELT(source_description, sour->repository.description, desc);  
168 }
169
170 void source_add_mm_link(Gom_ctxt ctxt, struct multimedia_link* link)
171 {
172   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
173   if (sour)
174     LINK_CHAIN_ELT(multimedia_link, sour->mm_link, link);
175 }
176
177 void source_add_note(Gom_ctxt ctxt, struct note_sub* note)
178 {
179   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
180   if (sour)
181     LINK_CHAIN_ELT(note_sub, sour->note, note);
182 }
183
184 void source_add_user_ref(Gom_ctxt ctxt, struct user_ref_number* ref)
185 {
186   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
187   if (sour)
188     LINK_CHAIN_ELT(user_ref_number, sour->ref, ref);
189 }
190
191 void source_set_record_id(Gom_ctxt ctxt, const char *rin)
192 {
193   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
194   if (sour) {
195     sour->record_id = strdup(rin);
196     if (! sour->record_id) MEMORY_ERROR;
197   }
198 }
199
200 void source_set_change_date(Gom_ctxt ctxt, struct change_date* chan)
201 {
202   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
203   if (sour)
204     sour->change_date = chan;
205 }
206
207 void source_add_user_data(Gom_ctxt ctxt, struct user_data* data)
208 {
209   struct source *obj = SAFE_CTXT_CAST(source, ctxt);
210   if (obj)
211     LINK_CHAIN_ELT(user_data, obj->extra, data);
212 }
213
214 void source_cleanup(struct source* sour)
215 {
216   if (sour) {
217     SAFE_FREE(sour->xrefstr);
218     DESTROY_CHAIN_ELTS(source_event, sour->data.event, source_event_cleanup);
219     SAFE_FREE(sour->data.agency)
220     DESTROY_CHAIN_ELTS(note_sub, sour->data.note, note_sub_cleanup);
221     SAFE_FREE(sour->author);
222     SAFE_FREE(sour->title);
223     SAFE_FREE(sour->abbreviation);
224     SAFE_FREE(sour->publication);
225     SAFE_FREE(sour->text);
226     DESTROY_CHAIN_ELTS(note_sub, sour->repository.note, note_sub_cleanup);
227     DESTROY_CHAIN_ELTS(source_description, sour->repository.description,
228                        source_description_cleanup);
229     DESTROY_CHAIN_ELTS(multimedia_link, sour->mm_link,multimedia_link_cleanup);
230     DESTROY_CHAIN_ELTS(note_sub, sour->note, note_sub_cleanup);
231     DESTROY_CHAIN_ELTS(user_ref_number, sour->ref, user_ref_cleanup);
232     SAFE_FREE(sour->record_id);
233     change_date_cleanup(sour->change_date);
234     DESTROY_CHAIN_ELTS(user_data, sour->extra, user_data_cleanup);
235   }
236 }
237
238 void sources_cleanup()
239 {
240   DESTROY_CHAIN_ELTS(source, gom_first_source, source_cleanup);
241 }
242
243 struct source* gom_get_first_source()
244 {
245   return gom_first_source;
246 }
247
248 struct source* make_source_record(const char* xrefstr)
249 {
250   struct source* src = NULL;
251   MAKE_CHAIN_ELT(source, gom_first_source, src);
252   if (src) {
253     src->xrefstr = strdup(xrefstr);
254     if (! src->xrefstr) MEMORY_ERROR;
255   }
256   return src;
257 }