More thorough error handling.
[gedcom-parse.git] / gom / address.c
1 /* Address 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 "gom_internal.h"
27 #include "header.h"
28 #include "event.h"
29 #include "address.h"
30 #include "repository.h"
31 #include "submitter.h"
32 #include "user_rec.h"
33 #include "gom.h"
34 #include "gedcom.h"
35
36 Gedcom_ctxt sub_addr_start(_ELT_PARAMS_)
37 {
38   Gom_ctxt ctxt = (Gom_ctxt)parent;
39   Gom_ctxt result = NULL;
40
41   if (!ctxt)
42     NO_CONTEXT;
43   else {
44     struct address *addr = (struct address *)malloc(sizeof(struct address));
45     if (!addr)
46       MEMORY_ERROR;
47     else {
48       char *str = GEDCOM_STRING(parsed_value);
49       memset (addr, 0, sizeof(struct address));
50       addr->full_label = strdup(str);
51       
52       if (! addr->full_label) {
53         MEMORY_ERROR;
54         free(addr);
55       }
56       else {
57         switch (ctxt->ctxt_type) {
58           case ELT_HEAD_SOUR_CORP:
59             header_add_address(ctxt, addr); break;
60           case ELT_SUB_FAM_EVT:
61           case ELT_SUB_FAM_EVT_EVEN:
62           case ELT_SUB_INDIV_ATTR:
63           case ELT_SUB_INDIV_RESI:
64           case ELT_SUB_INDIV_BIRT:
65           case ELT_SUB_INDIV_GEN:
66           case ELT_SUB_INDIV_ADOP:
67           case ELT_SUB_INDIV_EVEN:
68             event_add_address(ctxt, addr); break;
69           case REC_REPO:
70             repository_add_address(ctxt, addr); break;
71           case REC_SUBM:
72             submitter_add_address(ctxt, addr); break;
73           default:
74             UNEXPECTED_CONTEXT(ctxt->ctxt_type);
75         }
76         result = MAKE_GOM_CTXT(elt, address, addr);
77       }
78     }
79   }
80   
81   return (Gedcom_ctxt)result;
82 }
83
84 Gedcom_ctxt sub_addr_cont_start(_ELT_PARAMS_)
85 {
86   Gom_ctxt ctxt = (Gom_ctxt)parent;
87   Gom_ctxt result = NULL;
88   if (! ctxt)
89     NO_CONTEXT;
90   else {
91     struct address *addr = SAFE_CTXT_CAST(address, ctxt);
92     if (addr) {
93       char *str = GEDCOM_STRING(parsed_value);
94       char *newvalue = concat_strings (WITH_NL, addr->full_label, str);
95       if (! newvalue)
96         MEMORY_ERROR;
97       else {
98         addr->full_label = newvalue;
99         result = MAKE_GOM_CTXT(elt, address, addr);
100       }
101     }
102   }
103   return (Gedcom_ctxt)result;
104 }
105
106 STRING_CB(address, sub_addr_adr1_start, line1)
107 STRING_CB(address, sub_addr_adr2_start, line2)
108 STRING_CB(address, sub_addr_city_start, city)
109 STRING_CB(address, sub_addr_stae_start, state)
110 STRING_CB(address, sub_addr_post_start, postal)
111 STRING_CB(address, sub_addr_ctry_start, country)
112
113 Gedcom_ctxt sub_phon_start(_ELT_PARAMS_)
114 {
115   Gom_ctxt ctxt = (Gom_ctxt)parent;
116   Gom_ctxt result = NULL;
117
118   if (! ctxt)
119     NO_CONTEXT;
120   else {
121     char *str = GEDCOM_STRING(parsed_value);
122     switch (ctxt->ctxt_type) {
123       case ELT_HEAD_SOUR_CORP:
124         header_add_phone(ctxt, str); break;
125       case ELT_SUB_FAM_EVT:
126       case ELT_SUB_INDIV_ATTR:
127       case ELT_SUB_INDIV_RESI:
128       case ELT_SUB_INDIV_BIRT:
129       case ELT_SUB_INDIV_GEN:
130       case ELT_SUB_INDIV_ADOP:
131       case ELT_SUB_INDIV_EVEN:
132         event_add_phone(ctxt, str); break;
133       case REC_REPO:
134         repository_add_phone(ctxt, str); break;
135       case REC_SUBM:
136         submitter_add_phone(ctxt, str); break;
137       default:
138         UNEXPECTED_CONTEXT(ctxt->ctxt_type);
139     }
140     result = make_gom_ctxt(elt, ctxt->obj_type, ctxt->ctxt_ptr);
141   }
142   return (Gedcom_ctxt)result;
143 }
144
145 void address_subscribe()
146 {
147   gedcom_subscribe_to_element(ELT_SUB_ADDR, sub_addr_start, def_elt_end);
148   gedcom_subscribe_to_element(ELT_SUB_ADDR_CONT,
149                               sub_addr_cont_start, def_elt_end);
150   gedcom_subscribe_to_element(ELT_SUB_ADDR_ADR1,
151                               sub_addr_adr1_start, def_elt_end);
152   gedcom_subscribe_to_element(ELT_SUB_ADDR_ADR2,
153                               sub_addr_adr2_start, def_elt_end);
154   gedcom_subscribe_to_element(ELT_SUB_ADDR_CITY,
155                               sub_addr_city_start, def_elt_end);
156   gedcom_subscribe_to_element(ELT_SUB_ADDR_STAE,
157                               sub_addr_stae_start, def_elt_end);
158   gedcom_subscribe_to_element(ELT_SUB_ADDR_POST,
159                               sub_addr_post_start, def_elt_end);
160   gedcom_subscribe_to_element(ELT_SUB_ADDR_CTRY,
161                               sub_addr_ctry_start, def_elt_end);
162   gedcom_subscribe_to_element(ELT_SUB_PHON, sub_phon_start, def_elt_end);
163 }
164
165 void address_add_user_data(Gom_ctxt ctxt, struct user_data* data)
166 {
167   struct address *obj = SAFE_CTXT_CAST(address, ctxt);
168   if (obj)
169     LINK_CHAIN_ELT(user_data, obj->extra, data);
170 }
171
172 void address_cleanup(struct address *address)
173 {
174   if (address) {
175     SAFE_FREE(address->full_label);
176     SAFE_FREE(address->line1);
177     SAFE_FREE(address->line2);
178     SAFE_FREE(address->city);
179     SAFE_FREE(address->state);
180     SAFE_FREE(address->postal);
181     SAFE_FREE(address->country);
182     DESTROY_CHAIN_ELTS(user_data, address->extra, user_data_cleanup);
183   }
184   SAFE_FREE(address);
185 }