Moved get/set string to gom_modify.c.
[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 int gom_parse_file(const char* file_name)
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   return gedcom_parse_file(file_name);
105 }
106
107 Gom_ctxt make_gom_ctxt(int ctxt_type, OBJ_TYPE obj_type, void *ctxt_ptr)
108 {
109   Gom_ctxt ctxt   = (Gom_ctxt)malloc(sizeof(struct Gom_ctxt_struct));
110   if (! ctxt)
111     MEMORY_ERROR;
112   else {
113     ctxt->ctxt_type = ctxt_type;
114     ctxt->obj_type  = obj_type;
115     ctxt->ctxt_ptr  = ctxt_ptr;
116   }
117   return ctxt;
118 }
119
120 void NULL_DESTROY(void* anything)
121 {
122 }
123
124 void destroy_gom_ctxt(Gom_ctxt ctxt)
125 {
126   SAFE_FREE(ctxt);
127 }
128
129 void gom_cast_error(const char* file, int line,
130                     OBJ_TYPE expected, OBJ_TYPE found)
131 {
132   fprintf(stderr,
133           "Wrong gom ctxt cast at %s, line %d: expected %d, found %d\n",
134           file, line, expected, found);
135   abort();
136 }
137
138 void gom_mem_error(const char *filename, int line)
139 {
140   gedcom_error(_("Could not allocate memory at %s, %d"), filename, line);
141 }
142
143 void gom_unexpected_context(const char* file, int line, OBJ_TYPE found)
144 {
145   gedcom_warning(_("Internal error: Unexpected context at %s, line %d: %d"),
146                  file, line, found);
147 }
148
149 void gom_no_context(const char* file, int line)
150 {
151   gedcom_warning(_("Internal error: No context at %s, line %d"),
152                  file, line);
153 }
154
155 void gom_default_callback (Gedcom_elt elt, Gedcom_ctxt parent, int level,
156                            char* tag, char* raw_value, int parsed_tag)
157 {
158   gedcom_warning(_("Data loss in import: \"%d %s %s\""),
159                  level, tag, raw_value);
160 }
161
162 void def_rec_end(Gedcom_rec rec, Gedcom_ctxt self)
163 {
164   Gom_ctxt ctxt = (Gom_ctxt)self;
165   destroy_gom_ctxt(ctxt);
166 }
167
168 void def_elt_end(Gedcom_elt elt, Gedcom_ctxt parent, Gedcom_ctxt self,
169                  Gedcom_val parsed_value)
170 {
171   Gom_ctxt ctxt = (Gom_ctxt)self;
172   destroy_gom_ctxt(ctxt);
173 }
174
175 void set_xref_type(struct xref_value* xr, const char *str)
176 {
177   if (!strcasecmp(str, "FAM"))
178     xr->type = XREF_FAM;
179   else if (!strcasecmp(str, "INDI"))
180     xr->type = XREF_INDI;
181   else if (!strcasecmp(str, "NOTE"))
182     xr->type = XREF_NOTE;
183   else if (!strcasecmp(str, "OBJE"))
184     xr->type = XREF_OBJE;
185   else if (!strcasecmp(str, "REPO"))
186     xr->type = XREF_REPO;
187   else if (!strcasecmp(str, "SOUR"))
188     xr->type = XREF_SOUR;
189   else if (!strcasecmp(str, "SUBM"))
190     xr->type = XREF_SUBM;
191   else if (!strcasecmp(str, "SUBN"))
192     xr->type = XREF_SUBN;
193   else
194     xr->type = XREF_ANY;
195 }
196
197 char* concat_strings(NL_TYPE type, char *str1, const char *str2)
198 {
199   if (str1 != NULL && str2 != NULL) {
200     char *newp;
201     char *wp;
202     size_t len1 = strlen(str1);
203     size_t len2 = strlen(str2);
204     size_t len  = len1 + len2 + 1;
205     if (type == WITH_NL)
206       len++;
207     newp = (char*) realloc(str1, len);
208     if (newp == NULL)
209       return NULL;
210     wp   = newp + len1;
211     str1 = newp;
212     if (type == WITH_NL)
213       *wp++ = '\n';
214     wp = memcpy (wp, str2, len2);
215     wp += len2;
216     *wp++ = '\0';
217   }
218
219   return str1;
220 }
221
222 struct date_value* dup_date(struct date_value dv)
223 {
224   struct date_value* dv_ptr;
225   dv_ptr = (struct date_value*) malloc(sizeof(struct date_value));
226   if (! dv_ptr)
227     MEMORY_ERROR;
228   else {
229     memcpy(dv_ptr, &dv, sizeof(struct date_value));
230   }
231   return dv_ptr;
232 }
233
234 struct age_value* dup_age(struct age_value age)
235 {
236   struct age_value* age_ptr;
237   age_ptr = (struct age_value*) malloc(sizeof(struct age_value));
238   if (! age_ptr)
239     MEMORY_ERROR;
240   else {
241     memcpy(age_ptr, &age, sizeof(struct age_value));
242   }
243   return age_ptr;
244 }