Allow elements out of context in GOM.
[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 DEFINE_MAKEFUNC(source, gom_first_source)
42 DEFINE_DESTROYFUNC(source, gom_first_source)
43 DEFINE_ADDFUNC(source, XREF_SOUR)
44 DEFINE_DELETEFUNC(source)
45 DEFINE_GETXREFFUNC(source, XREF_SOUR)
46      
47 DEFINE_REC_CB(source, sour_start)
48 DEFINE_NULL_CB(source, sour_data_start)
49 DEFINE_STRING_CB(source, sour_data_agnc_start, data.agency)
50 DEFINE_NULL_CB(source, sour_auth_start)  /* value set by end callback */
51 DEFINE_STRING_END_CB(source, sour_auth_end, author)
52 DEFINE_NULL_CB(source, sour_titl_start)  /* value set by end callback */
53 DEFINE_STRING_END_CB(source, sour_titl_end, title)
54 DEFINE_STRING_CB(source, sour_abbr_start, abbreviation)
55 DEFINE_NULL_CB(source, sour_publ_start)  /* value set by end callback */
56 DEFINE_STRING_END_CB(source, sour_publ_end, publication)
57 DEFINE_NULL_CB(source, sour_text_start)  /* value set by end callback */
58 DEFINE_STRING_END_CB(source, sour_text_end, text)
59 DEFINE_XREF_CB(source, sour_repo_start, repository.link, repository)
60
61 DEFINE_ADDFUNC2(source, source_event, data.event)
62 DEFINE_ADDFUNC2(source, source_description, repository.description)
63 DEFINE_ADDFUNC2(source, multimedia_link, mm_link)
64 DEFINE_ADDFUNC2(source, note_sub, note)
65 DEFINE_ADDFUNC2(source, user_ref_number, ref)
66 DEFINE_ADDFUNC2(source, user_data, extra)
67 DEFINE_ADDFUNC2_NOLIST(source, change_date, change_date)
68 DEFINE_ADDFUNC2_STR(source, record_id)
69
70 void source_subscribe()
71 {
72   gedcom_subscribe_to_record(REC_SOUR, sour_start, def_rec_end);
73   gedcom_subscribe_to_element(ELT_SOUR_DATA, sour_data_start, def_elt_end);
74   gedcom_subscribe_to_element(ELT_SOUR_DATA_AGNC, sour_data_agnc_start,
75                               def_elt_end);
76   gedcom_subscribe_to_element(ELT_SOUR_AUTH, sour_auth_start, sour_auth_end);
77   gedcom_subscribe_to_element(ELT_SOUR_TITL, sour_titl_start, sour_titl_end);
78   gedcom_subscribe_to_element(ELT_SOUR_ABBR, sour_abbr_start, def_elt_end);
79   gedcom_subscribe_to_element(ELT_SOUR_PUBL, sour_publ_start, sour_publ_end);
80   gedcom_subscribe_to_element(ELT_SOUR_TEXT, sour_text_start, sour_text_end);
81   gedcom_subscribe_to_element(ELT_SUB_REPO, sour_repo_start, def_elt_end);
82 }
83
84 void source_add_note_to_data(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->data.note, note);  
89 }
90
91 void source_add_note_to_repo(Gom_ctxt ctxt, struct note_sub* note)
92 {
93   struct source *sour = SAFE_CTXT_CAST(source, ctxt);
94   if (sour)
95     LINK_CHAIN_ELT(note_sub, sour->repository.note, note);  
96 }
97
98 void UNREFALLFUNC(source)(struct source *obj)
99 {
100   if (obj) {
101     UNREFALLFUNC(source_event)(obj->data.event);
102     UNREFALLFUNC(note_sub)(obj->data.note);
103     unref_xref_value(obj->repository.link);
104     UNREFALLFUNC(note_sub)(obj->repository.note);
105     UNREFALLFUNC(source_description)(obj->repository.description);
106     UNREFALLFUNC(multimedia_link)(obj->mm_link);
107     UNREFALLFUNC(note_sub)(obj->note);
108     UNREFALLFUNC(user_ref_number)(obj->ref);
109     UNREFALLFUNC(change_date)(obj->change_date);
110     UNREFALLFUNC(user_data)(obj->extra);
111   }
112 }
113
114 void CLEANFUNC(source)(struct source* sour)
115 {
116   if (sour) {
117     SAFE_FREE(sour->xrefstr);
118     DESTROY_CHAIN_ELTS(source_event, sour->data.event);
119     SAFE_FREE(sour->data.agency)
120     DESTROY_CHAIN_ELTS(note_sub, sour->data.note);
121     SAFE_FREE(sour->author);
122     SAFE_FREE(sour->title);
123     SAFE_FREE(sour->abbreviation);
124     SAFE_FREE(sour->publication);
125     SAFE_FREE(sour->text);
126     DESTROY_CHAIN_ELTS(note_sub, sour->repository.note);
127     DESTROY_CHAIN_ELTS(source_description, sour->repository.description);
128     DESTROY_CHAIN_ELTS(multimedia_link, sour->mm_link);
129     DESTROY_CHAIN_ELTS(note_sub, sour->note);
130     DESTROY_CHAIN_ELTS(user_ref_number, sour->ref);
131     SAFE_FREE(sour->record_id);
132     CLEANFUNC(change_date)(sour->change_date);
133     DESTROY_CHAIN_ELTS(user_data, sour->extra);
134   }
135 }
136
137 void sources_cleanup()
138 {
139   DESTROY_CHAIN_ELTS(source, gom_first_source);
140 }
141
142 struct source* gom_get_first_source()
143 {
144   return gom_first_source;
145 }
146
147 int write_sources(Gedcom_write_hndl hndl)
148 {
149   int result = 0;
150   struct source* obj;
151
152   for (obj = gom_first_source; obj; obj = obj->next) {
153     result |= gedcom_write_record_str(hndl, REC_SOUR, obj->xrefstr, NULL);
154     if (obj->data.event || obj->data.agency || obj->data.note)
155       result |= gedcom_write_element_str(hndl, ELT_SOUR_DATA, 0,
156                                          REC_SOUR, NULL);
157     if (obj->data.event)
158       result |= write_source_events(hndl, ELT_SOUR_DATA, obj->data.event);
159     if (obj->data.agency)
160       result |= gedcom_write_element_str(hndl, ELT_SOUR_DATA_AGNC, 0,
161                                          ELT_SOUR_DATA, obj->data.agency);
162     if (obj->data.note)
163       result |= write_note_subs(hndl, ELT_SOUR_DATA, obj->data.note);
164     if (obj->author)
165       result |= gedcom_write_element_str(hndl, ELT_SOUR_AUTH, 0,
166                                          REC_SOUR, obj->author);
167     if (obj->title)
168       result |= gedcom_write_element_str(hndl, ELT_SOUR_TITL, 0,
169                                          REC_SOUR, obj->title);
170     if (obj->abbreviation)
171       result |= gedcom_write_element_str(hndl, ELT_SOUR_ABBR, 0,
172                                          REC_SOUR, obj->abbreviation);
173     if (obj->publication)
174       result |= gedcom_write_element_str(hndl, ELT_SOUR_PUBL, 0,
175                                          REC_SOUR, obj->publication);
176     if (obj->text)
177       result |= gedcom_write_element_str(hndl, ELT_SOUR_TEXT, 0,
178                                          REC_SOUR, obj->text);
179     if (obj->repository.link || obj->repository.note
180         || obj->repository.description) {
181       result |= gedcom_write_element_xref(hndl, ELT_SUB_REPO, 0,
182                                           REC_SOUR, obj->repository.link);
183     }
184     if (obj->repository.note)
185       result |= write_note_subs(hndl, ELT_SUB_REPO, obj->repository.note);
186     if (obj->repository.description)
187       result |= write_source_descriptions(hndl, ELT_SUB_REPO,
188                                           obj->repository.description);
189     if (obj->mm_link)
190       result |= write_multimedia_links(hndl, REC_SOUR, obj->mm_link);
191     if (obj->note)
192       result |= write_note_subs(hndl, REC_SOUR, obj->note);
193     if (obj->ref)
194       result |= write_user_refs(hndl, REC_SOUR, obj->ref);
195     if (obj->record_id)
196       result |= gedcom_write_element_str(hndl, ELT_SUB_IDENT_RIN, 0,
197                                          REC_SOUR, obj->record_id);
198     if (obj->change_date)
199       result |= write_change_date(hndl, REC_SOUR, obj->change_date);
200     if (obj->extra)
201       result |= write_user_data(hndl, obj->extra);
202   }
203   
204   return result;
205 }
206