Unlink xrefs properly when struct is deleted.
[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 = SUB_MAKEFUNC(address)();
45     if (addr) {
46       switch (ctxt->ctxt_type) {
47         case ELT_HEAD_SOUR_CORP:
48           ADDFUNC2_NOLIST(header,address)(ctxt, addr); break;
49         case ELT_SUB_FAM_EVT:
50         case ELT_SUB_FAM_EVT_EVEN:
51         case ELT_SUB_INDIV_ATTR:
52         case ELT_SUB_INDIV_RESI:
53         case ELT_SUB_INDIV_BIRT:
54         case ELT_SUB_INDIV_GEN:
55         case ELT_SUB_INDIV_ADOP:
56         case ELT_SUB_INDIV_EVEN:
57           ADDFUNC2_NOLIST(event,address)(ctxt, addr); break;
58         case REC_REPO:
59           ADDFUNC2_NOLIST(repository,address)(ctxt, addr); break;
60         case REC_SUBM:
61           ADDFUNC2_NOLIST(submitter,address)(ctxt, addr); break;
62         default:
63           UNEXPECTED_CONTEXT(ctxt->ctxt_type);
64       }
65       result = MAKE_GOM_CTXT(elt, address, addr);
66     }
67   }
68   
69   return (Gedcom_ctxt)result;
70 }
71
72 Gedcom_ctxt sub_addr_cont_start(_ELT_PARAMS_)
73 {
74   Gom_ctxt ctxt = (Gom_ctxt)parent;
75   Gom_ctxt result = NULL;
76   if (! ctxt)
77     NO_CONTEXT;
78   else {
79     result = make_gom_ctxt(elt, ctxt->ctxt_type, ctxt->ctxt_ptr);
80   }
81   return (Gedcom_ctxt)result;
82 }
83
84 DEFINE_SUB_MAKEFUNC(address)
85 DEFINE_SUB_ADDFUNC(address)
86 DEFINE_SUB_DELETEFUNC(address)
87
88 DEFINE_STRING_END_CB(address, sub_addr_end, full_label)
89 DEFINE_STRING_CB(address, sub_addr_adr1_start, line1)
90 DEFINE_STRING_CB(address, sub_addr_adr2_start, line2)
91 DEFINE_STRING_CB(address, sub_addr_city_start, city)
92 DEFINE_STRING_CB(address, sub_addr_stae_start, state)
93 DEFINE_STRING_CB(address, sub_addr_post_start, postal)
94 DEFINE_STRING_CB(address, sub_addr_ctry_start, country)
95
96 DEFINE_ADDFUNC2(address, user_data, extra)
97
98 Gedcom_ctxt sub_phon_start(_ELT_PARAMS_)
99 {
100   Gom_ctxt ctxt = (Gom_ctxt)parent;
101   Gom_ctxt result = NULL;
102
103   if (! ctxt)
104     NO_CONTEXT;
105   else {
106     char *str = GEDCOM_STRING(parsed_value);
107     switch (ctxt->ctxt_type) {
108       case ELT_HEAD_SOUR_CORP:
109         header_add_phone(ctxt, str); break;
110       case ELT_SUB_FAM_EVT:
111       case ELT_SUB_INDIV_ATTR:
112       case ELT_SUB_INDIV_RESI:
113       case ELT_SUB_INDIV_BIRT:
114       case ELT_SUB_INDIV_GEN:
115       case ELT_SUB_INDIV_ADOP:
116       case ELT_SUB_INDIV_EVEN:
117         event_add_phone(ctxt, str); break;
118       case REC_REPO:
119         repository_add_phone(ctxt, str); break;
120       case REC_SUBM:
121         submitter_add_phone(ctxt, str); break;
122       default:
123         UNEXPECTED_CONTEXT(ctxt->ctxt_type);
124     }
125     result = make_gom_ctxt(elt, ctxt->obj_type, ctxt->ctxt_ptr);
126   }
127   return (Gedcom_ctxt)result;
128 }
129
130 void address_subscribe()
131 {
132   gedcom_subscribe_to_element(ELT_SUB_ADDR, sub_addr_start, sub_addr_end);
133   gedcom_subscribe_to_element(ELT_SUB_ADDR_CONT,
134                               sub_addr_cont_start, def_elt_end);
135   gedcom_subscribe_to_element(ELT_SUB_ADDR_ADR1,
136                               sub_addr_adr1_start, def_elt_end);
137   gedcom_subscribe_to_element(ELT_SUB_ADDR_ADR2,
138                               sub_addr_adr2_start, def_elt_end);
139   gedcom_subscribe_to_element(ELT_SUB_ADDR_CITY,
140                               sub_addr_city_start, def_elt_end);
141   gedcom_subscribe_to_element(ELT_SUB_ADDR_STAE,
142                               sub_addr_stae_start, def_elt_end);
143   gedcom_subscribe_to_element(ELT_SUB_ADDR_POST,
144                               sub_addr_post_start, def_elt_end);
145   gedcom_subscribe_to_element(ELT_SUB_ADDR_CTRY,
146                               sub_addr_ctry_start, def_elt_end);
147   gedcom_subscribe_to_element(ELT_SUB_PHON, sub_phon_start, def_elt_end);
148 }
149
150 void UNREFALLFUNC(address)(struct address *address)
151 {
152   if (address) {
153     UNREFALLFUNC(user_data)(address->extra);
154   }
155 }
156
157 void CLEANFUNC(address)(struct address *address)
158 {
159   if (address) {
160     SAFE_FREE(address->full_label);
161     SAFE_FREE(address->line1);
162     SAFE_FREE(address->line2);
163     SAFE_FREE(address->city);
164     SAFE_FREE(address->state);
165     SAFE_FREE(address->postal);
166     SAFE_FREE(address->country);
167     DESTROY_CHAIN_ELTS(user_data, address->extra);
168   }
169   SAFE_FREE(address);
170 }
171
172 int write_address(Gedcom_write_hndl hndl, int parent, struct address *address)
173 {
174   int result = 0;
175
176   if (!address) return 1;
177   
178   if (address->full_label)
179     result |= gedcom_write_element_str(hndl, ELT_SUB_ADDR, 0, parent,
180                                        address->full_label);
181   if (address->line1)
182     result |= gedcom_write_element_str(hndl, ELT_SUB_ADDR_ADR1, 0,
183                                        ELT_SUB_ADDR, address->line1);
184   if (address->line2)
185     result |= gedcom_write_element_str(hndl, ELT_SUB_ADDR_ADR2, 0,
186                                        ELT_SUB_ADDR, address->line2);
187   if (address->city)
188     result |= gedcom_write_element_str(hndl, ELT_SUB_ADDR_CITY, 0,
189                                        ELT_SUB_ADDR, address->city);
190   if (address->state)
191     result |= gedcom_write_element_str(hndl, ELT_SUB_ADDR_STAE, 0,
192                                        ELT_SUB_ADDR, address->state);
193   if (address->postal)
194     result |= gedcom_write_element_str(hndl, ELT_SUB_ADDR_POST, 0,
195                                        ELT_SUB_ADDR, address->postal);
196   if (address->country)
197     result |= gedcom_write_element_str(hndl, ELT_SUB_ADDR_CTRY, 0,
198                                        ELT_SUB_ADDR, address->country);
199   if (address->extra)
200     result |= write_user_data(hndl, address->extra);
201
202   return result;
203 }