1 /* Test program for the Gedcom library.
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.
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.
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.
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
26 #include "portability.h"
33 #include "utf8tools.h"
35 #define BOGUS_FILE_NAME "bogus.ged"
36 int total_conv_fails = 0;
40 printf("gedcom-parse test program for libgedcom\n\n");
41 printf("Usage: testgedcom [options] file\n");
43 printf(" -h Show this help text\n");
44 printf(" -nc Disable compatibility mode\n");
45 printf(" -fi Fail immediately on errors\n");
46 printf(" -fd Deferred fail on errors, but parse completely\n");
47 printf(" -fn No fail on errors\n");
48 printf(" -dg Debug setting: only libgedcom debug messages\n");
49 printf(" -da Debug setting: libgedcom + yacc debug messages\n");
50 printf(" -2 Run the test parse 2 times instead of once\n");
51 printf(" -3 Run the test parse 3 times instead of once\n");
52 printf(" -b Parse a bogus file (bogus.ged) before parsing the main file\n");
53 printf(" -q No output to standard output\n");
54 printf(" -o <outfile> File to generate output to (def. testgedcom.out)\n");
57 Gedcom_ctxt header_start(Gedcom_rec rec, int level, Gedcom_val xref, char *tag,
58 char *raw_value, int tag_value,
59 Gedcom_val parsed_value)
61 output(1, "Header start\n");
62 return (Gedcom_ctxt)1;
65 void header_end(Gedcom_rec rec, Gedcom_ctxt self, Gedcom_val parsed_value)
67 output(1, "Header end, context is %ld\n", void_ptr_to_int(self));
71 char family_xreftags[MAXFAMILY][255];
74 Gedcom_ctxt family_start(Gedcom_rec rec, int level, Gedcom_val xref, char *tag,
75 char *raw_value, int tag_value,
76 Gedcom_val parsed_value)
78 struct xref_value *xr = GEDCOM_XREF_PTR(xref);
79 output(1, "Family start, xref is %s\n", xr->string);
80 if (family_nr < MAXFAMILY) {
81 strcpy(family_xreftags[family_nr], xr->string);
83 xr->object = (Gedcom_ctxt)int_to_void_ptr(family_nr);
84 return (Gedcom_ctxt)int_to_void_ptr(family_nr++);
87 Gedcom_ctxt rec_start(Gedcom_rec rec, int level, Gedcom_val xref, char *tag,
88 char *raw_value, int tag_value,
89 Gedcom_val parsed_value)
91 char* xref_str = NULL;
92 if (! GEDCOM_IS_NULL(xref))
93 xref_str = GEDCOM_XREF_PTR(xref)->string;
94 output(1, "Rec %s start, xref is %s\n", tag, xref_str);
95 return (Gedcom_ctxt)int_to_void_ptr(tag_value);
98 Gedcom_ctxt note_start(Gedcom_rec rec, int level, Gedcom_val xref, char *tag,
99 char *raw_value, int tag_value,
100 Gedcom_val parsed_value)
102 output(1, "== %d %s (%d) %s (xref is %s)\n",
103 level, tag, tag_value, GEDCOM_STRING(parsed_value),
104 GEDCOM_XREF_PTR(xref)->string);
105 return (Gedcom_ctxt)int_to_void_ptr(tag_value);
108 void family_end(Gedcom_rec rec, Gedcom_ctxt self, Gedcom_val parsed_value)
110 char* family_xref = "<NOTSAVED>";
111 int family_nr = void_ptr_to_int(self);
112 if (family_nr < MAXFAMILY)
113 family_xref = family_xreftags[void_ptr_to_int(self)];
114 output(1, "Family end, xref is %s\n", family_xref);
117 Gedcom_ctxt submit_start(Gedcom_rec rec, int level, Gedcom_val xref, char *tag,
118 char *raw_value, int tag_value,
119 Gedcom_val parsed_value)
121 output(1, "Submitter, xref is %s\n", GEDCOM_XREF_PTR(xref)->string);
122 return (Gedcom_ctxt)10000;
125 Gedcom_ctxt source_start(Gedcom_elt elt, Gedcom_ctxt parent, int level,
126 char *tag, char* raw_value,
127 int tag_value, Gedcom_val parsed_value)
129 Gedcom_ctxt self = (Gedcom_ctxt)(void_ptr_to_int(parent) + 1000);
130 output(1, "Source is %s (ctxt is %ld, parent is %ld)\n",
131 GEDCOM_STRING(parsed_value), void_ptr_to_int(self),
132 void_ptr_to_int(parent));
136 void source_end(Gedcom_elt elt, Gedcom_ctxt parent, Gedcom_ctxt self,
137 Gedcom_val parsed_value)
139 output(1, "Source context %ld in parent %ld\n",
140 void_ptr_to_int(self), void_ptr_to_int(parent));
143 Gedcom_ctxt head_note_start(Gedcom_elt elt, Gedcom_ctxt parent, int level,
144 char *tag, char* raw_value,
145 int tag_value, Gedcom_val parsed_value)
147 Gedcom_ctxt self = (Gedcom_ctxt)(void_ptr_to_int(parent));
148 output(1, "Note: %s (ctxt is %ld, parent is %ld)\n",
149 GEDCOM_STRING(parsed_value), void_ptr_to_int(self),
150 void_ptr_to_int(parent));
154 void head_note_end(Gedcom_elt elt, Gedcom_ctxt parent, Gedcom_ctxt self,
155 Gedcom_val parsed_value)
157 output(1, "Complete note:\n%s\n", GEDCOM_STRING(parsed_value));
160 Gedcom_ctxt date_start(Gedcom_elt elt, Gedcom_ctxt parent, int level,
161 char *tag, char* raw_value,
162 int tag_value, Gedcom_val parsed_value)
164 struct date_value dv;
165 Gedcom_ctxt self = (Gedcom_ctxt)(void_ptr_to_int(parent) + 1000);
166 dv = GEDCOM_DATE(parsed_value);
167 output(1, "Contents of the date_value:\n");
168 output(1, " raw value: %s\n", raw_value);
169 output(1, " type: %d\n", dv.type);
170 output(1, " date1:\n");
171 output(1, " calendar type: %d\n", dv.date1.cal);
172 output(1, " day: %s\n", dv.date1.day_str);
173 output(1, " month: %s\n", dv.date1.month_str);
174 output(1, " year: %s\n", dv.date1.year_str);
175 output(1, " date type: %d\n", dv.date1.type);
176 output(1, " sdn1: %ld\n", dv.date1.sdn1);
177 output(1, " sdn2: %ld\n", dv.date1.sdn2);
178 output(1, " date2:\n");
179 output(1, " calendar type: %d\n", dv.date2.cal);
180 output(1, " day: %s\n", dv.date2.day_str);
181 output(1, " month: %s\n", dv.date2.month_str);
182 output(1, " year: %s\n", dv.date2.year_str);
183 output(1, " date type: %d\n", dv.date2.type);
184 output(1, " sdn1: %ld\n", dv.date2.sdn1);
185 output(1, " sdn2: %ld\n", dv.date2.sdn2);
186 output(1, " phrase: %s\n", dv.phrase);
190 Gedcom_ctxt age_start(Gedcom_elt elt, Gedcom_ctxt parent, int level,
191 char *tag, char *raw_value,
192 int tag_value, Gedcom_val parsed_value)
194 struct age_value age;
195 Gedcom_ctxt self = (Gedcom_ctxt)(void_ptr_to_int(parent) + 1000);
196 age = GEDCOM_AGE(parsed_value);
197 output(1, "Contents of the age_value:\n");
198 output(1, " raw value: %s\n", raw_value);
199 output(1, " type: %d\n", age.type);
200 output(1, " modifier: %d\n", age.mod);
201 output(1, " years: %d\n", age.years);
202 output(1, " months: %d\n", age.months);
203 output(1, " days: %d\n", age.days);
204 output(1, " phrase: %s\n", age.phrase);
208 void default_cb(Gedcom_elt elt, Gedcom_ctxt ctxt, int level, char *tag,
209 char *raw_value, int tag_value)
211 char *converted = NULL;
214 converted = convert_utf8_to_locale(raw_value, &conv_fails);
215 output(0, "== %d %s (%d) %s (ctxt is %ld, conversion failures: %d)\n",
216 level, tag, tag_value, converted, void_ptr_to_int(ctxt), conv_fails);
217 total_conv_fails += conv_fails;
220 void subscribe_callbacks()
222 gedcom_subscribe_to_record(REC_HEAD, header_start, header_end);
223 gedcom_subscribe_to_record(REC_FAM, family_start, family_end);
224 gedcom_subscribe_to_record(REC_INDI, rec_start, NULL);
225 gedcom_subscribe_to_record(REC_OBJE, rec_start, NULL);
226 gedcom_subscribe_to_record(REC_NOTE, note_start, NULL);
227 gedcom_subscribe_to_record(REC_REPO, rec_start, NULL);
228 gedcom_subscribe_to_record(REC_SOUR, rec_start, NULL);
229 gedcom_subscribe_to_record(REC_SUBN, rec_start, NULL);
230 gedcom_subscribe_to_record(REC_SUBM, submit_start, NULL);
231 gedcom_subscribe_to_record(REC_USER, rec_start, NULL);
232 gedcom_subscribe_to_element(ELT_HEAD_SOUR, source_start, source_end);
233 gedcom_subscribe_to_element(ELT_HEAD_NOTE, head_note_start, head_note_end);
234 gedcom_subscribe_to_element(ELT_SOUR_DATA_EVEN_DATE,
236 gedcom_subscribe_to_element(ELT_SUB_EVT_DATE, date_start, NULL);
237 gedcom_subscribe_to_element(ELT_SUB_FAM_EVT_AGE, age_start, NULL);
240 void gedcom_message_handler(Gedcom_msg_type type, char *msg)
243 output(1, "MESSAGE: ");
244 else if (type == WARNING)
245 output(1, "WARNING: ");
246 else if (type == ERROR)
247 output(1, "ERROR: ");
248 output(1, "%s\n", msg);
251 int main(int argc, char* argv[])
253 Gedcom_err_mech mech = IMMED_FAIL;
254 int compat_enabled = 1;
259 char* outfilename = NULL;
260 char* file_name = NULL;
264 for (i=1; i<argc; i++) {
265 if (!strncmp(argv[i], "-da", 4))
267 else if (!strncmp(argv[i], "-dg", 4))
269 else if (!strncmp(argv[i], "-fi", 4))
271 else if (!strncmp(argv[i], "-fd", 4))
273 else if (!strncmp(argv[i], "-fn", 4))
274 mech = IGNORE_ERRORS;
275 else if (!strncmp(argv[i], "-nc", 4))
277 else if (!strncmp(argv[i], "-h", 3)) {
281 else if (!strncmp(argv[i], "-2", 3)) {
284 else if (!strncmp(argv[i], "-3", 3)) {
287 else if (!strncmp(argv[i], "-b", 3)) {
290 else if (!strncmp(argv[i], "-q", 3)) {
293 else if (!strncmp(argv[i], "-o", 3)) {
296 outfilename = argv[i];
299 printf ("Missing output file name\n");
304 else if (strncmp(argv[i], "-", 1)) {
309 printf ("Unrecognized option: %s\n", argv[i]);
317 printf("No file name given\n");
323 setlocale(LC_ALL, "");
324 gedcom_set_debug_level(debug_level, NULL);
325 gedcom_set_compat_handling(compat_enabled);
326 gedcom_set_compat_options(COMPAT_ALLOW_OUT_OF_CONTEXT);
327 gedcom_set_error_handling(mech);
328 gedcom_set_message_handler(gedcom_message_handler);
329 gedcom_set_default_callback(default_cb);
331 subscribe_callbacks();
332 output_open(outfilename);
334 output(0, "\n=== Parsing bogus file %s\n", BOGUS_FILE_NAME);
335 gedcom_parse_file(BOGUS_FILE_NAME);
337 while (run_times-- > 0) {
338 output(0, "\n=== Parsing file %s\n", simple_base_name(file_name));
339 result |= gedcom_parse_file(file_name);
340 output(0, "\n=== Total conversion failures: %d\n", total_conv_fails);
343 output(1, "Parse succeeded\n");
346 output(1, "Parse failed\n");