Small comments.
[gedcom-parse.git] / gedcom / compat.c
1 /* Compatibility handling for the GEDCOM parser.
2    Copyright (C) 2001, 2002 The Genes Development Team
3    This file is part of the Gedcom parser library.
4    Contributed by Peter Verthez <Peter.Verthez@advalvas.be>, 2001.
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 "compat.h"
25 #include "interface.h"
26 #include "encoding.h"
27 #include "xref.h"
28 #include "gedcom_internal.h"
29 #include "gedcom.h"
30
31 int compat_enabled = 1;
32 int compatibility  = 0; 
33 int compat_at = 0;
34 char* default_charset;
35
36 #define SUBMITTER_LINK         "@__COMPAT__SUBM__@"
37 #define DEFAULT_SUBMITTER_NAME "Submitter"
38 #define DEFAULT_GEDCOM_VERS    "5.5"
39 #define DEFAULT_GEDCOM_FORM    "LINEAGE-LINKED"
40
41 /* Incompatibility list (with GEDCOM 5.5):
42
43     - ftree:
44         - no submitter record, no submitter link in the header
45         - INDI.ADDR instead of INDI.RESI.ADDR
46         - NOTE doesn't have a value
47
48     - Lifelines (3.0.2):
49         - no submitter record, no submitter link in the header
50         - no GEDC field in the header
51         - no CHAR field in the header
52         - HEAD.TIME instead of HEAD.DATE.TIME (will be ignored here)
53         - '@' not written as '@@' in values
54         - lots of missing required values
55  */
56
57 /* Compatibility handling */
58
59 void gedcom_set_compat_handling(int enable_compat)
60 {
61   compat_enabled = enable_compat;
62 }
63
64 void set_compatibility(char* program)
65 {
66   if (compat_enabled) {
67     if (! strncmp(program, "ftree", 6)) {
68       gedcom_warning(_("Enabling compatibility with 'ftree'"));
69       compatibility = C_FTREE;
70       default_charset = "ANSI";
71     }
72     else if (! strncmp(program, "LIFELINES", 9)) {
73       /* Matches "LIFELINES 3.0.2" */
74       gedcom_warning(_("Enabling compatibility with 'Lifelines'"));
75       compatibility = C_LIFELINES;
76       default_charset = "ANSI";
77       compat_at = 1;
78     }
79     else {
80       compatibility = 0;
81     }
82   }
83 }
84
85 int compat_mode(int compat_flags)
86 {
87   return (compat_flags & compatibility);
88 }
89
90 void compat_generate_submitter_link(Gedcom_ctxt parent)
91 {
92   struct xref_value *xr = gedcom_parse_xref(SUBMITTER_LINK, XREF_USED,
93                                             XREF_SUBM);
94   struct tag_struct ts;
95   Gedcom_ctxt self;
96   
97   ts.string = "SUBM";
98   ts.value  = TAG_SUBM;
99   self = start_element(ELT_HEAD_SUBM,
100                        parent, 1, ts, SUBMITTER_LINK,
101                        GEDCOM_MAKE_XREF_PTR(val1, xr));
102   end_element(ELT_HEAD_SUBM, parent, self, NULL);
103 }
104
105 void compat_generate_submitter()
106 {
107   struct xref_value *xr = gedcom_parse_xref(SUBMITTER_LINK, XREF_DEFINED,
108                                             XREF_SUBM);
109   struct tag_struct ts;
110   Gedcom_ctxt self1, self2;
111
112   /* first generate "0 SUBM" */
113   ts.string = "SUBM";
114   ts.value  = TAG_SUBM;
115   self1 = start_record(REC_SUBM, 0, GEDCOM_MAKE_XREF_PTR(val1, xr), ts,
116                        NULL, GEDCOM_MAKE_NULL(val2));
117
118   /* then generate "1 NAME ..." */
119   ts.string = "NAME";
120   ts.value  = TAG_NAME;
121   self2 = start_element(ELT_SUBM_NAME, self1, 1, ts, DEFAULT_SUBMITTER_NAME,
122                         GEDCOM_MAKE_STRING(val1, DEFAULT_SUBMITTER_NAME));
123
124   /* close "1 NAME ..." */
125   end_element(ELT_SUBM_NAME, self1, self2, NULL);
126
127   /* close "0 SUBM" */
128   end_record(REC_SUBM, self1);
129 }
130
131 void compat_generate_gedcom(Gedcom_ctxt parent)
132 {
133   struct tag_struct ts;
134   Gedcom_ctxt self1, self2;
135   
136   /* first generate "1 GEDC" */
137   ts.string = "GEDC";
138   ts.value  = TAG_GEDC;
139   self1 = start_element(ELT_HEAD_GEDC, parent, 1, ts, NULL,
140                         GEDCOM_MAKE_NULL(val1));
141   
142   /* then generate "2 VERS <DEFAULT_GEDC_VERS>" */
143   ts.string = "VERS";
144   ts.value  = TAG_VERS;
145   self2 = start_element(ELT_HEAD_GEDC_VERS, self1, 2, ts,
146                         DEFAULT_GEDCOM_VERS,
147                         GEDCOM_MAKE_STRING(val1, DEFAULT_GEDCOM_VERS));
148   
149   /* close "2 VERS" */
150   end_element(ELT_HEAD_GEDC_VERS, self1, self2, NULL);
151   
152   /* then generate "2 FORM <DEFAULT_GEDCOM_FORM> */
153   ts.string = "FORM";
154   ts.value  = TAG_FORM;
155   self2 = start_element(ELT_HEAD_GEDC_FORM, self1, 2, ts,
156                         DEFAULT_GEDCOM_FORM,
157                         GEDCOM_MAKE_STRING(val1, DEFAULT_GEDCOM_FORM));
158   
159   /* close "2 FORM" */
160   end_element(ELT_HEAD_GEDC_FORM, self1, self2, NULL);
161   
162   /* close "1 GEDC" */
163   end_element(ELT_HEAD_GEDC, parent, self1, NULL);
164 }
165
166 int compat_generate_char(Gedcom_ctxt parent)
167 {
168   struct tag_struct ts;
169   Gedcom_ctxt self1;
170   
171   /* first generate "1 CHAR <DEFAULT_CHAR>" */
172   ts.string = "CHAR";
173   ts.value  = TAG_CHAR;
174   self1 = start_element(ELT_HEAD_CHAR, parent, 1, ts, default_charset,
175                         GEDCOM_MAKE_STRING(val1, default_charset));
176   
177   /* close "1 CHAR" */
178   end_element(ELT_HEAD_CHAR, parent, self1, NULL);
179   if (open_conv_to_internal(default_charset) == 0)
180     return 1;
181   else
182     return 0;
183 }
184
185 Gedcom_ctxt compat_generate_resi_start(Gedcom_ctxt parent)
186 {
187   Gedcom_ctxt self;
188   struct tag_struct ts;
189
190   ts.string = "RESI";
191   ts.value  = TAG_RESI;
192   self = start_element(ELT_SUB_INDIV_RESI, parent, 1, ts, NULL,
193                        GEDCOM_MAKE_NULL(val1));
194   return self;
195 }
196
197 void compat_generate_resi_end(Gedcom_ctxt parent, Gedcom_ctxt self)
198 {
199   end_element(ELT_SUB_INDIV_RESI, parent, self, NULL);
200 }