2f353973d18fae5b840862ac9fca801f8cff23a0
[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 STRING_END_CB(source, sour_auth_end, author)
47 NULL_CB(source, sour_titl_start)  /* value set by end callback */
48 STRING_END_CB(source, sour_titl_end, title)
49 STRING_CB(source, sour_abbr_start, abbreviation)
50 NULL_CB(source, sour_publ_start)  /* value set by end callback */
51 STRING_END_CB(source, sour_publ_end, publication)
52 NULL_CB(source, sour_text_start)  /* value set by end callback */
53 STRING_END_CB(source, sour_text_end, text)
54 XREF_CB(source, sour_repo_start, repository.link, make_repository_record)
55
56 void source_subscribe()
57 {
58   gedcom_subscribe_to_record(REC_SOUR, sour_start, def_rec_end);
59   gedcom_subscribe_to_element(ELT_SOUR_DATA, sour_data_start, def_elt_end);
60   gedcom_subscribe_to_element(ELT_SOUR_DATA_AGNC, sour_data_agnc_start,
61                               def_elt_end);
62   gedcom_subscribe_to_element(ELT_SOUR_AUTH, sour_auth_start, sour_auth_end);
63   gedcom_subscribe_to_element(ELT_SOUR_TITL, sour_titl_start, sour_titl_end);
64   gedcom_subscribe_to_element(ELT_SOUR_ABBR, sour_abbr_start, def_elt_end);
65   gedcom_subscribe_to_element(ELT_SOUR_PUBL, sour_publ_start, sour_publ_end);
66   gedcom_subscribe_to_element(ELT_SOUR_TEXT, sour_text_start, sour_text_end);
67   gedcom_subscribe_to_element(ELT_SUB_REPO, sour_repo_start, def_elt_end);
68 }
69
70 void source_add_event(Gom_ctxt ctxt, struct source_event* evt)
71 {
72   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
73   if (sour)
74     LINK_CHAIN_ELT(source_event, sour->data.event, evt);  
75 }
76
77 void source_add_note_to_data(Gom_ctxt ctxt, struct note_sub* note)
78 {
79   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
80   if (sour)
81     LINK_CHAIN_ELT(note_sub, sour->data.note, note);  
82 }
83
84 void source_add_note_to_repo(Gom_ctxt ctxt, struct note_sub* note)
85 {
86   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
87   if (sour)
88     LINK_CHAIN_ELT(note_sub, sour->repository.note, note);  
89 }
90
91 void source_add_description(Gom_ctxt ctxt, struct source_description* desc)
92 {
93   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
94   if (sour)
95     LINK_CHAIN_ELT(source_description, sour->repository.description, desc);  
96 }
97
98 void source_add_mm_link(Gom_ctxt ctxt, struct multimedia_link* link)
99 {
100   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
101   if (sour)
102     LINK_CHAIN_ELT(multimedia_link, sour->mm_link, link);
103 }
104
105 void source_add_note(Gom_ctxt ctxt, struct note_sub* note)
106 {
107   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
108   if (sour)
109     LINK_CHAIN_ELT(note_sub, sour->note, note);
110 }
111
112 void source_add_user_ref(Gom_ctxt ctxt, struct user_ref_number* ref)
113 {
114   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
115   if (sour)
116     LINK_CHAIN_ELT(user_ref_number, sour->ref, ref);
117 }
118
119 void source_set_record_id(Gom_ctxt ctxt, const char *rin)
120 {
121   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
122   if (sour) {
123     sour->record_id = strdup(rin);
124     if (! sour->record_id) MEMORY_ERROR;
125   }
126 }
127
128 void source_set_change_date(Gom_ctxt ctxt, struct change_date* chan)
129 {
130   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
131   if (sour)
132     sour->change_date = chan;
133 }
134
135 void source_add_user_data(Gom_ctxt ctxt, struct user_data* data)
136 {
137   struct source *obj = SAFE_CTXT_CAST(source, ctxt);
138   if (obj)
139     LINK_CHAIN_ELT(user_data, obj->extra, data);
140 }
141
142 void source_cleanup(struct source* sour)
143 {
144   if (sour) {
145     SAFE_FREE(sour->xrefstr);
146     DESTROY_CHAIN_ELTS(source_event, sour->data.event, source_event_cleanup);
147     SAFE_FREE(sour->data.agency)
148     DESTROY_CHAIN_ELTS(note_sub, sour->data.note, note_sub_cleanup);
149     SAFE_FREE(sour->author);
150     SAFE_FREE(sour->title);
151     SAFE_FREE(sour->abbreviation);
152     SAFE_FREE(sour->publication);
153     SAFE_FREE(sour->text);
154     DESTROY_CHAIN_ELTS(note_sub, sour->repository.note, note_sub_cleanup);
155     DESTROY_CHAIN_ELTS(source_description, sour->repository.description,
156                        source_description_cleanup);
157     DESTROY_CHAIN_ELTS(multimedia_link, sour->mm_link,multimedia_link_cleanup);
158     DESTROY_CHAIN_ELTS(note_sub, sour->note, note_sub_cleanup);
159     DESTROY_CHAIN_ELTS(user_ref_number, sour->ref, user_ref_cleanup);
160     SAFE_FREE(sour->record_id);
161     change_date_cleanup(sour->change_date);
162     DESTROY_CHAIN_ELTS(user_data, sour->extra, user_data_cleanup);
163   }
164 }
165
166 void sources_cleanup()
167 {
168   DESTROY_CHAIN_ELTS(source, gom_first_source, source_cleanup);
169 }
170
171 struct source* gom_get_first_source()
172 {
173   return gom_first_source;
174 }
175
176 struct source* make_source_record(const char* xrefstr)
177 {
178   struct source* src = NULL;
179   MAKE_CHAIN_ELT(source, gom_first_source, src);
180   if (src) {
181     src->xrefstr = strdup(xrefstr);
182     if (! src->xrefstr) MEMORY_ERROR;
183   }
184   return src;
185 }
186
187 int write_sources(Gedcom_write_hndl hndl)
188 {
189   int result = 0;
190   struct source* obj;
191
192   for (obj = gom_first_source; obj; obj = obj->next) {
193     result |= gedcom_write_record_str(hndl, REC_SOUR, 0,
194                                       obj->xrefstr, NULL);
195     if (obj->data.event || obj->data.agency || obj->data.note)
196       result |= gedcom_write_element_str(hndl, ELT_SOUR_DATA, 0,
197                                          REC_SOUR, NULL);
198     if (obj->data.event)
199       result |= write_source_events(hndl, ELT_SOUR_DATA, obj->data.event);
200     if (obj->data.agency)
201       result |= gedcom_write_element_str(hndl, ELT_SOUR_DATA_AGNC, 0,
202                                          ELT_SOUR_DATA, obj->data.agency);
203     if (obj->data.note)
204       result |= write_note_subs(hndl, ELT_SOUR_DATA, obj->data.note);
205     if (obj->author)
206       result |= gedcom_write_element_str(hndl, ELT_SOUR_AUTH, 0,
207                                          REC_SOUR, obj->author);
208     if (obj->title)
209       result |= gedcom_write_element_str(hndl, ELT_SOUR_TITL, 0,
210                                          REC_SOUR, obj->title);
211     if (obj->abbreviation)
212       result |= gedcom_write_element_str(hndl, ELT_SOUR_ABBR, 0,
213                                          REC_SOUR, obj->abbreviation);
214     if (obj->publication)
215       result |= gedcom_write_element_str(hndl, ELT_SOUR_PUBL, 0,
216                                          REC_SOUR, obj->publication);
217     if (obj->text)
218       result |= gedcom_write_element_str(hndl, ELT_SOUR_TEXT, 0,
219                                          REC_SOUR, obj->text);
220     if (obj->repository.link || obj->repository.note
221         || obj->repository.description) {
222       result |= gedcom_write_element_xref(hndl, ELT_SUB_REPO, 0,
223                                           REC_SOUR, obj->repository.link);
224     }
225     if (obj->repository.note)
226       result |= write_note_subs(hndl, ELT_SUB_REPO, obj->repository.note);
227     if (obj->repository.description)
228       result |= write_source_descriptions(hndl, ELT_SUB_REPO,
229                                           obj->repository.description);
230     if (obj->mm_link)
231       result |= write_multimedia_links(hndl, REC_SOUR, obj->mm_link);
232     if (obj->note)
233       result |= write_note_subs(hndl, REC_SOUR, obj->note);
234     if (obj->ref)
235       result |= write_user_refs(hndl, REC_SOUR, obj->ref);
236     if (obj->record_id)
237       result |= gedcom_write_element_str(hndl, ELT_SUB_IDENT_RIN, 0,
238                                          REC_SOUR, obj->record_id);
239     if (obj->change_date)
240       result |= write_change_date(hndl, REC_SOUR, obj->change_date);
241     if (obj->extra)
242       result |= write_user_data(hndl, obj->extra);
243   }
244   
245   return result;
246 }
247