X-Git-Url: https://git.dlugolecki.net.pl/?a=blobdiff_plain;f=gedcom%2Fgedcom.y;h=911b5fdf85b0a049002b59bc80de634792efe2f1;hb=44bfd161d5274ff6a39f3640d745b9bbabe715ad;hp=10486dadc7889c8b6cec9eee958de326bbe00cfe;hpb=a9ef3e45e68f855ec594bd5f1fa5e25618a706fd;p=gedcom-parse.git diff --git a/gedcom/gedcom.y b/gedcom/gedcom.y index 10486da..911b5fd 100644 --- a/gedcom/gedcom.y +++ b/gedcom/gedcom.y @@ -162,15 +162,16 @@ char line_item_buf[MAXGEDCLINELEN * UTF_FACTOR + 1]; char *line_item_buf_ptr; enum _COMPAT { - C_FTREE = 0x01 + C_FTREE = 0x01, + C_LIFELINES = 0x02 }; /* 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); @@ -204,10 +205,12 @@ 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; \ @@ -229,14 +232,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; \ @@ -257,7 +260,7 @@ int compat_mode(int flags); } %token_table -%expect 303 +%expect 304 %token BADTOKEN %token OPEN @@ -418,6 +421,8 @@ int compat_mode(int flags); file : head_sect records trlr_sect { if (fail == 1) YYABORT; } + | error + { } ; records : /* empty */ @@ -448,12 +453,18 @@ head_sect : OPEN DELIM TAG_HEAD CHECK3(SOUR, GEDC, CHAR); compat_generate_submitter_link($4); } + else if (compat_mode(C_LIFELINES)) { + CHECK1(SOUR); + compat_generate_submitter_link($4); + compat_generate_gedcom($4); + if (compat_generate_char($4)) YYABORT; + } else CHECK4(SOUR, SUBM, GEDC, CHAR) } CLOSE { end_record(REC_HEAD, $4); - if (compat_mode(C_FTREE)) + if (compat_mode(C_FTREE | C_LIFELINES)) compat_generate_submitter(); } ; @@ -465,6 +476,9 @@ head_subs : /* empty */ head_sub : head_sour_sect { OCCUR2(SOUR, 1, 1) } | head_dest_sect { OCCUR2(DEST, 0, 1) } | head_date_sect { OCCUR2(DATE, 0, 1) } + | head_time_sect { if (!compat_mode(C_LIFELINES)) + INVALID_TAG("TIME"); + OCCUR2(TIME, 0, 1) } | head_subm_sect { OCCUR2(SUBM, 1, 1) } | head_subn_sect { OCCUR2(SUBN, 0, 1) } | head_file_sect { OCCUR2(FILE, 0, 1) } @@ -656,6 +670,13 @@ head_date_time_sect : OPEN DELIM TAG_TIME mand_line_item } ; +/* HEAD.TIME (Only for 'Lifelines' compatibility) */ +/* Just ignore the time... */ +head_time_sect : OPEN DELIM TAG_TIME opt_line_item + { } + CLOSE + ; + /* HEAD.SUBM */ head_subm_sect : OPEN DELIM TAG_SUBM mand_pointer { struct xref_value *xr = gedcom_parse_xref($4, XREF_USED, @@ -1199,10 +1220,25 @@ ftree_addr_subs : /* empty */ ; ftree_addr_sub : continuation_sub - | phon_sect + | 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 ****/ /*********************************************************************/ @@ -3526,7 +3562,16 @@ mand_pointer : /* empty */ { gedcom_error(_("Missing pointer")); YYERROR; } $$ = $2; } ; -mand_line_item : /* empty */ { gedcom_error(_("Missing value")); YYERROR; } +mand_line_item : /* empty */ + { if (compat_mode(C_LIFELINES)) { + /* Lifelines tends to not care about mandatory values */ + gedcom_debug_print("==Val: =="); + $$ = ""; + } + else { + gedcom_error(_("Missing value")); YYERROR; + } + } | DELIM line_item { gedcom_debug_print("==Val: %s==", $2); $$ = $2; } ; @@ -3787,14 +3832,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) @@ -3878,6 +3923,12 @@ void set_compatibility(char* program) gedcom_warning(_("Enabling compatibility with 'ftree'")); compatibility = C_FTREE; } + else if (! strncmp(program, "LIFELINES", 9)) { + /* Matches "LIFELINES 3.0.2" */ + gedcom_warning(_("Enabling compatibility with 'Lifelines'")); + compatibility = C_LIFELINES; + compat_at = 1; + } else { compatibility = 0; }