renamed the package to libgedcom-dev
[gedcom-parse.git] / gom / gom.c
1 /* Main file for building 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 <stdio.h>
27 #include "gedcom.h"
28 #include "header.h"
29 #include "submitter.h"
30 #include "submission.h"
31 #include "family.h"
32 #include "individual.h"
33 #include "multimedia.h"
34 #include "note.h"
35 #include "repository.h"
36 #include "source.h"
37 #include "user_rec.h"
38 #include "address.h"
39 #include "event.h"
40 #include "place.h"
41 #include "source_citation.h"
42 #include "multimedia_link.h"
43 #include "note_sub.h"
44 #include "lds_event.h"
45 #include "user_ref.h"
46 #include "change_date.h"
47 #include "personal_name.h"
48 #include "family_link.h"
49 #include "association.h"
50 #include "source_event.h"
51 #include "source_description.h"
52 #include "gom.h"
53 #include "gom_internal.h"
54
55 void gom_default_callback (Gedcom_elt elt, Gedcom_ctxt parent, int level,
56                            char* tag, char* raw_value, int parsed_tag);
57
58 void gom_cleanup()
59 {
60   header_cleanup();
61   submission_cleanup();
62   families_cleanup();
63   individuals_cleanup();
64   multimedias_cleanup();
65   notes_cleanup();
66   repositories_cleanup();
67   sources_cleanup();
68   submitters_cleanup();
69   user_recs_cleanup();
70 }
71
72 void subscribe_all()
73 {
74   gedcom_set_default_callback(gom_default_callback);
75   header_subscribe();
76   submission_subscribe();
77   family_subscribe();
78   individual_subscribe();
79   multimedia_subscribe();
80   note_subscribe();
81   repository_subscribe();
82   source_subscribe();
83   submitter_subscribe();
84   user_rec_subscribe();
85   
86   address_subscribe();
87   event_subscribe();
88   place_subscribe();
89   citation_subscribe();
90   note_sub_subscribe();
91   multimedia_link_subscribe();
92   lds_event_subscribe();
93   user_ref_subscribe();
94   change_date_subscribe();
95   name_subscribe();
96   family_link_subscribe();
97   association_subscribe();
98   source_event_subscribe();
99   source_description_subscribe();
100
101   if (atexit(gom_cleanup) != 0) {
102     gedcom_warning(_("Could not register gom cleanup function"));
103   }
104 }
105
106 int gom_active = 0;
107
108 /** This function initializes the object model by parsing the given GEDCOM
109     file.
110
111     \param file_name  The input file
112
113     \retval 0 on success
114     \retval 1 on failure
115 */
116 int gom_parse_file(const char* file_name)
117 {
118   if (gom_active) {
119     gom_cleanup();
120   }
121   else {
122     gedcom_set_compat_options(COMPAT_ALLOW_OUT_OF_CONTEXT);
123     subscribe_all();
124   }
125   gom_active = 1;
126   return gedcom_parse_file(file_name);
127 }
128
129 /** This function starts an empty model.  It does this by parsing the
130     \c new.ged
131     file in the data directory of the library (\c $PREFIX/share/gedcom-parse).
132     This can be used to start from an empty model, and to build up the model
133     by adding new records yourself.
134
135     \retval 0 on success
136     \retval nonzero on errors (mainly the errors from
137             \ref gedcom_parse_file()).
138 */
139 int gom_new_model()
140 {
141   if (gom_active) {
142     gom_cleanup();
143   }
144   else {
145     subscribe_all();
146   }
147   gom_active = 1;
148   return gedcom_new_model();
149 }
150
151 /** This function writes the current Gedcom model to a file.
152
153     \param file_name  The name of the file to write to
154     \param total_conv_fails Pass a pointer to an integer if you want to know
155     the number of conversion failures (filled in on return).  You can pass
156     \c NULL if you're not interested.
157
158     \retval 0 on success
159     \retval nonzero on errors
160 */
161 int gom_write_file(const char* file_name, int *total_conv_fails)
162 {
163   Gedcom_write_hndl hndl;
164   int result = 1;
165
166   hndl = gedcom_write_open(file_name);
167   if (hndl) {
168     result = write_header(hndl);
169     result |= write_submission(hndl);
170     result |= write_submitters(hndl);
171     result |= write_individuals(hndl);
172     result |= write_families(hndl);
173     result |= write_multimedia_recs(hndl);
174     result |= write_notes(hndl);
175     result |= write_repositories(hndl);
176     result |= write_sources(hndl);
177     result |= write_user_recs(hndl);
178     result |= gedcom_write_close(hndl, total_conv_fails);
179   }
180
181   return result;
182 }
183
184 int gom_write_xref_list(Gedcom_write_hndl hndl,
185                         Gedcom_elt elt, int tag, int parent_rec_or_elt,
186                         struct xref_list* val)
187 {
188   int result = 0;
189   struct xref_list* xrl;
190   for (xrl = val; xrl; xrl = xrl->next) {
191     result |= gedcom_write_element_xref(hndl, elt, tag, parent_rec_or_elt,
192                                         xrl->xref);
193   }
194   return result;
195 }
196
197 void gom_default_callback (Gedcom_elt elt UNUSED, Gedcom_ctxt parent UNUSED,
198                            int level, char* tag, char* raw_value,
199                            int parsed_tag UNUSED)
200 {
201   gedcom_warning(_("Data loss in import: \"%d %s %s\""),
202                  level, tag, raw_value);
203 }
204
205 void gom_mem_error(const char *filename, int line)
206 {
207   gedcom_error(_("Could not allocate memory at %s, %d"), filename, line);
208 }
209
210 void gom_xref_already_in_use(const char *xrefstr)
211 {
212   gedcom_error(_("Cross-reference key '%s' is already in use"), xrefstr);
213 }
214
215 void gom_move_error(const char* type)
216 {
217   gedcom_warning(_("Could not move struct of type %s"), type);
218 }
219
220 void gom_find_error(const char* type)
221 {
222   gedcom_warning(_("Could not find struct of type %s in chain"), type);
223 }
224
225 void set_xref_type(struct xref_value* xr, const char *str)
226 {
227   if (!strcasecmp(str, "FAM"))
228     xr->type = XREF_FAM;
229   else if (!strcasecmp(str, "INDI"))
230     xr->type = XREF_INDI;
231   else if (!strcasecmp(str, "NOTE"))
232     xr->type = XREF_NOTE;
233   else if (!strcasecmp(str, "OBJE"))
234     xr->type = XREF_OBJE;
235   else if (!strcasecmp(str, "REPO"))
236     xr->type = XREF_REPO;
237   else if (!strcasecmp(str, "SOUR"))
238     xr->type = XREF_SOUR;
239   else if (!strcasecmp(str, "SUBM"))
240     xr->type = XREF_SUBM;
241   else if (!strcasecmp(str, "SUBN"))
242     xr->type = XREF_SUBN;
243   else
244     xr->type = XREF_ANY;
245 }