Beginnings of write support.
[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       int err = 0;
57       memset (cit, 0, sizeof(struct source_citation));
58       if (GEDCOM_IS_STRING(parsed_value)) {
59         cit->description = strdup(GEDCOM_STRING(parsed_value));
60         if (! cit->description) {
61           MEMORY_ERROR;
62           free(cit);
63           err = 1;
64         }
65       }
66       else if (GEDCOM_IS_XREF_PTR(parsed_value))
67         cit->reference = GEDCOM_XREF_PTR(parsed_value);
68
69       if (! err) {
70         switch (ctxt->ctxt_type) {
71           case ELT_SUB_PLAC:
72             place_add_citation(ctxt, cit); break;
73           case ELT_SUB_FAM_EVT:
74           case ELT_SUB_FAM_EVT_EVEN:
75           case ELT_SUB_INDIV_ATTR:
76           case ELT_SUB_INDIV_RESI:
77           case ELT_SUB_INDIV_BIRT:
78           case ELT_SUB_INDIV_GEN:
79           case ELT_SUB_INDIV_ADOP:
80           case ELT_SUB_INDIV_EVEN:
81             event_add_citation(ctxt, cit); break;
82           case ELT_SUB_NOTE:
83             note_sub_add_citation(ctxt, cit); break;
84           case ELT_SUB_LSS_SLGS:
85           case ELT_SUB_LIO_BAPL:
86           case ELT_SUB_LIO_SLGC:
87             lds_event_add_citation(ctxt, cit); break;
88           case REC_FAM:
89             family_add_citation(ctxt, cit); break;
90           case ELT_SUB_PERS_NAME:
91             name_add_citation(ctxt, cit); break;
92           case REC_INDI:
93             individual_add_citation(ctxt, cit); break;
94           case ELT_SUB_ASSO:
95             association_add_citation(ctxt, cit); break;
96           case REC_NOTE:
97             note_add_citation(ctxt, cit); break;
98           default:
99             UNEXPECTED_CONTEXT(ctxt->ctxt_type);
100         }
101         result = MAKE_GOM_CTXT(elt, source_citation, cit);
102       }
103     }
104   }
105
106   return (Gedcom_ctxt)result;
107 }
108
109 Gedcom_ctxt sub_cit_text_start(_ELT_PARAMS_)
110 {
111   Gom_ctxt ctxt = (Gom_ctxt)parent;
112   Gom_ctxt result = NULL;
113
114   if (! ctxt)
115     NO_CONTEXT;
116   else {
117     struct source_citation *cit = SAFE_CTXT_CAST(source_citation, ctxt);
118     if (cit) {
119       struct text *t = NULL;
120       MAKE_CHAIN_ELT(text, cit->text, t);
121       if (t) {
122         t->text = strdup(GEDCOM_STRING(parsed_value));
123         if (! t->text) {
124           MEMORY_ERROR;
125           free(t);
126         }
127         else
128           result = MAKE_GOM_CTXT(elt, text, t);
129       }
130     }
131   }
132   
133   return (Gedcom_ctxt)result;
134 }
135
136 STRING_CB(source_citation, sub_cit_page_start, page)
137 STRING_CB(source_citation, sub_cit_even_start, event)
138 STRING_CB(source_citation, sub_cit_even_role_start, role)
139 NULL_CB(source_citation, sub_cit_data_start)
140 DATE_CB(source_citation, sub_cit_data_date_start, date)
141 STRING_CB(source_citation, sub_cit_quay_start, quality)
142      
143 void citation_subscribe()
144 {
145   gedcom_subscribe_to_element(ELT_SUB_SOUR, sub_citation_start, def_elt_end);
146   gedcom_subscribe_to_element(ELT_SUB_SOUR_PAGE, sub_cit_page_start,
147                               def_elt_end);
148   gedcom_subscribe_to_element(ELT_SUB_SOUR_EVEN, sub_cit_even_start,
149                               def_elt_end);
150   gedcom_subscribe_to_element(ELT_SUB_SOUR_EVEN_ROLE, sub_cit_even_role_start,
151                               def_elt_end);
152   gedcom_subscribe_to_element(ELT_SUB_SOUR_DATA, sub_cit_data_start,
153                               def_elt_end);
154   gedcom_subscribe_to_element(ELT_SUB_SOUR_DATA_DATE, sub_cit_data_date_start,
155                               def_elt_end);
156   gedcom_subscribe_to_element(ELT_SUB_SOUR_TEXT, sub_cit_text_start,
157                               def_elt_end);
158   gedcom_subscribe_to_element(ELT_SUB_SOUR_QUAY, sub_cit_quay_start,
159                               def_elt_end);
160 }
161
162 void citation_add_note(Gom_ctxt ctxt, struct note_sub* note)
163 {
164   struct source_citation *cit = SAFE_CTXT_CAST(source_citation, ctxt);
165   if (cit)
166     LINK_CHAIN_ELT(note_sub, cit->note, note);    
167 }
168
169 void citation_add_mm_link(Gom_ctxt ctxt, struct multimedia_link* mm)
170 {
171   struct source_citation *cit = SAFE_CTXT_CAST(source_citation, ctxt);
172   if (cit)
173     LINK_CHAIN_ELT(multimedia_link, cit->mm_link, mm);    
174 }
175
176 void citation_add_to_desc(NL_TYPE type, Gom_ctxt ctxt, const char* str)
177 {
178   struct source_citation *cit = SAFE_CTXT_CAST(source_citation, ctxt);
179   if (cit) {
180     char *newvalue = concat_strings (type, cit->description, str);
181     if (newvalue)
182       cit->description = newvalue;
183     else
184       MEMORY_ERROR;
185   }
186 }
187
188 void citation_add_to_text(NL_TYPE type, Gom_ctxt ctxt, const char* str)
189 {
190   struct text *t = SAFE_CTXT_CAST(text, ctxt);
191   if (t) {
192     char *newvalue = concat_strings (type, t->text, str);
193     if (newvalue)
194       t->text = newvalue;
195     else
196       MEMORY_ERROR;
197   }
198 }
199
200 void citation_add_user_data(Gom_ctxt ctxt, struct user_data* data)
201 {
202   struct source_citation *obj = SAFE_CTXT_CAST(source_citation, ctxt);
203   if (obj)
204     LINK_CHAIN_ELT(user_data, obj->extra, data);
205 }
206
207 void text_cleanup(struct text* t)
208 {
209   if (t) {
210     SAFE_FREE(t->text);
211   }
212 }
213
214 void citation_cleanup(struct source_citation* cit)
215 {
216   if (cit) {
217     SAFE_FREE(cit->description);
218     SAFE_FREE(cit->page);
219     SAFE_FREE(cit->event);
220     SAFE_FREE(cit->role);
221     SAFE_FREE(cit->date);
222     DESTROY_CHAIN_ELTS(text, cit->text, text_cleanup);
223     SAFE_FREE(cit->quality);
224     DESTROY_CHAIN_ELTS(multimedia_link, cit->mm_link, multimedia_link_cleanup);
225     DESTROY_CHAIN_ELTS(note_sub, cit->note, note_sub_cleanup);
226     DESTROY_CHAIN_ELTS(user_data, cit->extra, user_data_cleanup);
227   }
228 }