Use of libutf8
[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 STRING_CB(source, sour_auth_start, author)
46 STRING_CB(source, sour_titl_start, title)
47 STRING_CB(source, sour_abbr_start, abbreviation)
48 STRING_CB(source, sour_publ_start, publication)
49 STRING_CB(source, sour_text_start, text)
50 XREF_CB(source, sour_repo_start, repository.link, make_repository_record)
51
52 void source_subscribe()
53 {
54   gedcom_subscribe_to_record(REC_SOUR, sour_start, def_rec_end);
55   gedcom_subscribe_to_element(ELT_SOUR_DATA, sour_data_start, def_elt_end);
56   gedcom_subscribe_to_element(ELT_SOUR_DATA_AGNC, sour_data_agnc_start,
57                               def_elt_end);
58   gedcom_subscribe_to_element(ELT_SOUR_AUTH, sour_auth_start, def_elt_end);
59   gedcom_subscribe_to_element(ELT_SOUR_TITL, sour_titl_start, def_elt_end);
60   gedcom_subscribe_to_element(ELT_SOUR_ABBR, sour_abbr_start, def_elt_end);
61   gedcom_subscribe_to_element(ELT_SOUR_PUBL, sour_publ_start, def_elt_end);
62   gedcom_subscribe_to_element(ELT_SOUR_TEXT, sour_text_start, def_elt_end);
63   gedcom_subscribe_to_element(ELT_SUB_REPO, sour_repo_start, def_elt_end);
64 }
65
66 void source_add_event(Gom_ctxt ctxt, struct source_event* evt)
67 {
68   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
69   if (sour)
70     LINK_CHAIN_ELT(source_event, sour->data.event, evt);  
71 }
72
73 void source_add_note_to_data(Gom_ctxt ctxt, struct note_sub* note)
74 {
75   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
76   if (sour)
77     LINK_CHAIN_ELT(note_sub, sour->data.note, note);  
78 }
79
80 void source_add_note_to_repo(Gom_ctxt ctxt, struct note_sub* note)
81 {
82   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
83   if (sour)
84     LINK_CHAIN_ELT(note_sub, sour->repository.note, note);  
85 }
86
87 void source_add_description(Gom_ctxt ctxt, struct source_description* desc)
88 {
89   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
90   if (sour)
91     LINK_CHAIN_ELT(source_description, sour->repository.description, desc);  
92 }
93
94 void source_add_to_value(NL_TYPE type, Gom_ctxt ctxt, const char* str)
95 {
96   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
97   if (sour) {
98     switch (ctxt->ctxt_type) {
99       char *newvalue;
100       case ELT_SOUR_AUTH:
101         newvalue = concat_strings (type, sour->author, str);
102         if (newvalue)
103           sour->author = newvalue;
104         else
105           MEMORY_ERROR;
106         break;
107       case ELT_SOUR_TITL:
108         newvalue = concat_strings (type, sour->title, str);
109         if (newvalue)
110           sour->title = newvalue;
111         else
112           MEMORY_ERROR;
113         break;
114       case ELT_SOUR_PUBL:
115         newvalue = concat_strings (type, sour->publication, str);
116         if (newvalue)
117           sour->publication = newvalue;
118         else
119           MEMORY_ERROR;
120         break;
121       case ELT_SOUR_TEXT:
122         newvalue = concat_strings (type, sour->text, str);
123         if (newvalue)
124           sour->text = newvalue;
125         else
126           MEMORY_ERROR;
127         break;
128       default:
129         UNEXPECTED_CONTEXT(ctxt->ctxt_type);
130     }
131   }
132 }
133
134 void source_add_mm_link(Gom_ctxt ctxt, struct multimedia_link* link)
135 {
136   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
137   if (sour)
138     LINK_CHAIN_ELT(multimedia_link, sour->mm_link, link);
139 }
140
141 void source_add_note(Gom_ctxt ctxt, struct note_sub* note)
142 {
143   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
144   if (sour)
145     LINK_CHAIN_ELT(note_sub, sour->note, note);
146 }
147
148 void source_add_user_ref(Gom_ctxt ctxt, struct user_ref_number* ref)
149 {
150   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
151   if (sour)
152     LINK_CHAIN_ELT(user_ref_number, sour->ref, ref);
153 }
154
155 void source_set_record_id(Gom_ctxt ctxt, const char *rin)
156 {
157   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
158   if (sour) {
159     sour->record_id = strdup(rin);
160     if (! sour->record_id) MEMORY_ERROR;
161   }
162 }
163
164 void source_set_change_date(Gom_ctxt ctxt, struct change_date* chan)
165 {
166   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
167   if (sour)
168     sour->change_date = chan;
169 }
170
171 void source_add_user_data(Gom_ctxt ctxt, struct user_data* data)
172 {
173   struct source *obj = SAFE_CTXT_CAST(source, ctxt);
174   if (obj)
175     LINK_CHAIN_ELT(user_data, obj->extra, data);
176 }
177
178 void source_cleanup(struct source* sour)
179 {
180   if (sour) {
181     SAFE_FREE(sour->xrefstr);
182     DESTROY_CHAIN_ELTS(source_event, sour->data.event, source_event_cleanup);
183     SAFE_FREE(sour->data.agency)
184     DESTROY_CHAIN_ELTS(note_sub, sour->data.note, note_sub_cleanup);
185     SAFE_FREE(sour->author);
186     SAFE_FREE(sour->title);
187     SAFE_FREE(sour->abbreviation);
188     SAFE_FREE(sour->publication);
189     SAFE_FREE(sour->text);
190     DESTROY_CHAIN_ELTS(note_sub, sour->repository.note, note_sub_cleanup);
191     DESTROY_CHAIN_ELTS(source_description, sour->repository.description,
192                        source_description_cleanup);
193     DESTROY_CHAIN_ELTS(multimedia_link, sour->mm_link,multimedia_link_cleanup);
194     DESTROY_CHAIN_ELTS(note_sub, sour->note, note_sub_cleanup);
195     DESTROY_CHAIN_ELTS(user_ref_number, sour->ref, user_ref_cleanup);
196     SAFE_FREE(sour->record_id);
197     change_date_cleanup(sour->change_date);
198     DESTROY_CHAIN_ELTS(user_data, sour->extra, user_data_cleanup);
199   }
200 }
201
202 void sources_cleanup()
203 {
204   DESTROY_CHAIN_ELTS(source, gom_first_source, source_cleanup);
205 }
206
207 struct source* gom_get_first_source()
208 {
209   return gom_first_source;
210 }
211
212 struct source* make_source_record(const char* xrefstr)
213 {
214   struct source* src = NULL;
215   MAKE_CHAIN_ELT(source, gom_first_source, src);
216   if (src) {
217     src->xrefstr = strdup(xrefstr);
218     if (! src->xrefstr) MEMORY_ERROR;
219   }
220   return src;
221 }