X-Git-Url: https://git.dlugolecki.net.pl/?a=blobdiff_plain;f=gedcom%2Fgedcom.y;h=48847192e1ed1ed8a7d0d1b8e7abdb3bdd848923;hb=79269c03d231d3d2a564f77072d466f23cfc42c0;hp=3302c1b808fa718eab3af3e93aeae6f7992ce75b;hpb=3068ed1f64a96d42cdde19cfebf1468ec9169e62;p=gedcom-parse.git diff --git a/gedcom/gedcom.y b/gedcom/gedcom.y index 3302c1b..4884719 100644 --- a/gedcom/gedcom.y +++ b/gedcom/gedcom.y @@ -147,6 +147,7 @@ #include "interface.h" #include "date.h" #include "xref.h" +#include "compat.h" int count_level = 0; int fail = 0; @@ -167,9 +168,9 @@ enum _COMPAT { /* These are defined at the bottom of the file */ void push_countarray(); void set_parenttag(char* tag); -char* get_parenttag(); +char* get_parenttag(int offset); void set_parentctxt(Gedcom_ctxt ctxt); -Gedcom_ctxt get_parentctxt(); +Gedcom_ctxt get_parentctxt(int offset); void pop_countarray(); int count_tag(int tag); int check_occurrence(int tag); @@ -203,15 +204,17 @@ int compat_mode(int flags); START2(PARENTCTXT); \ } #define PARENT \ - get_parentctxt() + get_parentctxt(0) +#define GRANDPARENT(OFF) \ + get_parentctxt(OFF) #define CHK(TAG) \ { if (!check_occurrence(TAG_##TAG)) { \ - char* parenttag = get_parenttag(); \ + char* parenttag = get_parenttag(0); \ gedcom_error(_("The tag '%s' is mandatory within '%s', but missing"),\ #TAG, parenttag); \ HANDLE_ERROR; \ } \ - } + } #define POP \ { pop_countarray(); \ --count_level; \ @@ -228,14 +231,14 @@ int compat_mode(int flags); #define OCCUR2(CHILDTAG, MIN, MAX) \ { int num = count_tag(TAG_##CHILDTAG); \ if (num > MAX) { \ - char* parenttag = get_parenttag(); \ + char* parenttag = get_parenttag(0); \ gedcom_error(_("The tag '%s' can maximally occur %d time(s) within '%s'"), \ #CHILDTAG, MAX, parenttag); \ HANDLE_ERROR; \ } \ } #define INVALID_TAG(CHILDTAG) \ - { char* parenttag = get_parenttag(); \ + { char* parenttag = get_parenttag(0); \ gedcom_error(_("The tag '%s' is not a valid tag within '%s'"), \ CHILDTAG, parenttag); \ HANDLE_ERROR; \ @@ -256,7 +259,7 @@ int compat_mode(int flags); } %token_table -%expect 300 +%expect 303 %token BADTOKEN %token OPEN @@ -417,6 +420,8 @@ int compat_mode(int flags); file : head_sect records trlr_sect { if (fail == 1) YYABORT; } + | error + { } ; records : /* empty */ @@ -443,13 +448,18 @@ head_sect : OPEN DELIM TAG_HEAD NULL, GEDCOM_MAKE_NULL(val2)); START(HEAD, $$) } head_subs - { if (compat_mode(C_FTREE)) - CHECK3(SOUR, GEDC, CHAR) + { if (compat_mode(C_FTREE)) { + CHECK3(SOUR, GEDC, CHAR); + compat_generate_submitter_link($4); + } else CHECK4(SOUR, SUBM, GEDC, CHAR) } CLOSE - { end_record(REC_HEAD, $4); } + { end_record(REC_HEAD, $4); + if (compat_mode(C_FTREE)) + compat_generate_submitter(); + } ; head_subs : /* empty */ @@ -761,7 +771,9 @@ head_gedc_form_sect : OPEN DELIM TAG_FORM mand_line_item /* HEAD.CHAR */ head_char_sect : OPEN DELIM TAG_CHAR mand_line_item - { if (open_conv_to_internal($4) == 0) YYERROR; + { /* Don't allow to continue if conversion context couldn't + be opened */ + if (open_conv_to_internal($4) == 0) YYABORT; $$ = start_element(ELT_HEAD_CHAR, PARENT, $1, $3, $4, GEDCOM_MAKE_STRING(val1, $4)); @@ -1164,7 +1176,51 @@ indi_afn_sect : OPEN DELIM TAG_AFN mand_line_item /* INDI.ADDR (Only for 'ftree' compatibility) */ ftree_addr_sect : OPEN DELIM TAG_ADDR opt_line_item - { START(ADDR, NULL) } no_std_subs { CHECK0 } CLOSE { } + { if (compat_mode(C_FTREE)) { + Gedcom_ctxt par = compat_generate_resi_start(PARENT); + START(RESI, par); + $$ + = start_element(ELT_SUB_ADDR, + par, $1 + 1, $3, $4, + GEDCOM_MAKE_NULL_OR_STRING(val2, $4)); + START(ADDR, $$); + } + else { START(ADDR, NULL) } + } + ftree_addr_subs + { CHECK0 } + CLOSE + { if (compat_mode(C_FTREE)) { + Gedcom_ctxt par = PARENT; + end_element(ELT_SUB_ADDR, par, $5, NULL); + CHECK0; + compat_generate_resi_end(PARENT, par); + } + } + +ftree_addr_subs : /* empty */ + | ftree_addr_subs ftree_addr_sub + ; + +ftree_addr_sub : continuation_sub + | ftree_addr_phon_sect + | no_std_sub + ; + +ftree_addr_phon_sect : OPEN DELIM TAG_PHON mand_line_item + { $$ + = start_element(ELT_SUB_PHON, + GRANDPARENT(1), $1, $3, $4, + GEDCOM_MAKE_STRING(val1, $4)); + START(PHON, $$) + } + no_std_subs + { CHECK0 } + CLOSE + { end_element(ELT_SUB_PHON, GRANDPARENT(1), + $5, NULL); + } + ; /*********************************************************************/ /**** Multimedia record ****/ @@ -1744,7 +1800,7 @@ subm_subs : /* empty */ | subm_subs subm_sub ; -subm_sub : subm_name_sect { OCCUR2(NAME, 0, 1) } +subm_sub : subm_name_sect { OCCUR2(NAME, 1, 1) } | addr_struc_sub /* 0:1 */ | multim_link_sub /* 0:M */ | subm_lang_sect { OCCUR2(LANG, 0, 3) } @@ -3494,7 +3550,7 @@ mand_line_item : /* empty */ { gedcom_error(_("Missing value")); YYERROR; } $$ = $2; } ; -opt_line_item : /* empty */ { } +opt_line_item : /* empty */ { $$ = NULL; } | DELIM line_item { gedcom_debug_print("==Val: %s==", $2); $$ = $2; } ; @@ -3546,7 +3602,7 @@ error_subs : /* empty */ error_sect : OPEN DELIM opt_xref anytag opt_value error_subs CLOSE { } gen_sect : OPEN DELIM opt_xref anystdtag - { INVALID_TAG($4); } + { INVALID_TAG($4.string); } opt_value opt_sects CLOSE { } ; @@ -3556,7 +3612,7 @@ gen_rec : gen_rec_top ; gen_rec_norm : OPEN DELIM opt_xref anystdtag - { INVALID_TOP_TAG($4) } + { INVALID_TOP_TAG($4.string) } opt_value opt_sects CLOSE { } ; @@ -3750,14 +3806,14 @@ void set_parentctxt(Gedcom_ctxt ctxt) ctxt_stack[count_level+1] = ctxt; } -char* get_parenttag() +char* get_parenttag(int offset) { - return tag_stack[count_level]; + return tag_stack[count_level - offset]; } -Gedcom_ctxt get_parentctxt() +Gedcom_ctxt get_parentctxt(int offset) { - return ctxt_stack[count_level]; + return ctxt_stack[count_level - offset]; } int count_tag(int tag)