From 0a9103e26559e1501b6cf7dd7f8eb00ba50de1cb Mon Sep 17 00:00:00 2001 From: Peter Verthez Date: Fri, 16 Aug 2002 16:12:38 +0000 Subject: [PATCH] Add compatibility for Lifelines. --- gedcom/compat.c | 70 ++++++++++++++++++++++++++++++++++++++++- gedcom/compat.h | 4 +++ gedcom/gedcom.y | 40 ++++++++++++++++++++--- gedcom/gedcom_1byte.lex | 3 ++ gedcom/gedcom_hilo.lex | 3 ++ gedcom/gedcom_lohi.lex | 3 ++ 6 files changed, 118 insertions(+), 5 deletions(-) diff --git a/gedcom/compat.c b/gedcom/compat.c index f18e1be..59e61d3 100644 --- a/gedcom/compat.c +++ b/gedcom/compat.c @@ -23,12 +23,20 @@ #include "compat.h" #include "interface.h" +#include "encoding.h" #include "xref.h" #include "gedcom_internal.h" #include "gedcom.h" -#define SUBMITTER_LINK "@__COMPAT__SUBM__@" +int compat_at = 0; + +#define SUBMITTER_LINK "@__COMPAT__SUBM__@" #define DEFAULT_SUBMITTER_NAME "Submitter" +#define DEFAULT_GEDCOM_VERS "5.5" +#define DEFAULT_GEDCOM_FORM "LINEAGE-LINKED" +/* Make default character set ANSI, for all 'special characters' + typically used in non-compliant gedcom generators */ +#define DEFAULT_CHAR "ANSI" /* Incompatibily list (with GEDCOM 5.5): @@ -37,6 +45,12 @@ - INDI.ADDR instead of INDI.RESI.ADDR - NOTE doesn't have a value + - Lifelines (3.0.2): + - no submitter record, no submitter link in the header + - no GEDC field in the header + - no CHAR field in the header + - TIME field outside of DATE field in the header (will be ignored here) + - '@' not written as '@@' in values */ void compat_generate_submitter_link(Gedcom_ctxt parent) @@ -80,6 +94,60 @@ void compat_generate_submitter() end_record(REC_SUBM, self1); } +void compat_generate_gedcom(Gedcom_ctxt parent) +{ + struct tag_struct ts; + Gedcom_ctxt self1, self2; + + /* first generate "1 GEDC" */ + ts.string = "GEDC"; + ts.value = TAG_GEDC; + self1 = start_element(ELT_HEAD_GEDC, parent, 1, ts, NULL, + GEDCOM_MAKE_NULL(val1)); + + /* then generate "2 VERS " */ + ts.string = "VERS"; + ts.value = TAG_VERS; + self2 = start_element(ELT_HEAD_GEDC_VERS, self1, 2, ts, + DEFAULT_GEDCOM_VERS, + GEDCOM_MAKE_STRING(val1, DEFAULT_GEDCOM_VERS)); + + /* close "2 VERS" */ + end_element(ELT_HEAD_GEDC_VERS, self1, self2, NULL); + + /* then generate "2 FORM */ + ts.string = "FORM"; + ts.value = TAG_FORM; + self2 = start_element(ELT_HEAD_GEDC_FORM, self1, 2, ts, + DEFAULT_GEDCOM_FORM, + GEDCOM_MAKE_STRING(val1, DEFAULT_GEDCOM_FORM)); + + /* close "2 FORM" */ + end_element(ELT_HEAD_GEDC_FORM, self1, self2, NULL); + + /* close "1 GEDC" */ + end_element(ELT_HEAD_GEDC, parent, self1, NULL); +} + +int compat_generate_char(Gedcom_ctxt parent) +{ + struct tag_struct ts; + Gedcom_ctxt self1; + + /* first generate "1 CHAR " */ + ts.string = "CHAR"; + ts.value = TAG_CHAR; + self1 = start_element(ELT_HEAD_CHAR, parent, 1, ts, DEFAULT_CHAR, + GEDCOM_MAKE_STRING(val1, DEFAULT_CHAR)); + + /* close "1 CHAR" */ + end_element(ELT_HEAD_CHAR, parent, self1, NULL); + if (open_conv_to_internal(DEFAULT_CHAR) == 0) + return 1; + else + return 0; +} + Gedcom_ctxt compat_generate_resi_start(Gedcom_ctxt parent) { Gedcom_ctxt self; diff --git a/gedcom/compat.h b/gedcom/compat.h index 2bd454f..f92293c 100644 --- a/gedcom/compat.h +++ b/gedcom/compat.h @@ -26,8 +26,12 @@ #include "gedcom.h" +extern int compat_at; + void compat_generate_submitter_link(Gedcom_ctxt parent); void compat_generate_submitter(); +void compat_generate_gedcom(Gedcom_ctxt parent); +int compat_generate_char(Gedcom_ctxt parent); Gedcom_ctxt compat_generate_resi_start(Gedcom_ctxt parent); void compat_generate_resi_end(Gedcom_ctxt parent, Gedcom_ctxt self); diff --git a/gedcom/gedcom.y b/gedcom/gedcom.y index 4884719..911b5fd 100644 --- a/gedcom/gedcom.y +++ b/gedcom/gedcom.y @@ -162,7 +162,8 @@ 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 */ @@ -259,7 +260,7 @@ int compat_mode(int flags); } %token_table -%expect 303 +%expect 304 %token BADTOKEN %token OPEN @@ -452,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(); } ; @@ -469,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) } @@ -660,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, @@ -3545,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; } ; @@ -3897,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; } diff --git a/gedcom/gedcom_1byte.lex b/gedcom/gedcom_1byte.lex index be44965..6431dcf 100644 --- a/gedcom/gedcom_1byte.lex +++ b/gedcom/gedcom_1byte.lex @@ -37,6 +37,7 @@ delim " " tab [\t] hash # literal_at @@ +normal_at @ otherchar [\x21-\x22\x24-\x2F\x3A-\x3F\x5B-\x5E\x60\x7B-\x7E\x80-\xFE] terminator \x0D|\x0A|\x0D\x0A|\x0A\x0D @@ -209,6 +210,8 @@ ACTION_BEFORE_REGEXPS <> ACTION_EOF +{normal_at} ACTION_NORMAL_AT + . ACTION_UNEXPECTED %% diff --git a/gedcom/gedcom_hilo.lex b/gedcom/gedcom_hilo.lex index 60b7a1a..c7a7151 100644 --- a/gedcom/gedcom_hilo.lex +++ b/gedcom/gedcom_hilo.lex @@ -40,6 +40,7 @@ delim \x00\x20 tab \x00[\t] hash \x00# literal_at \x00@\x00@ +normal_at \x00@ otherchar \x00[\x21-\x22\x24-\x2F\x3A-\x3F\x5B-\x5E\x60\x7B-\x7E\x80-\xFF]|[\x01-\xFF][\x00-\xFF] terminator \x00\x0D|\x00\x0A|\x00\x0D\x00\x0A|\x00\x0A\x00\x0D @@ -212,6 +213,8 @@ ACTION_BEFORE_REGEXPS <> ACTION_EOF +{normal_at} ACTION_NORMAL_AT + . ACTION_UNEXPECTED %% diff --git a/gedcom/gedcom_lohi.lex b/gedcom/gedcom_lohi.lex index 13f4515..d6092a6 100644 --- a/gedcom/gedcom_lohi.lex +++ b/gedcom/gedcom_lohi.lex @@ -40,6 +40,7 @@ delim \x20\x00 tab [\t]\x00 hash #\x00 literal_at @\x00@\x00 +normal_at @\x00 otherchar [\x21-\x22\x24-\x2F\x3A-\x3F\x5B-\x5E\x60\x7B-\x7E\x80-\xFF]\x00|[\x00-\xFF][\x01-\xFF] terminator \x0D\x00|\x0A\x00|\x0D\x00\x0A\x00|\x0A\x00\x0D\x00 @@ -212,6 +213,8 @@ ACTION_BEFORE_REGEXPS <> ACTION_EOF +{normal_at} ACTION_NORMAL_AT + . ACTION_UNEXPECTED %% -- 2.30.2