#include "encoding.h"
#include "interface.h"
#include "date.h"
+#include "age.h"
#include "xref.h"
#include "compat.h"
int count_level = 0;
int fail = 0;
-int compat_enabled = 1;
int gedcom_high_level_debug = 0;
-int compatibility = 0;
Gedcom_err_mech error_mechanism = IMMED_FAIL;
Gedcom_val_struct val1;
Gedcom_val_struct val2;
char line_item_buf[MAXGEDCLINELEN * UTF_FACTOR + 1];
char *line_item_buf_ptr;
-enum _COMPAT {
- C_FTREE = 0x01
-};
-
/* These are defined at the bottom of the file */
void push_countarray();
-void set_parenttag(char* tag);
-char* get_parenttag();
+void set_parenttag(const char* tag);
+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);
-void set_compatibility(char* program);
-int compat_mode(int flags);
#define CLEAR_BUFFER(BUF) \
memset(BUF, 0, sizeof(BUF));
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 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 303
+%expect 304
%token <string> BADTOKEN
%token <number> OPEN
file : head_sect records trlr_sect
{ if (fail == 1) YYABORT; }
+ | error
+ { }
;
records : /* empty */
CHECK3(SOUR, GEDC, CHAR);
compat_generate_submitter_link($<ctxt>4);
}
+ else if (compat_mode(C_LIFELINES)) {
+ CHECK1(SOUR);
+ compat_generate_submitter_link($<ctxt>4);
+ compat_generate_gedcom($<ctxt>4);
+ if (compat_generate_char($<ctxt>4)) YYABORT;
+ }
else
CHECK4(SOUR, SUBM, GEDC, CHAR)
}
CLOSE
{ end_record(REC_HEAD, $<ctxt>4);
- if (compat_mode(C_FTREE))
+ if (compat_mode(C_FTREE | C_LIFELINES))
compat_generate_submitter();
}
;
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) }
}
;
+/* HEAD.TIME (Only for 'Lifelines' compatibility) */
+/* Just ignore the time... */
+head_time_sect : OPEN DELIM TAG_TIME opt_line_item CLOSE
+ { gedcom_warning(_("Header change time lost in the compatibility"));
+ }
+ ;
+
/* HEAD.SUBM */
head_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
{ struct xref_value *xr = gedcom_parse_xref($4, XREF_USED,
;
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
+ { $<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 ****/
/*********************************************************************/
asso_sect : OPEN DELIM TAG_ASSO mand_pointer
{ struct xref_value *xr = gedcom_parse_xref($4, XREF_USED,
- XREF_INDI);
+ XREF_ANY);
if (xr == NULL) HANDLE_ERROR;
$<ctxt>$ = start_element(ELT_SUB_ASSO,
PARENT, $1, $3, $4,
}
;
event_detail_age_sect : OPEN DELIM TAG_AGE mand_line_item
- { $<ctxt>$
+ { struct age_value age = gedcom_parse_age($4);
+ $<ctxt>$
= start_element(ELT_SUB_EVT_AGE,
PARENT, $1, $3, $4,
- GEDCOM_MAKE_STRING(val1, $4));
+ GEDCOM_MAKE_AGE(val1, age));
START(AGE, $<ctxt>$)
}
no_std_subs
;
fam_even_age_sect : OPEN DELIM TAG_AGE mand_line_item
- { $<ctxt>$ = start_element(ELT_SUB_FAM_EVT_AGE,
+ { struct age_value age = gedcom_parse_age($4);
+ $<ctxt>$ = start_element(ELT_SUB_FAM_EVT_AGE,
PARENT, $1, $3, $4,
- GEDCOM_MAKE_STRING(val1, $4));
+ GEDCOM_MAKE_AGE(val1, age));
START(AGE, $<ctxt>$)
}
no_std_subs
$$ = $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; }
;
}
}
-void set_parenttag(char* tag)
+void set_parenttag(const char* tag)
{
strncpy(tag_stack[count_level+1], tag, MAXSTDTAGLEN+1);
}
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)
}
}
-int gedcom_debug_print(char* s, ...)
+int gedcom_debug_print(const char* s, ...)
{
int res = 0;
if (gedcom_high_level_debug) {
{
error_mechanism = mechanism;
}
-
-/* Compatibility handling */
-
-void gedcom_set_compat_handling(int enable_compat)
-{
- compat_enabled = enable_compat;
-}
-
-void set_compatibility(char* program)
-{
- if (compat_enabled) {
- if (! strncmp(program, "ftree", 6)) {
- gedcom_warning(_("Enabling compatibility with 'ftree'"));
- compatibility = C_FTREE;
- }
- else {
- compatibility = 0;
- }
- }
-}
-
-int compat_mode(int compat_flags)
-{
- return (compat_flags & compatibility);
-}
-