#include "interface.h"
#include "date.h"
#include "xref.h"
+#include "compat.h"
int count_level = 0;
int fail = 0;
/* 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);
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; \
#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; \
}
%token_table
-%expect 300
+%expect 303
%token <string> BADTOKEN
%token <number> OPEN
NULL, GEDCOM_MAKE_NULL(val2));
START(HEAD, $<ctxt>$) }
head_subs
- { if (compat_mode(C_FTREE))
- CHECK3(SOUR, GEDC, CHAR)
+ { if (compat_mode(C_FTREE)) {
+ CHECK3(SOUR, GEDC, CHAR);
+ compat_generate_submitter_link($<ctxt>4);
+ }
else
CHECK4(SOUR, SUBM, GEDC, CHAR)
}
CLOSE
- { end_record(REC_HEAD, $<ctxt>4); }
+ { end_record(REC_HEAD, $<ctxt>4);
+ if (compat_mode(C_FTREE))
+ compat_generate_submitter();
+ }
;
head_subs : /* empty */
/* 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;
$<ctxt>$ = start_element(ELT_HEAD_CHAR,
PARENT, $1, $3, $4,
GEDCOM_MAKE_STRING(val1, $4));
/* 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);
+ $<ctxt>$
+ = start_element(ELT_SUB_ADDR,
+ par, $1 + 1, $3, $4,
+ GEDCOM_MAKE_NULL_OR_STRING(val2, $4));
+ START(ADDR, $<ctxt>$);
+ }
+ else { START(ADDR, NULL) }
+ }
+ ftree_addr_subs
+ { CHECK0 }
+ CLOSE
+ { if (compat_mode(C_FTREE)) {
+ Gedcom_ctxt par = PARENT;
+ end_element(ELT_SUB_ADDR, par, $<ctxt>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
+ { $<ctxt>$
+ = start_element(ELT_SUB_PHON,
+ GRANDPARENT(1), $1, $3, $4,
+ GEDCOM_MAKE_STRING(val1, $4));
+ START(PHON, $<ctxt>$)
+ }
+ no_std_subs
+ { CHECK0 }
+ CLOSE
+ { end_element(ELT_SUB_PHON, GRANDPARENT(1),
+ $<ctxt>5, NULL);
+ }
+ ;
/*********************************************************************/
/**** Multimedia record ****/
| 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) }
$$ = $2; }
;
-opt_line_item : /* empty */ { }
+opt_line_item : /* empty */ { $$ = NULL; }
| DELIM line_item { gedcom_debug_print("==Val: %s==", $2);
$$ = $2; }
;
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
{ }
;
;
gen_rec_norm : OPEN DELIM opt_xref anystdtag
- { INVALID_TOP_TAG($4) }
+ { INVALID_TOP_TAG($4.string) }
opt_value opt_sects CLOSE
{ }
;
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)