2 Copyright (C) 2001 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
24 /* WARNING: THIS PARSER RELIES HEAVILY ON SOME FEATURES OF BISON.
25 DON'T TRY TO USE IT WITH YACC, IT WON'T WORK...
28 /* Design of the parser:
30 In general, a GEDCOM file contains records, each consisting of a line
31 (which we'll call a section), hierarchically containing other lines
32 (subsections of the section).
34 This means that in general we have:
36 A 'record' is a 'section' (sect) containing 'subsections' (subs)
37 Each 'subsection' (sub) is again a specific 'section' (sect)
39 In parser notation, this means:
43 sect : <some prefix> subs <some suffix>
45 subs : <empty> | subs sub
47 sub : sect_a | sect_b | ...
49 This pattern is repeated throughout the parser for the different types of
53 Cardinality of the subsections:
54 -------------------------------
55 Note that in the above, the order of the subsections is of no importance.
56 Indeed, this is the case in the GEDCOM grammar. However, this also makes
57 it difficult to check whether there are not too many subsections of a
58 specific type, or whether a mandatory subsection is indeed there.
60 Suppose there is a section A that can contain 0 or 1 B section and
63 This can be expressed in parser notation as follows:
65 A : CC | BCC | CBC | CCB
67 So, cardinality is indeed expressable. However, as the number of subsection
68 types and the limits grow bigger (and even theoretically limitless), listing
69 all possible permutations becomes quickly unfeasible.
71 Much simpler is to say:
74 subs : <empty> | subs sub
77 and then check the cardinality in the semantic actions, which is the
78 solution chosen in the parser below, using the following macros:
81 Make a new context for the <parent> tag to count child tags in
83 - OCCUR2(<child>, <min>, <max>)
84 Express that the <child> tag should occur at least <min> times and
85 at most <max> tags within its parent
87 What this actually does is the following. It increments the counter
88 for that tag and then checks whether the maximum is exceeded. If so,
89 then a parser error is produced. The minimum is not actually checked
90 by this macro, but it makes the statements more declarative.
92 - OCCUR1(<child>, <min>)
93 Express that the <child> tag should occur at least <min> times within
94 its parent (no upper limit)
96 Actually, this only increments the counter for the tag, but it looks
97 very like the previous macro.
99 If the minimum is 0, it is not necessary to express this constraint.
101 - CHECKn(<child1>, ..., <childn>)
102 This closes the context for the parent tag and checks whether the
103 given <child> tags did effectively occur within the parent (i.e.
104 these are the tags that were mandatory).
106 Since the <min> values above are always 0 or 1 in GEDCOM, this is
107 sufficient. All sub-tags that declare a minimum of 1 in the OCCUR
108 macros should be listed in this macro here.
110 The macros CHECK0 to CHECK4 are defined like this (the first one
111 has no arguments and is only used to close the parent context; note
112 that this is necessary for correct functioning).
116 Only sections that have subsections need to use these macros. This can
117 be done like this (the OPEN and CHECK macros are used as mid-rule
118 actions around the subsections):
120 head_sect : OPEN DELIM TAG_HEAD
124 CLOSE { <semantic actions> }
130 head_sub : head_sour_sect { OCCUR2(SOUR, 1, 1) }
131 | head_dest_sect { OCCUR2(DEST, 0, 1) }
132 | head_date_sect { OCCUR2(DATE, 0, 1) }
138 - The syntax analysis doesn't handle the contents of the line values;
139 this is done in the semantic analysis.
144 #include "gedcom_internal.h"
145 #include "multilex.h"
146 #include "encoding.h"
147 #include "interface.h"
151 int compat_enabled = 1;
152 int gedcom_high_level_debug = 0;
153 int compatibility = 0;
154 Gedcom_err_mech error_mechanism = IMMED_FAIL;
156 char line_item_buf[MAXGEDCLINELEN * UTF_FACTOR + 1];
157 char *line_item_buf_ptr;
163 /* These are defined at the bottom of the file */
164 void push_countarray();
165 void set_parenttag(char* tag);
166 char* get_parenttag();
167 void set_parentctxt(Gedcom_ctxt ctxt);
168 Gedcom_ctxt get_parentctxt();
169 void pop_countarray();
170 int count_tag(int tag);
171 int check_occurrence(int tag);
172 void set_compatibility(char* program);
173 int compat_mode(int flags);
175 #define CLEAR_BUFFER(BUF) \
176 memset(BUF, 0, sizeof(BUF));
178 #define HANDLE_ERROR \
179 { if (error_mechanism == IMMED_FAIL) { \
182 else if (error_mechanism == DEFER_FAIL) { \
185 else if (error_mechanism == IGNORE_ERRORS) { \
189 #define START(PARENTTAG,PARENTCTXT) \
191 set_parenttag(#PARENTTAG); \
192 set_parentctxt(PARENTCTXT); \
198 { if (!check_occurrence(TAG_##TAG)) { \
199 char* parenttag = get_parenttag(); \
200 gedcom_error("The tag '%s' is mandatory within '%s', but missing", \
206 { pop_countarray(); \
210 #define CHECK1(TAG1) { CHK(TAG1); POP; }
211 #define CHECK2(TAG1,TAG2) \
212 { CHK(TAG1); CHK(TAG2); POP; }
213 #define CHECK3(TAG1,TAG2,TAG3) \
214 { CHK(TAG1); CHK(TAG2); CHK(TAG3); POP; }
215 #define CHECK4(TAG1,TAG2,TAG3,TAG4) \
216 { CHK(TAG1); CHK(TAG2); CHK(TAG3); CHK(TAG4); POP; }
217 #define OCCUR1(CHILDTAG, MIN) { count_tag(TAG_##CHILDTAG); }
218 #define OCCUR2(CHILDTAG, MIN, MAX) \
219 { int num = count_tag(TAG_##CHILDTAG); \
221 char* parenttag = get_parenttag(); \
222 gedcom_error("The tag '%s' can maximally occur %d " \
223 "time(s) within '%s'", \
224 #CHILDTAG, MAX, parenttag); \
228 #define INVALID_TAG(CHILDTAG) \
229 { char* parenttag = get_parenttag(); \
230 gedcom_error("The tag '%s' is not a valid tag within '%s'", \
231 CHILDTAG, parenttag); \
234 #define INVALID_TOP_TAG(CHILDTAG) \
235 { gedcom_error("The tag '%s' is not a valid top-level tag", \
251 %token <string> BADTOKEN
253 %token <string> CLOSE
254 %token <string> ESCAPE
255 %token <string> DELIM
256 %token <string> ANYCHAR
257 %token <string> POINTER
258 %token <string> USERTAG
259 %token <string> TAG_ABBR
260 %token <string> TAG_ADDR
261 %token <string> TAG_ADR1
262 %token <string> TAG_ADR2
263 %token <string> TAG_ADOP
264 %token <string> TAG_AFN
265 %token <string> TAG_AGE
266 %token <string> TAG_AGNC
267 %token <string> TAG_ALIA
268 %token <string> TAG_ANCE
269 %token <string> TAG_ANCI
270 %token <string> TAG_ANUL
271 %token <string> TAG_ASSO
272 %token <string> TAG_AUTH
273 %token <string> TAG_BAPL
274 %token <string> TAG_BAPM
275 %token <string> TAG_BARM
276 %token <string> TAG_BASM
277 %token <string> TAG_BIRT
278 %token <string> TAG_BLES
279 %token <string> TAG_BLOB
280 %token <string> TAG_BURI
281 %token <string> TAG_CALN
282 %token <string> TAG_CAST
283 %token <string> TAG_CAUS
284 %token <string> TAG_CENS
285 %token <string> TAG_CHAN
286 %token <string> TAG_CHAR
287 %token <string> TAG_CHIL
288 %token <string> TAG_CHR
289 %token <string> TAG_CHRA
290 %token <string> TAG_CITY
291 %token <string> TAG_CONC
292 %token <string> TAG_CONF
293 %token <string> TAG_CONL
294 %token <string> TAG_CONT
295 %token <string> TAG_COPR
296 %token <string> TAG_CORP
297 %token <string> TAG_CREM
298 %token <string> TAG_CTRY
299 %token <string> TAG_DATA
300 %token <string> TAG_DATE
301 %token <string> TAG_DEAT
302 %token <string> TAG_DESC
303 %token <string> TAG_DESI
304 %token <string> TAG_DEST
305 %token <string> TAG_DIV
306 %token <string> TAG_DIVF
307 %token <string> TAG_DSCR
308 %token <string> TAG_EDUC
309 %token <string> TAG_EMIG
310 %token <string> TAG_ENDL
311 %token <string> TAG_ENGA
312 %token <string> TAG_EVEN
313 %token <string> TAG_FAM
314 %token <string> TAG_FAMC
315 %token <string> TAG_FAMF
316 %token <string> TAG_FAMS
317 %token <string> TAG_FCOM
318 %token <string> TAG_FILE
319 %token <string> TAG_FORM
320 %token <string> TAG_GEDC
321 %token <string> TAG_GIVN
322 %token <string> TAG_GRAD
323 %token <string> TAG_HEAD
324 %token <string> TAG_HUSB
325 %token <string> TAG_IDNO
326 %token <string> TAG_IMMI
327 %token <string> TAG_INDI
328 %token <string> TAG_LANG
329 %token <string> TAG_LEGA
330 %token <string> TAG_MARB
331 %token <string> TAG_MARC
332 %token <string> TAG_MARL
333 %token <string> TAG_MARR
334 %token <string> TAG_MARS
335 %token <string> TAG_MEDI
336 %token <string> TAG_NAME
337 %token <string> TAG_NATI
338 %token <string> TAG_NATU
339 %token <string> TAG_NCHI
340 %token <string> TAG_NICK
341 %token <string> TAG_NMR
342 %token <string> TAG_NOTE
343 %token <string> TAG_NPFX
344 %token <string> TAG_NSFX
345 %token <string> TAG_OBJE
346 %token <string> TAG_OCCU
347 %token <string> TAG_ORDI
348 %token <string> TAG_ORDN
349 %token <string> TAG_PAGE
350 %token <string> TAG_PEDI
351 %token <string> TAG_PHON
352 %token <string> TAG_PLAC
353 %token <string> TAG_POST
354 %token <string> TAG_PROB
355 %token <string> TAG_PROP
356 %token <string> TAG_PUBL
357 %token <string> TAG_QUAY
358 %token <string> TAG_REFN
359 %token <string> TAG_RELA
360 %token <string> TAG_RELI
361 %token <string> TAG_REPO
362 %token <string> TAG_RESI
363 %token <string> TAG_RESN
364 %token <string> TAG_RETI
365 %token <string> TAG_RFN
366 %token <string> TAG_RIN
367 %token <string> TAG_ROLE
368 %token <string> TAG_SEX
369 %token <string> TAG_SLGC
370 %token <string> TAG_SLGS
371 %token <string> TAG_SOUR
372 %token <string> TAG_SPFX
373 %token <string> TAG_SSN
374 %token <string> TAG_STAE
375 %token <string> TAG_STAT
376 %token <string> TAG_SUBM
377 %token <string> TAG_SUBN
378 %token <string> TAG_SURN
379 %token <string> TAG_TEMP
380 %token <string> TAG_TEXT
381 %token <string> TAG_TIME
382 %token <string> TAG_TITL
383 %token <string> TAG_TRLR
384 %token <string> TAG_TYPE
385 %token <string> TAG_VERS
386 %token <string> TAG_WIFE
387 %token <string> TAG_WILL
389 %type <string> anystdtag
390 %type <string> anytoptag
391 %type <string> line_item
392 %type <string> line_value
393 %type <string> mand_line_item
394 %type <string> mand_pointer
395 %type <string> note_line_item
396 %type <string> anychar
397 %type <string> opt_xref
398 %type <string> opt_value
399 %type <ctxt> head_sect
403 file : head_sect records trlr_sect
404 { if (fail == 1) YYABORT; }
407 records : /* empty */
422 /*********************************************************************/
424 /*********************************************************************/
425 head_sect : OPEN DELIM TAG_HEAD
426 { $<ctxt>$ = start_record(REC_HEAD, $1, NULL, $3);
427 START(HEAD, $<ctxt>$) }
429 { if (compat_mode(C_FTREE))
430 CHECK3(SOUR, GEDC, CHAR)
432 CHECK4(SOUR, SUBM, GEDC, CHAR)
435 { end_record(REC_HEAD, $<ctxt>4); }
438 head_subs : /* empty */
442 head_sub : head_sour_sect { OCCUR2(SOUR, 1, 1) }
443 | head_dest_sect { OCCUR2(DEST, 0, 1) }
444 | head_date_sect { OCCUR2(DATE, 0, 1) }
445 | head_subm_sect { OCCUR2(SUBM, 1, 1) }
446 | head_subn_sect { OCCUR2(SUBN, 0, 1) }
447 | head_file_sect { OCCUR2(FILE, 0, 1) }
448 | head_copr_sect { OCCUR2(COPR, 0, 1) }
449 | head_gedc_sect { OCCUR2(GEDC, 1, 1) }
450 | head_char_sect { OCCUR2(CHAR, 1, 1) }
451 | head_lang_sect { OCCUR2(LANG, 0, 1) }
452 | head_plac_sect { OCCUR2(PLAC, 0, 1) }
453 | head_note_sect { OCCUR2(NOTE, 0, 1) }
458 head_sour_sect : OPEN DELIM TAG_SOUR mand_line_item
459 { set_compatibility($4);
460 $<ctxt>$ = start_element(ELT_HEAD_SOUR, PARENT,
462 START(SOUR, $<ctxt>$)
467 { end_element(ELT_HEAD_SOUR, PARENT, $<ctxt>5, NULL); }
470 head_sour_subs : /* empty */
471 | head_sour_subs head_sour_sub
474 head_sour_sub : head_sour_vers_sect { OCCUR2(VERS, 0, 1) }
475 | head_sour_name_sect { OCCUR2(NAME, 0, 1) }
476 | head_sour_corp_sect { OCCUR2(CORP, 0, 1) }
477 | head_sour_data_sect { OCCUR2(DATA, 0, 1) }
481 head_sour_vers_sect : OPEN DELIM TAG_VERS mand_line_item
482 { $<ctxt>$ = start_element(ELT_HEAD_SOUR_VERS, PARENT,
484 START(VERS, $<ctxt>$)
489 { end_element(ELT_HEAD_SOUR_VERS,
490 PARENT, $<ctxt>5, NULL);
493 head_sour_name_sect : OPEN DELIM TAG_NAME mand_line_item
494 { $<ctxt>$ = start_element(ELT_HEAD_SOUR_NAME, PARENT,
496 START(NAME, $<ctxt>$)
501 { end_element(ELT_HEAD_SOUR_NAME,
502 PARENT, $<ctxt>5, NULL);
505 head_sour_corp_sect : OPEN DELIM TAG_CORP mand_line_item
506 { $<ctxt>$ = start_element(ELT_HEAD_SOUR_CORP, PARENT,
508 START(CORP, $<ctxt>$)
513 { end_element(ELT_HEAD_SOUR_CORP,
514 PARENT, $<ctxt>5, NULL);
518 head_sour_corp_subs : /* empty */
519 | head_sour_corp_subs head_sour_corp_sub
522 head_sour_corp_sub : addr_struc_sub /* 0:1 */
526 head_sour_data_sect : OPEN DELIM TAG_DATA mand_line_item
527 { $<ctxt>$ = start_element(ELT_HEAD_SOUR_DATA, PARENT,
529 START(DATA, $<ctxt>$)
534 { end_element(ELT_HEAD_SOUR_DATA,
535 PARENT, $<ctxt>5, NULL);
539 head_sour_data_subs : /* empty */
540 | head_sour_data_subs head_sour_data_sub
543 head_sour_data_sub : head_sour_data_date_sect { OCCUR2(DATE, 0, 1) }
544 | head_sour_data_copr_sect { OCCUR2(COPR, 0, 1) }
548 head_sour_data_date_sect : OPEN DELIM TAG_DATE mand_line_item
549 { $<ctxt>$ = start_element(ELT_HEAD_SOUR_DATA_DATE,
550 PARENT, $1, $3, $4, $4);
551 START(DATE, $<ctxt>$)
556 { end_element(ELT_HEAD_SOUR_DATA_DATE,
557 PARENT, $<ctxt>5, NULL);
560 head_sour_data_copr_sect : OPEN DELIM TAG_COPR mand_line_item
561 { $<ctxt>$ = start_element(ELT_HEAD_SOUR_DATA_COPR,
562 PARENT, $1, $3, $4, $4);
563 START(COPR, $<ctxt>$)
568 { end_element(ELT_HEAD_SOUR_DATA_COPR,
569 PARENT, $<ctxt>5, NULL);
574 head_dest_sect : OPEN DELIM TAG_DEST mand_line_item
575 { $<ctxt>$ = start_element(ELT_HEAD_DEST,
576 PARENT, $1, $3, $4, $4);
577 START(DEST, $<ctxt>$)
582 { end_element(ELT_HEAD_DEST,
583 PARENT, $<ctxt>5, NULL);
588 head_date_sect : OPEN DELIM TAG_DATE mand_line_item
589 { $<ctxt>$ = start_element(ELT_HEAD_DATE,
590 PARENT, $1, $3, $4, $4);
591 START(DATE, $<ctxt>$)
596 { end_element(ELT_HEAD_DATE,
597 PARENT, $<ctxt>5, NULL);
601 head_date_subs : /* empty */
602 | head_date_subs head_date_sub
605 head_date_sub : head_date_time_sect { OCCUR2(TIME, 0, 1) }
609 head_date_time_sect : OPEN DELIM TAG_TIME mand_line_item
610 { $<ctxt>$ = start_element(ELT_HEAD_DATE_TIME,
611 PARENT, $1, $3, $4, $4);
612 START(TIME, $<ctxt>$)
617 { end_element(ELT_HEAD_DATE_TIME,
618 PARENT, $<ctxt>5, NULL);
623 head_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
624 { $<ctxt>$ = start_element(ELT_HEAD_SUBM,
625 PARENT, $1, $3, $4, $4);
626 START(SUBM, $<ctxt>$)
631 { end_element(ELT_HEAD_SUBM,
632 PARENT, $<ctxt>5, NULL);
636 head_subn_sect : OPEN DELIM TAG_SUBN mand_pointer
637 { $<ctxt>$ = start_element(ELT_HEAD_SUBN,
638 PARENT, $1, $3, $4, $4);
639 START(SUBN, $<ctxt>$)
644 { end_element(ELT_HEAD_SUBN,
645 PARENT, $<ctxt>5, NULL);
649 head_file_sect : OPEN DELIM TAG_FILE mand_line_item
650 { $<ctxt>$ = start_element(ELT_HEAD_FILE,
651 PARENT, $1, $3, $4, $4);
652 START(FILE, $<ctxt>$)
657 { end_element(ELT_HEAD_FILE, PARENT, $<ctxt>5, NULL);
661 head_copr_sect : OPEN DELIM TAG_COPR mand_line_item
662 { $<ctxt>$ = start_element(ELT_HEAD_COPR,
663 PARENT, $1, $3, $4, $4);
664 START(COPR, $<ctxt>$)
669 { end_element(ELT_HEAD_COPR, PARENT, $<ctxt>5, NULL);
673 head_gedc_sect : OPEN DELIM TAG_GEDC
674 { $<ctxt>$ = start_element(ELT_HEAD_GEDC,
675 PARENT, $1, $3, NULL, NULL);
676 START(GEDC, $<ctxt>$)
679 { CHECK2(VERS, FORM) }
681 { end_element(ELT_HEAD_GEDC, PARENT, $<ctxt>4, NULL);
685 head_gedc_subs : /* empty */
686 | head_gedc_subs head_gedc_sub
689 head_gedc_sub : head_gedc_vers_sect { OCCUR2(VERS, 1, 1) }
690 | head_gedc_form_sect { OCCUR2(FORM, 1, 1) }
693 head_gedc_vers_sect : OPEN DELIM TAG_VERS mand_line_item
694 { $<ctxt>$ = start_element(ELT_HEAD_GEDC_VERS,
695 PARENT, $1, $3, $4, $4);
696 START(VERS, $<ctxt>$)
701 { end_element(ELT_HEAD_GEDC_VERS,
702 PARENT, $<ctxt>5, NULL);
705 head_gedc_form_sect : OPEN DELIM TAG_FORM mand_line_item
706 { $<ctxt>$ = start_element(ELT_HEAD_GEDC_FORM,
707 PARENT, $1, $3, $4, $4);
708 START(FORM, $<ctxt>$)
713 { end_element(ELT_HEAD_GEDC_FORM,
714 PARENT, $<ctxt>5, NULL);
719 head_char_sect : OPEN DELIM TAG_CHAR mand_line_item
720 { if (open_conv_to_internal($4) == 0) YYERROR;
721 $<ctxt>$ = start_element(ELT_HEAD_CHAR,
722 PARENT, $1, $3, $4, $4);
723 START(CHAR, $<ctxt>$)
728 { end_element(ELT_HEAD_CHAR, PARENT, $<ctxt>5, NULL);
732 head_char_subs : /* empty */
733 | head_char_subs head_char_sub
736 head_char_sub : head_char_vers_sect { OCCUR2(VERS, 0, 1) }
739 head_char_vers_sect : OPEN DELIM TAG_VERS mand_line_item
740 { $<ctxt>$ = start_element(ELT_HEAD_CHAR_VERS,
741 PARENT, $1, $3, $4, $4);
742 START(VERS, $<ctxt>$)
747 { end_element(ELT_HEAD_CHAR_VERS,
748 PARENT, $<ctxt>5, NULL);
753 head_lang_sect : OPEN DELIM TAG_LANG mand_line_item
754 { $<ctxt>$ = start_element(ELT_HEAD_LANG,
755 PARENT, $1, $3, $4, $4);
756 START(LANG, $<ctxt>$)
761 { end_element(ELT_HEAD_LANG, PARENT, $<ctxt>5, NULL);
765 head_plac_sect : OPEN DELIM TAG_PLAC
766 { $<ctxt>$ = start_element(ELT_HEAD_PLAC,
767 PARENT, $1, $3, NULL, NULL);
768 START(PLAC, $<ctxt>$)
773 { end_element(ELT_HEAD_PLAC, PARENT, $<ctxt>4, NULL);
777 head_plac_subs : /* empty */
778 | head_plac_subs head_plac_sub
781 head_plac_sub : head_plac_form_sect { OCCUR2(FORM, 1, 1) }
784 head_plac_form_sect : OPEN DELIM TAG_FORM mand_line_item
785 { $<ctxt>$ = start_element(ELT_HEAD_PLAC_FORM,
786 PARENT, $1, $3, $4, $4);
787 START(FORM, $<ctxt>$)
792 { end_element(ELT_HEAD_PLAC_FORM,
793 PARENT, $<ctxt>5, NULL);
798 head_note_sect : OPEN DELIM TAG_NOTE mand_line_item
799 { $<ctxt>$ = start_element(ELT_HEAD_NOTE,
800 PARENT, $1, $3, $4, $4);
801 START(NOTE, $<ctxt>$)
806 { end_element(ELT_HEAD_NOTE, PARENT, $<ctxt>5, NULL);
810 head_note_subs : /* empty */
811 | head_note_subs head_note_sub
814 head_note_sub : continuation_sub /* 0:M */
818 /*********************************************************************/
820 /*********************************************************************/
821 /* Don't need callbacks here, there is no information... */
822 trlr_sect : OPEN DELIM TAG_TRLR CLOSE { }
825 /*********************************************************************/
826 /**** Family record ****/
827 /*********************************************************************/
828 fam_rec : OPEN DELIM POINTER DELIM TAG_FAM
829 { $<ctxt>$ = start_record(REC_FAM, $1, $3, $5);
830 START(FAM, $<ctxt>$) }
834 { end_record(REC_FAM, $<ctxt>6); }
837 fam_subs : /* empty */
841 fam_sub : fam_event_struc_sub /* 0:M */
842 | fam_husb_sect { OCCUR2(HUSB, 0, 1) }
843 | fam_wife_sect { OCCUR2(WIFE, 0, 1) }
844 | fam_chil_sect /* 0:M */
845 | fam_nchi_sect { OCCUR2(NCHI, 0, 1) }
846 | fam_subm_sect /* 0:M */
847 | lds_spouse_seal_sub /* 0:M */
848 | source_cit_sub /* 0:M */
849 | multim_link_sub /* 0:M */
850 | note_struc_sub /* 0:M */
851 | ident_struc_sub /* 0:1 */
852 | change_date_sub /* 0:1 */
857 fam_husb_sect : OPEN DELIM TAG_HUSB mand_pointer
858 { START(HUSB, NULL) } no_std_subs { CHECK0 } CLOSE
863 fam_wife_sect : OPEN DELIM TAG_WIFE mand_pointer
864 { START(WIFE, NULL) } no_std_subs { CHECK0 } CLOSE
869 fam_chil_sect : OPEN DELIM TAG_CHIL mand_pointer
870 { START(CHIL, NULL) } no_std_subs { CHECK0 } CLOSE
875 fam_nchi_sect : OPEN DELIM TAG_NCHI mand_line_item
876 { START(NCHI, NULL) } no_std_subs { CHECK0 } CLOSE
881 fam_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
882 { START(SUBM, NULL) } no_std_subs { CHECK0 } CLOSE
886 /*********************************************************************/
887 /**** Individual record ****/
888 /*********************************************************************/
889 indiv_rec : OPEN DELIM POINTER DELIM TAG_INDI
890 { $<ctxt>$ = start_record(REC_INDI, $1, $3, $5);
891 START(INDI, $<ctxt>$) }
895 { end_record(REC_INDI, $<ctxt>6); }
898 indi_subs : /* empty */
902 indi_sub : indi_resn_sect { OCCUR2(RESN, 0, 1) }
903 | pers_name_struc_sub /* 0:M */
904 | indi_sex_sect { OCCUR2(SEX, 0, 1) }
905 | indiv_even_struc_sub /* 0:M */
906 | indiv_attr_struc_sub /* 0:M */
907 | lds_indiv_ord_sub /* 0:M */
908 | chi_fam_link_sub /* 0:M */
909 | spou_fam_link_sub /* 0:M */
910 | indi_subm_sect /* 0:M */
911 | assoc_struc_sub /* 0:M */
912 | indi_alia_sect /* 0:M */
913 | indi_anci_sect /* 0:M */
914 | indi_desi_sect /* 0:M */
915 | source_cit_sub /* 0:M */
916 | multim_link_sub /* 0:M */
917 | note_struc_sub /* 0:M */
918 | indi_rfn_sect { OCCUR2(RFN, 0, 1) }
919 | indi_afn_sect /* 0:M */
920 | ident_struc_sub /* 0:1 */
921 | change_date_sub /* 0:1 */
922 | ftree_addr_sect { if (!compat_mode(C_FTREE))
929 indi_resn_sect : OPEN DELIM TAG_RESN mand_line_item
930 { START(RESN, NULL) } no_std_subs { CHECK0 } CLOSE { }
934 indi_sex_sect : OPEN DELIM TAG_SEX mand_line_item
935 { START(SEX, NULL) } no_std_subs { CHECK0 } CLOSE { }
939 indi_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
940 { START(SUBM, NULL) } no_std_subs { CHECK0 } CLOSE { }
944 indi_alia_sect : OPEN DELIM TAG_ALIA mand_pointer
945 { START(ALIA, NULL) } no_std_subs { CHECK0 } CLOSE { }
949 indi_anci_sect : OPEN DELIM TAG_ANCI mand_pointer
950 { START(ANCI, NULL) } no_std_subs { CHECK0 } CLOSE { }
954 indi_desi_sect : OPEN DELIM TAG_DESI mand_pointer
955 { START(DESI, NULL) } no_std_subs { CHECK0 } CLOSE { }
959 indi_rfn_sect : OPEN DELIM TAG_RFN mand_line_item
960 { START(RFN, NULL) } no_std_subs { CHECK0 } CLOSE { }
964 indi_afn_sect : OPEN DELIM TAG_AFN mand_line_item
965 { START(AFN, NULL) } no_std_subs { CHECK0 } CLOSE { }
968 /* INDI.ADDR (Only for 'ftree' compatibility) */
969 ftree_addr_sect : OPEN DELIM TAG_ADDR opt_line_item
970 { START(ADDR, NULL) } no_std_subs { CHECK0 } CLOSE { }
972 /*********************************************************************/
973 /**** Multimedia record ****/
974 /*********************************************************************/
975 multim_rec : OPEN DELIM POINTER DELIM TAG_OBJE
976 { $<ctxt>$ = start_record(REC_OBJE, $1, $3, $5);
977 START(OBJE, $<ctxt>$) }
979 { CHECK2(FORM, BLOB) }
981 { end_record(REC_OBJE, $<ctxt>6); }
984 obje_subs : /* empty */
988 obje_sub : obje_form_sect { OCCUR2(FORM, 1, 1) }
989 | obje_titl_sect { OCCUR2(TITL, 0, 1) }
990 | note_struc_sub /* 0:M */
991 | obje_blob_sect { OCCUR2(BLOB, 1, 1) }
992 | obje_obje_sect { OCCUR2(OBJE, 0, 1) }
993 | ident_struc_sub /* 0:1 */
994 | change_date_sub /* 0:1 */
999 obje_form_sect : OPEN DELIM TAG_FORM mand_line_item
1000 { START(FORM, NULL) } no_std_subs { CHECK0 } CLOSE { }
1004 obje_titl_sect : OPEN DELIM TAG_TITL mand_line_item
1005 { START(TITL, NULL) } no_std_subs { CHECK0 } CLOSE { }
1009 obje_blob_sect : OPEN DELIM TAG_BLOB
1010 { START(BLOB, NULL) }
1016 obje_blob_subs : /* empty */
1017 | obje_blob_subs obje_blob_sub
1020 obje_blob_sub : obje_blob_cont_sect { OCCUR1(CONT, 1) }
1024 obje_blob_cont_sect : OPEN DELIM TAG_CONT mand_line_item
1025 { START(CONT, NULL) } no_std_subs { CHECK0 } CLOSE { }
1029 obje_obje_sect : OPEN DELIM TAG_OBJE mand_pointer
1030 { START(OBJE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1033 /*********************************************************************/
1034 /**** Note record ****/
1035 /*********************************************************************/
1036 note_rec : OPEN DELIM POINTER DELIM TAG_NOTE note_line_item
1037 { $<ctxt>$ = start_record(REC_NOTE, $1, $3, $5);
1038 START(NOTE, $<ctxt>$) }
1042 { end_record(REC_NOTE, $<ctxt>6); }
1045 note_line_item : /* empty */
1046 { if (!compat_mode(C_FTREE)) {
1047 gedcom_error("Missing value"); YYERROR;
1051 { gedcom_debug_print("==Val: %s==\n", $2);
1055 note_subs : /* empty */
1056 | note_subs note_sub
1059 note_sub : continuation_sub /* 0:M */
1060 | source_cit_sub /* 0:M */
1061 | ident_struc_sub /* 0:1 */
1062 | change_date_sub /* 0:1 */
1066 /*********************************************************************/
1067 /**** Repository record ****/
1068 /*********************************************************************/
1069 repos_rec : OPEN DELIM POINTER DELIM TAG_REPO
1070 { $<ctxt>$ = start_record(REC_REPO, $1, $3, $5);
1071 START(REPO, $<ctxt>$) }
1075 { end_record(REC_REPO, $<ctxt>6); }
1078 repo_subs : /* empty */
1079 | repo_subs repo_sub
1082 repo_sub : repo_name_sect { OCCUR2(NAME, 0, 1) }
1083 | addr_struc_sub /* 0:1 */
1084 | note_struc_sub /* 0:M */
1085 | ident_struc_sub /* 0:1 */
1086 | change_date_sub /* 0:1 */
1091 repo_name_sect : OPEN DELIM TAG_NAME mand_line_item
1092 { START(NAME, NULL) } no_std_subs { CHECK0 } CLOSE {}
1095 /*********************************************************************/
1096 /**** Source record ****/
1097 /*********************************************************************/
1098 source_rec : OPEN DELIM POINTER DELIM TAG_SOUR
1099 { $<ctxt>$ = start_record(REC_SOUR, $1, $3, $5);
1100 START(SOUR, $<ctxt>$) }
1104 { end_record(REC_SOUR, $<ctxt>6); }
1107 sour_subs : /* empty */
1108 | sour_subs sour_sub
1111 sour_sub : sour_data_sect { OCCUR2(DATA, 0, 1) }
1112 | sour_auth_sect { OCCUR2(AUTH, 0, 1) }
1113 | sour_titl_sect { OCCUR2(TITL, 0, 1) }
1114 | sour_abbr_sect { OCCUR2(ABBR, 0, 1) }
1115 | sour_publ_sect { OCCUR2(PUBL, 0, 1) }
1116 | sour_text_sect { OCCUR2(TEXT, 0, 1) }
1117 | source_repos_cit_sub /* 0:1 */
1118 | multim_link_sub /* 0:M */
1119 | note_struc_sub /* 0:M */
1120 | ident_struc_sub /* 0:1 */
1121 | change_date_sub /* 0:1 */
1126 sour_data_sect : OPEN DELIM TAG_DATA
1127 { START(DATA, NULL) }
1133 sour_data_subs : /* empty */
1134 | sour_data_subs sour_data_sub
1137 sour_data_sub : sour_data_even_sect /* 0:M */
1138 | sour_data_agnc_sect { OCCUR2(AGNC, 0, 1) }
1139 | note_struc_sub /* 0:M */
1143 sour_data_even_sect : OPEN DELIM TAG_EVEN mand_line_item
1144 { START(EVEN, NULL) }
1150 sour_data_even_subs : /* empty */
1151 | sour_data_even_subs sour_data_even_sub
1154 sour_data_even_sub : sour_data_even_date_sect { OCCUR2(DATE, 0, 1) }
1155 | sour_data_even_plac_sect { OCCUR2(PLAC, 0, 1) }
1159 sour_data_even_date_sect : OPEN DELIM TAG_DATE mand_line_item
1160 { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1163 sour_data_even_plac_sect : OPEN DELIM TAG_PLAC mand_line_item
1164 { START(PLAC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1167 sour_data_agnc_sect : OPEN DELIM TAG_AGNC mand_line_item
1168 { START(AGNC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1172 sour_auth_sect : OPEN DELIM TAG_AUTH mand_line_item
1173 { START(AUTH, NULL) }
1179 sour_auth_subs : /* empty */
1180 | sour_auth_subs sour_auth_sub
1183 sour_auth_sub : continuation_sub /* 0:M */
1188 sour_titl_sect : OPEN DELIM TAG_TITL mand_line_item
1189 { START(TITL, NULL) }
1195 sour_titl_subs : /* empty */
1196 | sour_titl_subs sour_titl_sub
1199 sour_titl_sub : continuation_sub /* 0:M */
1204 sour_abbr_sect : OPEN DELIM TAG_ABBR mand_line_item
1205 { START(ABBR, NULL) } no_std_subs { CHECK0 } CLOSE { }
1209 sour_publ_sect : OPEN DELIM TAG_PUBL mand_line_item
1210 { START(PUBL, NULL) }
1216 sour_publ_subs : /* empty */
1217 | sour_publ_subs sour_publ_sub
1220 sour_publ_sub : continuation_sub /* 0:M */
1225 sour_text_sect : OPEN DELIM TAG_TEXT mand_line_item
1226 { START(TEXT, NULL) }
1232 sour_text_subs : /* empty */
1233 | sour_text_subs sour_text_sub
1236 sour_text_sub : continuation_sub /* 0:M */
1240 /*********************************************************************/
1241 /**** Submission record ****/
1242 /*********************************************************************/
1243 submis_rec : OPEN DELIM POINTER DELIM TAG_SUBN
1244 { $<ctxt>$ = start_record(REC_SUBN, $1, $3, $5);
1245 START(SUBN, $<ctxt>$) }
1249 { end_record(REC_SUBN, $<ctxt>6); }
1252 subn_subs : /* empty */
1253 | subn_subs subn_sub
1256 subn_sub : subn_subm_sect { OCCUR2(SUBM, 0, 1) }
1257 | subn_famf_sect { OCCUR2(FAMF, 0, 1) }
1258 | subn_temp_sect { OCCUR2(TEMP, 0, 1) }
1259 | subn_ance_sect { OCCUR2(ANCE, 0, 1) }
1260 | subn_desc_sect { OCCUR2(DESC, 0, 1) }
1261 | subn_ordi_sect { OCCUR2(ORDI, 0, 1) }
1262 | subn_rin_sect { OCCUR2(RIN, 0, 1) }
1267 subn_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
1268 { START(SUBM, NULL) } no_std_subs { CHECK0 } CLOSE { }
1272 subn_famf_sect : OPEN DELIM TAG_FAMF mand_line_item
1273 { START(FAMF, NULL) } no_std_subs { CHECK0 } CLOSE { }
1277 subn_temp_sect : OPEN DELIM TAG_TEMP mand_line_item
1278 { START(TEMP, NULL) } no_std_subs { CHECK0 } CLOSE { }
1282 subn_ance_sect : OPEN DELIM TAG_ANCE mand_line_item
1283 { START(ANCE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1287 subn_desc_sect : OPEN DELIM TAG_DESC mand_line_item
1288 { START(DESC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1292 subn_ordi_sect : OPEN DELIM TAG_ORDI mand_line_item
1293 { START(ORDI, NULL) } no_std_subs { CHECK0 } CLOSE { }
1297 subn_rin_sect : OPEN DELIM TAG_RIN mand_line_item
1298 { START(RIN, NULL) } no_std_subs { CHECK0 } CLOSE { }
1301 /*********************************************************************/
1302 /**** Submitter record ****/
1303 /*********************************************************************/
1304 submit_rec : OPEN DELIM POINTER DELIM TAG_SUBM
1305 { $<ctxt>$ = start_record(REC_SUBM, $1, $3, $5);
1306 START(SUBM, $<ctxt>$) }
1310 { end_record(REC_SUBM, $<ctxt>6); }
1313 subm_subs : /* empty */
1314 | subm_subs subm_sub
1317 subm_sub : subm_name_sect { OCCUR2(NAME, 0, 1) }
1318 | addr_struc_sub /* 0:1 */
1319 | multim_link_sub /* 0:M */
1320 | subm_lang_sect { OCCUR2(LANG, 0, 3) }
1321 | subm_rfn_sect { OCCUR2(RFN, 0, 1) }
1322 | subm_rin_sect { OCCUR2(RIN, 0, 1) }
1323 | change_date_sub /* 0:1 */
1328 subm_name_sect : OPEN DELIM TAG_NAME mand_line_item
1329 { START(NAME, NULL) } no_std_subs { CHECK0 } CLOSE { }
1333 subm_lang_sect : OPEN DELIM TAG_LANG mand_line_item
1334 { START(LANG, NULL) } no_std_subs { CHECK0 } CLOSE { }
1338 subm_rfn_sect : OPEN DELIM TAG_RFN mand_line_item
1339 { START(RFN, NULL) } no_std_subs { CHECK0 } CLOSE { }
1343 subm_rin_sect : OPEN DELIM TAG_RIN mand_line_item
1344 { START(RIN, NULL) } no_std_subs { CHECK0 } CLOSE { }
1347 /*********************************************************************/
1348 /**** Substructures ****/
1349 /*********************************************************************/
1351 /* ADDRESS STRUCTURE */
1352 addr_struc_sub : addr_sect { OCCUR2(ADDR, 0, 1) }
1353 | phon_sect { OCCUR2(PHON, 0, 3) }
1356 addr_sect : OPEN DELIM TAG_ADDR mand_line_item
1357 { START(ADDR, NULL) }
1363 addr_subs : /* empty */
1364 | addr_subs addr_sub
1367 addr_sub : addr_cont_sect /* 0:M */
1368 | addr_adr1_sect { OCCUR2(ADR1, 0, 1) }
1369 | addr_adr2_sect { OCCUR2(ADR2, 0, 1) }
1370 | addr_city_sect { OCCUR2(CITY, 0, 1) }
1371 | addr_stae_sect { OCCUR2(STAE, 0, 1) }
1372 | addr_post_sect { OCCUR2(POST, 0, 1) }
1373 | addr_ctry_sect { OCCUR2(CTRY, 0, 1) }
1377 addr_cont_sect : OPEN DELIM TAG_CONT mand_line_item
1378 { START(CONT, NULL) } no_std_subs { CHECK0 } CLOSE { }
1380 addr_adr1_sect : OPEN DELIM TAG_ADR1 mand_line_item
1381 { START(ADR1, NULL) } no_std_subs { CHECK0 } CLOSE { }
1383 addr_adr2_sect : OPEN DELIM TAG_ADR2 mand_line_item
1384 { START(ADR2, NULL) } no_std_subs { CHECK0 } CLOSE { }
1386 addr_city_sect : OPEN DELIM TAG_CITY mand_line_item
1387 { START(CITY, NULL) } no_std_subs { CHECK0 } CLOSE { }
1389 addr_stae_sect : OPEN DELIM TAG_STAE mand_line_item
1390 { START(STAE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1392 addr_post_sect : OPEN DELIM TAG_POST mand_line_item
1393 { START(POST, NULL) } no_std_subs { CHECK0 } CLOSE { }
1395 addr_ctry_sect : OPEN DELIM TAG_CTRY mand_line_item
1396 { START(CTRY, NULL) } no_std_subs { CHECK0 } CLOSE { }
1399 phon_sect : OPEN DELIM TAG_PHON mand_line_item
1400 { START(PHON, NULL) } no_std_subs { CHECK0 } CLOSE { }
1403 /* ASSOCIATION STRUCTURE */
1404 assoc_struc_sub : asso_sect /* 0:M */
1407 asso_sect : OPEN DELIM TAG_ASSO mand_pointer
1408 { START(ASSO, NULL) }
1410 { CHECK2(TYPE,RELA) }
1414 asso_subs : /* empty */
1415 | asso_type_sect { OCCUR2(TYPE, 1, 1) }
1416 | asso_rela_sect { OCCUR2(RELA, 1, 1) }
1422 asso_type_sect : OPEN DELIM TAG_TYPE mand_line_item
1423 { START(TYPE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1426 asso_rela_sect : OPEN DELIM TAG_RELA mand_line_item
1427 { START(RELA, NULL) } no_std_subs { CHECK0 } CLOSE { }
1431 change_date_sub : change_date_chan_sect { OCCUR2(CHAN, 0, 1) }
1434 change_date_chan_sect : OPEN DELIM TAG_CHAN
1435 { START(CHAN, NULL) }
1436 change_date_chan_subs
1441 change_date_chan_subs : /* empty */
1442 | change_date_chan_subs change_date_chan_sub
1445 change_date_chan_sub : change_date_date_sect { OCCUR2(DATE, 1, 1) }
1450 change_date_date_sect : OPEN DELIM TAG_DATE mand_line_item
1451 { START(DATE, NULL) }
1452 change_date_date_subs
1457 change_date_date_subs : /* empty */
1458 | change_date_date_subs change_date_date_sub
1461 change_date_date_sub : change_date_date_time_sect { OCCUR2(TIME, 0, 1) }
1465 change_date_date_time_sect : OPEN DELIM TAG_TIME mand_line_item
1466 { START(TIME, NULL) } no_std_subs { CHECK0 } CLOSE { }
1469 /* CHILD TO FAMILY LINK */
1470 chi_fam_link_sub : famc_sect /* 0:M */
1473 famc_sect : OPEN DELIM TAG_FAMC mand_pointer
1474 { START(FAMC, NULL) }
1480 famc_subs : /* empty */
1481 | famc_subs famc_sub
1484 famc_sub : famc_pedi_sect /* 0:M */
1489 famc_pedi_sect : OPEN DELIM TAG_PEDI mand_line_item
1490 { START(PEDI, NULL) } no_std_subs { CHECK0 } CLOSE { }
1493 /* CONTINUATION SUBSECTIONS */
1494 continuation_sub : cont_sect /* 0:M */
1495 | conc_sect /* 0:M */
1498 cont_sect : OPEN DELIM TAG_CONT mand_line_item
1499 { START(CONT, NULL) } no_std_subs { CHECK0 } CLOSE { }
1502 conc_sect : OPEN DELIM TAG_CONC mand_line_item
1503 { START(CONC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1507 event_detail_sub : event_detail_type_sect { OCCUR2(TYPE, 0, 1) }
1508 | event_detail_date_sect { OCCUR2(DATE, 0, 1) }
1511 | event_detail_age_sect { OCCUR2(AGE, 0, 1) }
1512 | event_detail_agnc_sect { OCCUR2(AGNC, 0, 1) }
1513 | event_detail_caus_sect { OCCUR2(CAUS, 0, 1) }
1519 event_detail_type_sect : OPEN DELIM TAG_TYPE mand_line_item
1520 { START(TYPE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1522 event_detail_date_sect : OPEN DELIM TAG_DATE mand_line_item
1523 { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1525 event_detail_age_sect : OPEN DELIM TAG_AGE mand_line_item
1526 { START(AGE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1528 event_detail_agnc_sect : OPEN DELIM TAG_AGNC mand_line_item
1529 { START(AGNC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1531 event_detail_caus_sect : OPEN DELIM TAG_CAUS mand_line_item
1532 { START(CAUS, NULL) } no_std_subs { CHECK0 } CLOSE { }
1535 /* FAMILY EVENT STRUCTURE */
1536 fam_event_struc_sub : fam_event_sect
1537 | fam_gen_even_sect /* 0:M */
1540 fam_event_sect : OPEN DELIM fam_event_tag opt_value fam_event_subs
1545 fam_event_tag : TAG_ANUL { START(ANUL, NULL) }
1546 | TAG_CENS { START(CENS, NULL) }
1547 | TAG_DIV { START(DIV, NULL) }
1548 | TAG_DIVF { START(DIVF, NULL) }
1549 | TAG_ENGA { START(ENGA, NULL) }
1550 | TAG_MARR { START(MARR, NULL) }
1551 | TAG_MARB { START(MARB, NULL) }
1552 | TAG_MARC { START(MARC, NULL) }
1553 | TAG_MARL { START(MARL, NULL) }
1554 | TAG_MARS { START(MARS, NULL) }
1557 fam_event_subs : /* empty */
1558 | fam_event_subs fam_event_sub
1561 fam_event_sub : event_detail_sub
1562 | fam_even_husb_sect { OCCUR2(HUSB, 0, 1) }
1563 | fam_even_wife_sect { OCCUR2(WIFE, 0, 1) }
1567 fam_even_husb_sect : OPEN DELIM TAG_HUSB
1568 { START(HUSB, NULL) }
1574 fam_even_husb_subs : /* empty */
1575 | fam_even_husb_subs fam_even_husb_sub
1578 fam_even_husb_sub : fam_even_husb_age_sect { OCCUR2(AGE, 1, 1) }
1582 fam_even_husb_age_sect : OPEN DELIM TAG_AGE mand_line_item
1583 { START(AGE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1586 fam_even_wife_sect : OPEN DELIM TAG_WIFE
1587 { START(HUSB, NULL) }
1593 fam_gen_even_sect : OPEN DELIM TAG_EVEN
1594 { START(EVEN, NULL) }
1600 fam_gen_even_subs : /* empty */
1601 | fam_gen_even_subs fam_gen_even_sub
1604 fam_gen_even_sub : event_detail_sub
1605 | fam_even_husb_sect { OCCUR2(HUSB, 0, 1) }
1606 | fam_even_wife_sect { OCCUR2(WIFE, 0, 1) }
1610 /* IDENTIFICATION STRUCTURE */
1611 ident_struc_sub : ident_refn_sect /* 0:M */
1612 | ident_rin_sect { OCCUR2(RIN, 0, 1) }
1615 ident_refn_sect : OPEN DELIM TAG_REFN mand_line_item
1616 { START(REFN, NULL) }
1622 ident_refn_subs : /* empty */
1623 | ident_refn_subs ident_refn_sub
1626 ident_refn_sub : ident_refn_type_sect { OCCUR2(TYPE, 0, 1) }
1630 ident_refn_type_sect : OPEN DELIM TAG_TYPE mand_line_item
1631 { START(TYPE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1634 ident_rin_sect : OPEN DELIM TAG_RIN mand_line_item
1635 { START(RIN, NULL) } no_std_subs { CHECK0 } CLOSE { }
1638 /* INDIVIDUAL ATTRIBUTE STRUCTURE */
1639 indiv_attr_struc_sub : indiv_cast_sect /* 0:M */
1640 | indiv_dscr_sect /* 0:M */
1641 | indiv_educ_sect /* 0:M */
1642 | indiv_idno_sect /* 0:M */
1643 | indiv_nati_sect /* 0:M */
1644 | indiv_nchi_sect /* 0:M */
1645 | indiv_nmr_sect /* 0:M */
1646 | indiv_occu_sect /* 0:M */
1647 | indiv_prop_sect /* 0:M */
1648 | indiv_reli_sect /* 0:M */
1649 | indiv_resi_sect /* 0:M */
1650 | indiv_ssn_sect /* 0:M */
1651 | indiv_titl_sect /* 0:M */
1654 indiv_cast_sect : OPEN DELIM TAG_CAST mand_line_item
1655 { START(CAST, NULL) }
1656 indiv_attr_event_subs
1660 indiv_dscr_sect : OPEN DELIM TAG_DSCR mand_line_item
1661 { START(DSCR, NULL) }
1662 indiv_attr_event_subs
1666 indiv_educ_sect : OPEN DELIM TAG_EDUC mand_line_item
1667 { START(EDUC, NULL) }
1668 indiv_attr_event_subs
1672 indiv_idno_sect : OPEN DELIM TAG_IDNO mand_line_item
1673 { START(IDNO, NULL) }
1674 indiv_attr_event_subs
1678 indiv_nati_sect : OPEN DELIM TAG_NATI mand_line_item
1679 { START(NATI, NULL) }
1680 indiv_attr_event_subs
1684 indiv_nchi_sect : OPEN DELIM TAG_NCHI mand_line_item
1685 { START(NCHI, NULL) }
1686 indiv_attr_event_subs
1690 indiv_nmr_sect : OPEN DELIM TAG_NMR mand_line_item
1691 { START(NMR, NULL) }
1692 indiv_attr_event_subs
1696 indiv_occu_sect : OPEN DELIM TAG_OCCU mand_line_item
1697 { START(OCCU, NULL) }
1698 indiv_attr_event_subs
1702 indiv_prop_sect : OPEN DELIM TAG_PROP mand_line_item
1703 { START(PROP, NULL) }
1704 indiv_attr_event_subs
1708 indiv_reli_sect : OPEN DELIM TAG_RELI mand_line_item
1709 { START(RELI, NULL) }
1710 indiv_attr_event_subs
1714 indiv_resi_sect : OPEN DELIM TAG_RESI
1715 { START(RESI, NULL) }
1716 indiv_attr_event_subs
1720 indiv_ssn_sect : OPEN DELIM TAG_SSN mand_line_item
1721 { START(SSN, NULL) }
1722 indiv_attr_event_subs
1726 indiv_titl_sect : OPEN DELIM TAG_TITL mand_line_item
1727 { START(TITL, NULL) }
1728 indiv_attr_event_subs
1733 indiv_attr_event_subs : /* empty */
1734 | indiv_attr_event_subs indiv_attr_event_sub
1737 indiv_attr_event_sub : event_detail_sub
1741 /* INDIVIDUAL EVENT STRUCTURE */
1742 indiv_even_struc_sub : indiv_birt_sect
1744 | indiv_adop_sect /* 0:M */
1745 | indiv_even_sect /* 0:M */
1748 indiv_birt_sect : OPEN DELIM indiv_birt_tag opt_value indiv_birt_subs
1753 indiv_birt_tag : TAG_BIRT { START(BIRT, NULL) }
1754 | TAG_CHR { START(CHR, NULL) }
1757 indiv_birt_subs : /* empty */
1758 | indiv_birt_subs indiv_birt_sub
1761 indiv_birt_sub : event_detail_sub
1762 | indiv_birt_famc_sect { OCCUR2(FAMC,0, 1) }
1766 indiv_birt_famc_sect : OPEN DELIM TAG_FAMC mand_pointer
1767 { START(FAMC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1770 indiv_gen_sect : OPEN DELIM indiv_gen_tag opt_value indiv_gen_subs
1775 indiv_gen_tag : TAG_DEAT { START(DEAT, NULL) }
1776 | TAG_BURI { START(BURI, NULL) }
1777 | TAG_CREM { START(CREM, NULL) }
1778 | TAG_BAPM { START(BAPM, NULL) }
1779 | TAG_BARM { START(BARM, NULL) }
1780 | TAG_BASM { START(BASM, NULL) }
1781 | TAG_BLES { START(BLES, NULL) }
1782 | TAG_CHRA { START(CHRA, NULL) }
1783 | TAG_CONF { START(CONF, NULL) }
1784 | TAG_FCOM { START(FCOM, NULL) }
1785 | TAG_ORDN { START(ORDN, NULL) }
1786 | TAG_NATU { START(NATU, NULL) }
1787 | TAG_EMIG { START(EMIG, NULL) }
1788 | TAG_IMMI { START(IMMI, NULL) }
1789 | TAG_CENS { START(CENS, NULL) }
1790 | TAG_PROB { START(PROB, NULL) }
1791 | TAG_WILL { START(WILL, NULL) }
1792 | TAG_GRAD { START(GRAD, NULL) }
1793 | TAG_RETI { START(RETI, NULL) }
1796 indiv_gen_subs : /* empty */
1797 | indiv_gen_subs indiv_gen_sub
1800 indiv_gen_sub : event_detail_sub
1804 indiv_adop_sect : OPEN DELIM TAG_ADOP opt_value
1805 { START(ADOP, NULL) }
1811 indiv_adop_subs : /* empty */
1812 | indiv_adop_subs indiv_adop_sub
1815 indiv_adop_sub : event_detail_sub
1816 | indiv_adop_famc_sect { OCCUR2(FAMC,0, 1) }
1820 indiv_adop_famc_sect : OPEN DELIM TAG_FAMC mand_pointer
1821 { START(FAMC, NULL) }
1822 indiv_adop_famc_subs
1827 indiv_adop_famc_subs : /* empty */
1828 | indiv_adop_famc_subs indiv_adop_famc_sub
1831 indiv_adop_famc_sub : indiv_adop_famc_adop_sect { OCCUR2(ADOP,0, 1) }
1835 indiv_adop_famc_adop_sect : OPEN DELIM TAG_ADOP mand_line_item
1836 { START(ADOP, NULL) } no_std_subs { CHECK0 } CLOSE { }
1839 indiv_even_sect : OPEN DELIM TAG_EVEN
1840 { START(EVEN, NULL) }
1846 /* LDS INDIVIDUAL ORDINANCE */
1847 lds_indiv_ord_sub : lio_bapl_sect /* 0:M */
1848 | lio_slgc_sect /* 0:M */
1851 lio_bapl_sect : OPEN DELIM lio_bapl_tag lio_bapl_subs
1856 lio_bapl_tag : TAG_BAPL { START(BAPL, NULL) }
1857 | TAG_CONL { START(CONL, NULL) }
1858 | TAG_ENDL { START(ENDL, NULL) }
1861 lio_bapl_subs : /* empty */
1862 | lio_bapl_subs lio_bapl_sub
1865 lio_bapl_sub : lio_bapl_stat_sect { OCCUR2(STAT, 0, 1) }
1866 | lio_bapl_date_sect { OCCUR2(DATE, 0, 1) }
1867 | lio_bapl_temp_sect { OCCUR2(TEMP, 0, 1) }
1868 | lio_bapl_plac_sect { OCCUR2(PLAC, 0, 1) }
1874 lio_bapl_stat_sect : OPEN DELIM TAG_STAT mand_line_item
1875 { START(STAT, NULL) } no_std_subs { CHECK0 } CLOSE { }
1877 lio_bapl_date_sect : OPEN DELIM TAG_DATE mand_line_item
1878 { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1880 lio_bapl_temp_sect : OPEN DELIM TAG_TEMP mand_line_item
1881 { START(TEMP, NULL) } no_std_subs { CHECK0 } CLOSE { }
1883 lio_bapl_plac_sect : OPEN DELIM TAG_PLAC mand_line_item
1884 { START(PLAC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1887 lio_slgc_sect : OPEN DELIM TAG_SLGC
1888 { START(SLGC, NULL) }
1894 lio_slgc_subs : /* empty */
1895 | lio_slgc_subs lio_slgc_sub
1898 lio_slgc_sub : lio_bapl_sub
1899 | lio_slgc_famc_sect { OCCUR2(FAMC, 1, 1) }
1902 lio_slgc_famc_sect : OPEN DELIM TAG_FAMC mand_pointer
1903 { START(FAMC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1906 /* LDS SPOUSE SEALING */
1907 lds_spouse_seal_sub : lss_slgs_sect
1910 lss_slgs_sect : OPEN DELIM TAG_SLGS
1911 { START(SLGS, NULL) }
1917 lss_slgs_subs : /* empty */
1918 | lss_slgs_subs lss_slgs_sub
1921 lss_slgs_sub : lss_slgs_stat_sect { OCCUR2(STAT, 0, 1) }
1922 | lss_slgs_date_sect { OCCUR2(DATE, 0, 1) }
1923 | lss_slgs_temp_sect { OCCUR2(TEMP, 0, 1) }
1924 | lss_slgs_plac_sect { OCCUR2(PLAC, 0, 1) }
1930 lss_slgs_stat_sect : OPEN DELIM TAG_STAT mand_line_item
1931 { START(STAT, NULL) } no_std_subs { CHECK0 } CLOSE { }
1933 lss_slgs_date_sect : OPEN DELIM TAG_DATE mand_line_item
1934 { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1936 lss_slgs_temp_sect : OPEN DELIM TAG_TEMP mand_line_item
1937 { START(TEMP, NULL) } no_std_subs { CHECK0 } CLOSE { }
1939 lss_slgs_plac_sect : OPEN DELIM TAG_PLAC mand_line_item
1940 { START(PLAC, NULL) } no_std_subs { CHECK0 } CLOSE { }
1943 /* MULTIMEDIA LINK */
1944 multim_link_sub : multim_obje_link_sect
1945 | multim_obje_emb_sect
1948 multim_obje_link_sect : OPEN DELIM TAG_OBJE DELIM POINTER
1949 { START(OBJE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1952 multim_obje_emb_sect : OPEN DELIM TAG_OBJE
1953 { START(OBJE, NULL) }
1954 multim_obje_emb_subs
1955 { CHECK2(FORM,FILE) }
1959 multim_obje_emb_subs : /* empty */
1960 | multim_obje_emb_subs multim_obje_emb_sub
1963 multim_obje_emb_sub : multim_obje_form_sect { OCCUR2(FORM, 1, 1) }
1964 | multim_obje_titl_sect { OCCUR2(TITL, 0, 1) }
1965 | multim_obje_file_sect { OCCUR2(FILE, 1, 1) }
1970 multim_obje_form_sect : OPEN DELIM TAG_FORM mand_line_item
1971 { START(FORM, NULL) } no_std_subs { CHECK0 } CLOSE { }
1973 multim_obje_titl_sect : OPEN DELIM TAG_TITL mand_line_item
1974 { START(TITL, NULL) } no_std_subs { CHECK0 } CLOSE { }
1976 multim_obje_file_sect : OPEN DELIM TAG_FILE mand_line_item
1977 { START(FILE, NULL) } no_std_subs { CHECK0 } CLOSE { }
1980 /* NOTE STRUCTURE */
1981 note_struc_sub : note_struc_link_sect /* 0:M */
1982 | note_struc_emb_sect /* 0:M */
1985 note_struc_link_sect : OPEN DELIM TAG_NOTE DELIM POINTER
1986 { START(NOTE, NULL) }
1987 note_struc_link_subs
1992 note_struc_link_subs : /* empty */
1993 | note_struc_link_subs note_struc_link_sub
1996 note_struc_link_sub : source_cit_sub
2000 note_struc_emb_sect : OPEN DELIM TAG_NOTE opt_line_item
2001 { START(NOTE, NULL) }
2007 note_struc_emb_subs : /* empty */
2008 | note_struc_emb_subs note_struc_emb_sub
2011 note_struc_emb_sub : continuation_sub
2016 /* PERSONAL NAME STRUCTURE */
2017 pers_name_struc_sub : pers_name_sect /* 0:M */
2020 pers_name_sect : OPEN DELIM TAG_NAME mand_line_item
2021 { START(NAME, NULL) }
2027 pers_name_subs : /* empty */
2028 | pers_name_subs pers_name_sub
2031 pers_name_sub : pers_name_npfx_sect { OCCUR2(NPFX, 0, 1) }
2032 | pers_name_givn_sect { OCCUR2(GIVN, 0, 1) }
2033 | pers_name_nick_sect { OCCUR2(NICK, 0, 1) }
2034 | pers_name_spfx_sect { OCCUR2(SPFX, 0, 1) }
2035 | pers_name_surn_sect { OCCUR2(SURN, 0, 1) }
2036 | pers_name_nsfx_sect { OCCUR2(NSFX, 0, 1) }
2042 pers_name_npfx_sect : OPEN DELIM TAG_NPFX mand_line_item
2043 { START(NPFX, NULL) } no_std_subs { CHECK0 } CLOSE { }
2045 pers_name_givn_sect : OPEN DELIM TAG_GIVN mand_line_item
2046 { START(GIVN, NULL) } no_std_subs { CHECK0 } CLOSE { }
2048 pers_name_nick_sect : OPEN DELIM TAG_NICK mand_line_item
2049 { START(NICK, NULL) } no_std_subs { CHECK0 } CLOSE { }
2051 pers_name_spfx_sect : OPEN DELIM TAG_SPFX mand_line_item
2052 { START(SPFX, NULL) } no_std_subs { CHECK0 } CLOSE { }
2054 pers_name_surn_sect : OPEN DELIM TAG_SURN mand_line_item
2055 { START(SURN, NULL) } no_std_subs { CHECK0 } CLOSE { }
2057 pers_name_nsfx_sect : OPEN DELIM TAG_NSFX mand_line_item
2058 { START(NSFX, NULL) } no_std_subs { CHECK0 } CLOSE { }
2061 /* PLACE STRUCTURE */
2062 place_struc_sub : place_struc_plac_sect /* 0:M */
2065 place_struc_plac_sect : OPEN DELIM TAG_PLAC mand_line_item
2066 { START(PLAC, NULL) }
2067 place_struc_plac_subs
2072 place_struc_plac_subs : /* empty */
2073 | place_struc_plac_subs place_struc_plac_sub
2076 place_struc_plac_sub : place_plac_form_sect { OCCUR2(FORM, 0, 1) }
2082 place_plac_form_sect : OPEN DELIM TAG_FORM mand_line_item
2083 { START(FORM, NULL) } no_std_subs { CHECK0 } CLOSE { }
2086 /* SOURCE_CITATION */
2087 source_cit_sub : source_cit_link_sect /* 0:M */
2088 | source_cit_emb_sect /* 0:M */
2091 source_cit_link_sect : OPEN DELIM TAG_SOUR DELIM POINTER
2092 { START(SOUR, NULL) }
2093 source_cit_link_subs
2098 source_cit_link_subs : /* empty */
2099 | source_cit_link_subs source_cit_link_sub
2102 source_cit_link_sub : source_cit_page_sect { OCCUR2(PAGE, 0, 1) }
2103 | source_cit_even_sect { OCCUR2(EVEN, 0, 1) }
2104 | source_cit_data_sect { OCCUR2(DATA, 0, 1) }
2105 | source_cit_quay_sect { OCCUR2(QUAY, 0, 1) }
2111 source_cit_page_sect : OPEN DELIM TAG_PAGE mand_line_item
2112 { START(PAGE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2115 source_cit_even_sect : OPEN DELIM TAG_EVEN mand_line_item
2116 { START(EVEN, NULL) }
2117 source_cit_even_subs
2122 source_cit_even_subs : /* empty */
2123 | source_cit_even_subs source_cit_even_sub
2126 source_cit_even_sub : source_cit_even_role_sect { OCCUR2(ROLE, 0, 1) }
2130 source_cit_even_role_sect : OPEN DELIM TAG_ROLE mand_line_item
2131 { START(ROLE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2134 source_cit_data_sect : OPEN DELIM TAG_DATA
2135 { START(DATA, NULL) }
2136 source_cit_data_subs
2141 source_cit_data_subs : /* empty */
2142 | source_cit_data_subs source_cit_data_sub
2145 source_cit_data_sub : source_cit_data_date_sect { OCCUR2(DATE, 0, 1) }
2146 | source_cit_text_sect /* 0:M */
2150 source_cit_data_date_sect : OPEN DELIM TAG_DATE mand_line_item
2151 { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
2154 source_cit_text_sect : OPEN DELIM TAG_TEXT mand_line_item
2155 { START(TEXT, NULL) }
2156 source_cit_text_subs
2161 source_cit_text_subs : /* empty */
2162 | source_cit_text_subs source_cit_text_sub
2165 source_cit_text_sub : continuation_sub
2169 source_cit_quay_sect : OPEN DELIM TAG_QUAY mand_line_item
2170 { START(QUAY, NULL) } no_std_subs { CHECK0 } CLOSE { }
2173 source_cit_emb_sect : OPEN DELIM TAG_SOUR mand_line_item
2174 { START(SOUR, NULL) }
2180 source_cit_emb_subs : /* empty */
2181 | source_cit_emb_subs source_cit_emb_sub
2184 source_cit_emb_sub : continuation_sub
2185 | source_cit_text_sect /* 0:M */
2190 /* SOURCE REPOSITORY CITATION */
2191 source_repos_cit_sub : source_repos_repo_sect { OCCUR2(REPO, 0, 1) }
2194 source_repos_repo_sect : OPEN DELIM TAG_REPO mand_pointer
2195 { START(REPO, NULL) }
2196 source_repos_repo_subs
2201 source_repos_repo_subs : /* empty */
2202 | source_repos_repo_subs source_repos_repo_sub
2205 source_repos_repo_sub : note_struc_sub
2206 | caln_sect /* 0:M */
2210 caln_sect : OPEN DELIM TAG_CALN mand_line_item
2211 { START(CALN, NULL) }
2217 caln_subs : /* empty */
2218 | caln_subs caln_sub
2221 caln_sub : caln_medi_sect { OCCUR2(MEDI, 0, 1) }
2225 caln_medi_sect : OPEN DELIM TAG_MEDI mand_line_item
2226 { START(MEDI, NULL) } no_std_subs { CHECK0 } CLOSE { }
2229 /* SPOUSE TO FAMILY LINK */
2230 spou_fam_link_sub : spou_fam_fams_sect /* 0:M */
2233 spou_fam_fams_sect : OPEN DELIM TAG_FAMS mand_pointer
2234 { START(FAMS, NULL) }
2240 spou_fam_fams_subs : /* empty */
2241 | spou_fam_fams_subs spou_fam_fams_sub
2244 spou_fam_fams_sub : note_struc_sub
2248 /*********************************************************************/
2250 /*********************************************************************/
2252 no_std_subs : /* empty */
2253 | no_std_subs no_std_sub
2256 no_std_sub : user_sect /* 0:M */
2258 | error error_subs CLOSE { HANDLE_ERROR }
2261 no_std_rec : user_rec /* 0:M */
2263 | error error_subs CLOSE { HANDLE_ERROR }
2266 user_rec : OPEN DELIM opt_xref USERTAG
2267 { if ($4[0] != '_') {
2268 gedcom_error("Undefined tag (and not a valid user tag): %s",
2274 { $<ctxt>$ = start_record(REC_USER, $1, $3, $4);
2280 { end_record(REC_USER, $<ctxt>7); }
2282 user_sect : OPEN DELIM opt_xref USERTAG
2283 { if ($4[0] != '_') {
2284 gedcom_error("Undefined tag (and not a valid user tag): %s",
2290 { $<ctxt>$ = start_element(ELT_USER, PARENT, $1, $4, $6, $6);
2291 START($4, $<ctxt>$);
2296 { end_element(ELT_USER, PARENT, $<ctxt>7, NULL);
2300 user_sects : /* empty */ { }
2301 | user_sects user_sect { }
2304 opt_xref : /* empty */ { $$ = NULL; }
2305 | POINTER DELIM { $$ = $1; }
2308 opt_value : /* empty */ { $$ = NULL; }
2309 | DELIM line_value { $$ = $2; }
2312 line_value : POINTER { $$ = $1; }
2313 | line_item { $$ = $1; }
2316 mand_pointer : /* empty */ { gedcom_error("Missing pointer"); YYERROR; }
2317 | DELIM POINTER { gedcom_debug_print("==Ptr: %s==\n", $2);
2321 mand_line_item : /* empty */ { gedcom_error("Missing value"); YYERROR; }
2322 | DELIM line_item { gedcom_debug_print("==Val: %s==\n", $2);
2326 opt_line_item : /* empty */ { }
2327 | DELIM line_item { }
2330 line_item : anychar { size_t i;
2331 CLEAR_BUFFER(line_item_buf);
2332 line_item_buf_ptr = line_item_buf;
2333 /* The following also takes care of '@@' */
2334 if (!strncmp($1, "@@", 3))
2335 *line_item_buf_ptr++ = '@';
2337 for (i=0; i < strlen($1); i++)
2338 *line_item_buf_ptr++ = $1[i];
2341 | ESCAPE { CLEAR_BUFFER(line_item_buf);
2342 line_item_buf_ptr = line_item_buf;
2343 /* For now, ignore escapes */
2348 /* The following also takes care of '@@' */
2349 if (!strncmp($2, "@@", 3))
2350 *line_item_buf_ptr++ = '@';
2352 for (i=0; i < strlen($2); i++)
2353 *line_item_buf_ptr++ = $2[i];
2357 { /* For now, ignore escapes */
2362 anychar : ANYCHAR { }
2366 error_subs : /* empty */
2367 | error_subs error_sect
2370 error_sect : OPEN DELIM opt_xref anytag opt_value error_subs CLOSE { }
2372 gen_sect : OPEN DELIM opt_xref anystdtag
2373 { INVALID_TAG($4); }
2374 opt_value opt_sects CLOSE
2378 gen_rec : gen_rec_top
2382 gen_rec_norm : OPEN DELIM opt_xref anystdtag
2383 { INVALID_TOP_TAG($4) }
2384 opt_value opt_sects CLOSE
2388 gen_rec_top : OPEN DELIM anytoptag
2389 { gedcom_error("Missing cross-reference"); YYERROR; }
2390 opt_value opt_sects CLOSE
2394 opt_sects : /* empty */ { }
2395 | opt_sects gen_sect { }
2398 anytag : USERTAG { }
2412 anystdtag : TAG_ABBR
2542 /* Functions that handle the counting of subtags */
2544 int* count_arrays[MAXGEDCLEVEL+1];
2545 char tag_stack[MAXGEDCLEVEL+1][MAXSTDTAGLEN+1];
2546 Gedcom_ctxt ctxt_stack[MAXGEDCLEVEL+1];
2548 void push_countarray()
2551 if (count_level > MAXGEDCLEVEL) {
2552 gedcom_error("Internal error: count array overflow");
2556 count = (int *)calloc(YYNTOKENS, sizeof(int));
2557 if (count == NULL) {
2558 gedcom_error("Internal error: count array calloc error");
2562 count_arrays[count_level] = count;
2567 void set_parenttag(char* tag)
2569 strncpy(tag_stack[count_level], tag, MAXSTDTAGLEN+1);
2572 void set_parentctxt(Gedcom_ctxt ctxt)
2574 ctxt_stack[count_level] = ctxt;
2577 char* get_parenttag()
2579 return tag_stack[count_level];
2582 Gedcom_ctxt get_parentctxt()
2584 return ctxt_stack[count_level];
2587 int count_tag(int tag)
2589 int *count = count_arrays[count_level];
2590 return ++count[tag - GEDCOMTAGOFFSET];
2593 int check_occurrence(int tag)
2595 int *count = count_arrays[count_level];
2596 return (count[tag - GEDCOMTAGOFFSET] > 0);
2599 void pop_countarray()
2602 if (count_level < 0) {
2603 gedcom_error("Internal error: count array underflow");
2607 count = count_arrays[count_level];
2609 count_arrays[count_level] = NULL;
2613 /* Enabling debug mode */
2614 /* level 0: no debugging */
2615 /* level 1: only internal */
2616 /* level 2: also bison */
2619 void gedcom_set_debug_level(int level, FILE* f)
2624 trace_output = stderr;
2626 gedcom_high_level_debug = 1;
2635 int gedcom_debug_print(char* s, ...)
2638 if (gedcom_high_level_debug) {
2641 res = vfprintf(trace_output, s, ap);
2647 /* Setting the error mechanism */
2648 void gedcom_set_error_handling(Gedcom_err_mech mechanism)
2650 error_mechanism = mechanism;
2653 /* Compatibility handling */
2655 void gedcom_set_compat_handling(int enable_compat)
2657 compat_enabled = enable_compat;
2660 void set_compatibility(char* program)
2662 if (compat_enabled) {
2663 gedcom_debug_print("==== Program: %s\n", program);
2664 if (! strncmp(program, "ftree", 6)) {
2665 gedcom_warning("Enabling compatibility with 'ftree'");
2666 compatibility = C_FTREE;
2674 int compat_mode(int compat_flags)
2676 return (compat_flags & compatibility);