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 printf("%d\n", family_nr);
82 strcpy(family_xreftags[family_nr], xr->string);
84 xr->object = (Gedcom_ctxt)int_to_void_ptr(family_nr);
85 return (Gedcom_ctxt)int_to_void_ptr(family_nr++);
88 Gedcom_ctxt rec_start(Gedcom_rec rec, int level, Gedcom_val xref, char *tag,
89 char *raw_value, int tag_value,
90 Gedcom_val parsed_value)
92 char* xref_str = NULL;
93 if (! GEDCOM_IS_NULL(xref))
94 xref_str = GEDCOM_XREF_PTR(xref)->string;
95 output(1, "Rec %s start, xref is %s\n", tag, xref_str);
96 return (Gedcom_ctxt)int_to_void_ptr(tag_value);
99 Gedcom_ctxt note_start(Gedcom_rec rec, int level, Gedcom_val xref, char *tag,
100 char *raw_value, int tag_value,
101 Gedcom_val parsed_value)
103 output(1, "== %d %s (%d) %s (xref is %s)\n",
104 level, tag, tag_value, GEDCOM_STRING(parsed_value),
105 GEDCOM_XREF_PTR(xref)->string);
106 return (Gedcom_ctxt)int_to_void_ptr(tag_value);
109 void family_end(Gedcom_rec rec, Gedcom_ctxt self, Gedcom_val parsed_value)
111 char* family_xref = "<NOTSAVED>";
112 int family_nr = void_ptr_to_int(self);
113 if (family_nr < MAXFAMILY)
114 family_xref = family_xreftags[void_ptr_to_int(self)];
115 output(1, "Family end, xref is %s\n", family_xref);
118 Gedcom_ctxt submit_start(Gedcom_rec rec, int level, Gedcom_val xref, char *tag,
119 char *raw_value, int tag_value,
120 Gedcom_val parsed_value)
122 output(1, "Submitter, xref is %s\n", GEDCOM_XREF_PTR(xref)->string);
123 return (Gedcom_ctxt)10000;
126 Gedcom_ctxt source_start(Gedcom_elt elt, Gedcom_ctxt parent, int level,
127 char *tag, char* raw_value,
128 int tag_value, Gedcom_val parsed_value)
130 Gedcom_ctxt self = (Gedcom_ctxt)(void_ptr_to_int(parent) + 1000);
131 output(1, "Source is %s (ctxt is %ld, parent is %ld)\n",
132 GEDCOM_STRING(parsed_value), void_ptr_to_int(self),
133 void_ptr_to_int(parent));
137 void source_end(Gedcom_elt elt, Gedcom_ctxt parent, Gedcom_ctxt self,
138 Gedcom_val parsed_value)
140 output(1, "Source context %ld in parent %ld\n",
141 void_ptr_to_int(self), void_ptr_to_int(parent));
144 Gedcom_ctxt head_note_start(Gedcom_elt elt, Gedcom_ctxt parent, int level,
145 char *tag, char* raw_value,
146 int tag_value, Gedcom_val parsed_value)
148 Gedcom_ctxt self = (Gedcom_ctxt)(void_ptr_to_int(parent));
149 output(1, "Note: %s (ctxt is %ld, parent is %ld)\n",
150 GEDCOM_STRING(parsed_value), void_ptr_to_int(self),
151 void_ptr_to_int(parent));
155 void head_note_end(Gedcom_elt elt, Gedcom_ctxt parent, Gedcom_ctxt self,
156 Gedcom_val parsed_value)
158 output(1, "Complete note:\n%s\n", GEDCOM_STRING(parsed_value));
161 Gedcom_ctxt date_start(Gedcom_elt elt, Gedcom_ctxt parent, int level,
162 char *tag, char* raw_value,
163 int tag_value, Gedcom_val parsed_value)
165 struct date_value dv;
166 Gedcom_ctxt self = (Gedcom_ctxt)(void_ptr_to_int(parent) + 1000);
167 dv = GEDCOM_DATE(parsed_value);
168 output(1, "Contents of the date_value:\n");
169 output(1, " raw value: %s\n", raw_value);
170 output(1, " type: %d\n", dv.type);
171 output(1, " date1:\n");
172 output(1, " calendar type: %d\n", dv.date1.cal);
173 output(1, " day: %s\n", dv.date1.day_str);
174 output(1, " month: %s\n", dv.date1.month_str);
175 output(1, " year: %s\n", dv.date1.year_str);
176 output(1, " date type: %d\n", dv.date1.type);
177 output(1, " sdn1: %ld\n", dv.date1.sdn1);
178 output(1, " sdn2: %ld\n", dv.date1.sdn2);
179 output(1, " date2:\n");
180 output(1, " calendar type: %d\n", dv.date2.cal);
181 output(1, " day: %s\n", dv.date2.day_str);
182 output(1, " month: %s\n", dv.date2.month_str);
183 output(1, " year: %s\n", dv.date2.year_str);
184 output(1, " date type: %d\n", dv.date2.type);
185 output(1, " sdn1: %ld\n", dv.date2.sdn1);
186 output(1, " sdn2: %ld\n", dv.date2.sdn2);
187 output(1, " phrase: %s\n", dv.phrase);
191 Gedcom_ctxt age_start(Gedcom_elt elt, Gedcom_ctxt parent, int level,
192 char *tag, char *raw_value,
193 int tag_value, Gedcom_val parsed_value)
195 struct age_value age;
196 Gedcom_ctxt self = (Gedcom_ctxt)(void_ptr_to_int(parent) + 1000);
197 age = GEDCOM_AGE(parsed_value);
198 output(1, "Contents of the age_value:\n");
199 output(1, " raw value: %s\n", raw_value);
200 output(1, " type: %d\n", age.type);
201 output(1, " modifier: %d\n", age.mod);
202 output(1, " years: %d\n", age.years);
203 output(1, " months: %d\n", age.months);
204 output(1, " days: %d\n", age.days);
205 output(1, " phrase: %s\n", age.phrase);
209 void default_cb(Gedcom_elt elt, Gedcom_ctxt ctxt, int level, char *tag,
210 char *raw_value, int tag_value)
212 char *converted = NULL;
215 converted = convert_utf8_to_locale(raw_value, &conv_fails);
216 output(0, "== %d %s (%d) %s (ctxt is %ld, conversion failures: %d)\n",
217 level, tag, tag_value, converted, void_ptr_to_int(ctxt), conv_fails);
218 total_conv_fails += conv_fails;
221 void subscribe_callbacks()
223 gedcom_subscribe_to_record(REC_HEAD, header_start, header_end);
224 gedcom_subscribe_to_record(REC_FAM, family_start, family_end);
225 gedcom_subscribe_to_record(REC_INDI, rec_start, NULL);
226 gedcom_subscribe_to_record(REC_OBJE, rec_start, NULL);
227 gedcom_subscribe_to_record(REC_NOTE, note_start, NULL);
228 gedcom_subscribe_to_record(REC_REPO, rec_start, NULL);
229 gedcom_subscribe_to_record(REC_SOUR, rec_start, NULL);
230 gedcom_subscribe_to_record(REC_SUBN, rec_start, NULL);
231 gedcom_subscribe_to_record(REC_SUBM, submit_start, NULL);
232 gedcom_subscribe_to_record(REC_USER, rec_start, NULL);
233 gedcom_subscribe_to_element(ELT_HEAD_SOUR, source_start, source_end);
234 gedcom_subscribe_to_element(ELT_HEAD_NOTE, head_note_start, head_note_end);
235 gedcom_subscribe_to_element(ELT_SOUR_DATA_EVEN_DATE,
237 gedcom_subscribe_to_element(ELT_SUB_EVT_DATE, date_start, NULL);
238 gedcom_subscribe_to_element(ELT_SUB_FAM_EVT_AGE, age_start, NULL);
241 void gedcom_message_handler(Gedcom_msg_type type, char *msg)
244 output(1, "MESSAGE: ");
245 else if (type == WARNING)
246 output(1, "WARNING: ");
247 else if (type == ERROR)
248 output(1, "ERROR: ");
249 output(1, "%s\n", msg);
252 int main(int argc, char* argv[])
254 Gedcom_err_mech mech = IMMED_FAIL;
255 int compat_enabled = 1;
260 char* outfilename = NULL;
261 char* file_name = NULL;
265 for (i=1; i<argc; i++) {
266 if (!strncmp(argv[i], "-da", 4))
268 else if (!strncmp(argv[i], "-dg", 4))
270 else if (!strncmp(argv[i], "-fi", 4))
272 else if (!strncmp(argv[i], "-fd", 4))
274 else if (!strncmp(argv[i], "-fn", 4))
275 mech = IGNORE_ERRORS;
276 else if (!strncmp(argv[i], "-nc", 4))
278 else if (!strncmp(argv[i], "-h", 3)) {
282 else if (!strncmp(argv[i], "-2", 3)) {
285 else if (!strncmp(argv[i], "-3", 3)) {
288 else if (!strncmp(argv[i], "-b", 3)) {
291 else if (!strncmp(argv[i], "-q", 3)) {
294 else if (!strncmp(argv[i], "-o", 3)) {
297 outfilename = argv[i];
300 printf ("Missing output file name\n");
305 else if (strncmp(argv[i], "-", 1)) {
310 printf ("Unrecognized option: %s\n", argv[i]);
318 printf("No file name given\n");
324 setlocale(LC_ALL, "");
325 gedcom_set_debug_level(debug_level, NULL);
326 gedcom_set_compat_handling(compat_enabled);
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");