04f99615032149e1bfabba6f29227d2e3ad23652
[gedcom-parse.git] / gom / user_rec.c
1 /* User record 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 "header.h"
27 #include "submission.h"
28 #include "submitter.h"
29 #include "family.h"
30 #include "individual.h"
31 #include "multimedia.h"
32 #include "note.h"
33 #include "repository.h"
34 #include "source.h"
35 #include "address.h"
36 #include "event.h"
37 #include "place.h"
38 #include "source_citation.h"
39 #include "note_sub.h"
40 #include "multimedia_link.h"
41 #include "lds_event.h"
42 #include "user_ref.h"
43 #include "change_date.h"
44 #include "personal_name.h"
45 #include "family_link.h"
46 #include "association.h"
47 #include "source_event.h"
48 #include "source_description.h"
49 #include "user_rec.h"
50 #include "gom.h"
51 #include "gedcom.h"
52 #include "gom_internal.h"
53
54 struct user_rec* gom_first_user_rec = NULL;
55
56 Gedcom_ctxt user_rec_start(_REC_PARAMS_)
57 {
58   struct user_rec* user = NULL;
59   struct xref_value* xr = NULL;
60   Gom_ctxt result  = NULL;
61   Gedcom_ctxt ctxt = NULL;
62   int err = 0;
63   
64   if (GEDCOM_IS_XREF_PTR(xref))
65     xr = GEDCOM_XREF_PTR(xref);
66   if (xr) {
67     if (! xr->object) {
68       user = MAKEFUNC(user_rec)(xr->string);
69       xr->object = (Gedcom_ctxt) user;
70     }
71     ctxt = xr->object;
72     if (ctxt) {
73       user = (struct user_rec*) ctxt;
74     }
75   }
76   else {
77     user = MAKEFUNC(user_rec)(NULL);
78     ctxt = (Gedcom_ctxt) user;
79   }
80
81   if (user) {
82     user->tag = strdup(tag);
83     if (! user->tag) {
84       MEMORY_ERROR;
85       err = 1;
86     }
87     else if (GEDCOM_IS_STRING(parsed_value)) {
88       user->str_value = strdup(GEDCOM_STRING(parsed_value));
89       if (!user->str_value) {
90         MEMORY_ERROR;
91         err = 1;
92       }
93     }
94     else if (GEDCOM_IS_XREF_PTR(parsed_value))
95       user->xref_value = GEDCOM_XREF_PTR(parsed_value);
96     
97     if (! err)
98       result = MAKE_GOM_CTXT(rec, user_rec, ctxt);
99   }
100   
101   return (Gedcom_ctxt)result;
102 }
103
104 DEFINE_DESTROYFUNC(user_rec, gom_first_user_rec)
105 DEFINE_DELETEFUNC(user_rec)
106 DEFINE_GETXREFFUNC(user_rec, XREF_USER)
107
108 DEFINE_ADDFUNC2(user_rec, user_data, extra)
109
110 /* Specific function, because xrefstr not mandatory here */
111 struct user_rec* MAKEFUNC(user_rec)(const char* xrefstr)
112 {
113   struct user_rec* rec = NULL;
114   MAKE_CHAIN_ELT(user_rec, gom_first_user_rec, rec);
115   if (rec && xrefstr) {
116     rec->xrefstr = strdup(xrefstr);
117     if (! rec->xrefstr) MEMORY_ERROR;
118   }
119   return rec;
120 }
121
122 struct user_rec* ADDFUNC(user_rec)(const char* xrefstr, const char* tag)
123 {
124   struct user_rec *obj = NULL;
125   struct xref_value* xrv = gedcom_get_by_xref(xrefstr);
126   if (tag && tag[0] == '_') {
127     if (xrv)
128       gom_xref_already_in_use(xrefstr);
129     else {
130       obj = MAKEFUNC(user_rec)(xrefstr);
131       if (obj) {
132         obj->tag = strdup(tag);
133         if (! obj->tag)
134           MEMORY_ERROR;
135         else
136           xrv = gedcom_add_xref(XREF_USER, xrefstr, (Gedcom_ctxt)obj);
137         if (!xrv) {
138           DESTROYFUNC(user_rec)(obj);
139           obj = NULL;
140         }
141       }
142     }
143   }
144   return obj;
145 }
146
147 Gedcom_ctxt user_elt_start(_ELT_PARAMS_)
148 {
149   Gom_ctxt ctxt = (Gom_ctxt)parent;
150   Gom_ctxt result = NULL;
151   int err = 0;
152
153   if (! ctxt)
154     NO_CONTEXT;
155   else {
156     struct user_data *data
157       = (struct user_data *)malloc(sizeof(struct user_data));
158
159     if (! data)
160       MEMORY_ERROR;
161     else {
162       memset (data, 0, sizeof(struct user_data));
163       
164       data->level = level;
165       data->tag = strdup(tag);
166       if (! data->tag) {
167         MEMORY_ERROR;
168         free(data);
169         err = 1;
170       }
171       else if (GEDCOM_IS_STRING(parsed_value)) {
172         data->str_value = strdup(GEDCOM_STRING(parsed_value));
173         if (! data->str_value) {
174           MEMORY_ERROR;
175           free(data->tag);
176           free(data->str_value);
177           err = 1;
178         }
179       }
180       else if (GEDCOM_IS_XREF_PTR(parsed_value))
181         data->xref_value = GEDCOM_XREF_PTR(parsed_value);
182
183       if (! err) {
184         printf("Tag: %s, value: %s\n", data->tag, data->str_value);
185         switch (ctxt->obj_type) {
186           case T_header:
187             ADDFUNC2(header,user_data)(ctxt, data); break;
188           case T_submission:
189             ADDFUNC2(submission,user_data)(ctxt, data); break;
190           case T_submitter:
191             ADDFUNC2(submitter,user_data)(ctxt, data); break;
192           case T_family:
193             ADDFUNC2(family,user_data)(ctxt, data); break;
194           case T_individual:
195             ADDFUNC2(individual,user_data)(ctxt, data); break;
196           case T_multimedia:
197             ADDFUNC2(multimedia,user_data)(ctxt, data); break;
198           case T_note:
199             ADDFUNC2(note,user_data)(ctxt, data); break;
200           case T_repository:
201             ADDFUNC2(repository,user_data)(ctxt, data); break;
202           case T_source:
203             ADDFUNC2(source,user_data)(ctxt, data); break;
204           case T_user_rec:
205             ADDFUNC2(user_rec,user_data)(ctxt, data); break;
206           case T_address:
207             ADDFUNC2(address,user_data)(ctxt, data); break;
208           case T_event:
209             ADDFUNC2(event,user_data)(ctxt, data); break;
210           case T_place:
211             ADDFUNC2(place,user_data)(ctxt, data); break;
212           case T_source_citation:
213             ADDFUNC2(source_citation,user_data)(ctxt, data); break;
214           case T_note_sub:
215             ADDFUNC2(note_sub,user_data)(ctxt, data); break;
216           case T_multimedia_link:
217             ADDFUNC2(multimedia_link,user_data)(ctxt, data); break;
218           case T_lds_event:
219             ADDFUNC2(lds_event,user_data)(ctxt, data); break;
220           case T_user_ref_number:
221             ADDFUNC2(user_ref_number,user_data)(ctxt, data); break;
222           case T_change_date:
223             ADDFUNC2(change_date,user_data)(ctxt, data); break;
224           case T_personal_name:
225             ADDFUNC2(personal_name,user_data)(ctxt, data); break;
226           case T_family_link:
227             ADDFUNC2(family_link,user_data)(ctxt, data); break;
228           case T_association:
229             ADDFUNC2(association,user_data)(ctxt, data); break;
230           case T_source_event:
231             ADDFUNC2(source_event,user_data)(ctxt, data); break;
232           case T_source_description:
233             ADDFUNC2(source_description,user_data)(ctxt, data); break;
234           default:
235             UNEXPECTED_CONTEXT(ctxt->ctxt_type);
236         }
237         result = make_gom_ctxt(elt, ctxt->obj_type, ctxt->ctxt_ptr);
238       }
239     }
240   }
241   
242   return (Gedcom_ctxt)result;
243 }
244
245 void user_rec_subscribe()
246 {
247   gedcom_subscribe_to_record(REC_USER, user_rec_start, def_rec_end);
248   gedcom_subscribe_to_element(ELT_USER, user_elt_start, def_elt_end);
249 }
250
251 void UNREFALLFUNC(user_data)(struct user_data *obj)
252 {
253   if (obj) {
254     struct user_data* runner;
255     for (runner = obj; runner; runner = runner->next)
256       unref_xref_value(runner->xref_value);
257   }
258 }
259
260 void CLEANFUNC(user_data)(struct user_data* data)
261 {
262   if (data) {
263     SAFE_FREE(data->tag);
264     SAFE_FREE(data->str_value);
265   }
266 }
267
268 void UNREFALLFUNC(user_rec)(struct user_rec *obj)
269 {
270   if (obj) {
271     unref_xref_value(obj->xref_value);
272     UNREFALLFUNC(user_data)(obj->extra);
273   }
274 }
275
276 void CLEANFUNC(user_rec)(struct user_rec* rec)
277 {
278   if (rec) {
279     SAFE_FREE(rec->xrefstr);
280     SAFE_FREE(rec->tag);
281     SAFE_FREE(rec->str_value);
282     DESTROY_CHAIN_ELTS(user_data, rec->extra);
283   }
284 }
285
286 void user_recs_cleanup()
287 {
288   DESTROY_CHAIN_ELTS(user_rec, gom_first_user_rec);
289 }
290
291 struct user_rec* gom_get_first_user_rec()
292 {
293   return gom_first_user_rec;
294 }
295
296 int write_user_recs(Gedcom_write_hndl hndl)
297 {
298   int result = 0;
299   struct user_rec* obj;
300
301   for (obj = gom_first_user_rec; obj; obj = obj->next) {
302     if (obj->xref_value)
303       result |= gedcom_write_user_xref(hndl, 0, obj->tag, obj->xrefstr,
304                                        obj->xref_value);
305     else
306       result |= gedcom_write_user_str(hndl, 0, obj->tag, obj->xrefstr,
307                                       obj->str_value);
308     if (obj->extra)
309       result |= write_user_data(hndl, obj->extra);
310   }
311   return result;  
312 }
313
314 int write_user_data(Gedcom_write_hndl hndl, struct user_data* data)
315 {
316   int result = 0;
317   struct user_data* obj;
318
319   if (!data) return 1;
320
321   for (obj = data; obj; obj = obj->next) {
322     if (obj->xref_value)
323       result |= gedcom_write_user_xref(hndl, obj->level, obj->tag, NULL,
324                                        obj->xref_value);
325     else {
326       result |= gedcom_write_user_str(hndl, obj->level, obj->tag, NULL,
327                                       obj->str_value);
328     }
329   }
330   return result;
331 }