From afb412554732d2b908fe257697d89cb5d71ba1eb Mon Sep 17 00:00:00 2001 From: Peter Verthez Date: Mon, 27 Jan 2003 19:31:52 +0000 Subject: [PATCH] Compatibility with EasyTree and Family Origins. --- gedcom/compat.c | 99 ++++++++++++++++++++++++++++++++----------------- gedcom/compat.h | 4 ++ gedcom/gedcom.y | 36 +++++++++++++++++- 3 files changed, 102 insertions(+), 37 deletions(-) diff --git a/gedcom/compat.c b/gedcom/compat.c index 833bac1..3b05680 100644 --- a/gedcom/compat.c +++ b/gedcom/compat.c @@ -41,27 +41,36 @@ const char* default_charset = ""; #define DEFAULT_GEDCOM_VERS "5.5" #define DEFAULT_GEDCOM_FORM "LINEAGE-LINKED" +struct program_data { + const char* name; + int default_compat; + const char* default_charset; +}; + enum _COMPAT_PROGRAM { CP_FTREE = 1, CP_LIFELINES, CP_PAF, - CP_FAMORIG + CP_FAMORIG, + CP_EASYTREE }; -const char* program_name[] = { - /* NULL */ "", - /* CP_FTREE */ "ftree", - /* CP_LIFELINES */ "Lifelines", - /* CP_PAF */ "Personal Ancestral File", - /* CP_FAMORIG */ "Family Origins" +enum _COMPAT { + C_FTREE = 0x0001, + C_LIFELINES = 0x0002, + C_PAF5 = 0x0004, + C_PAF2 = 0x0008, + C_FAMORIG = 0x0010, + C_EASYTREE = 0x0020 }; -enum _COMPAT { - C_FTREE = 0x01, - C_LIFELINES = 0x02, - C_PAF5 = 0x04, - C_PAF2 = 0x08, - C_FAMORIG = 0x10 +struct program_data data[] = { + /* NULL */ { "", 0, "" }, + /* CP_FTREE */ { "ftree", C_FTREE, "" }, + /* CP_LIFELINES */ { "Lifelines", C_LIFELINES, "ANSI" }, + /* CP_PAF */ { "Personal Ancestral File", C_PAF5, "" }, + /* CP_FAMORIG */ { "Family Origins", C_FAMORIG, "" }, + /* CP_EASYTREE */ { "EasyTree", C_EASYTREE, "" } }; /* Incompatibility list (with GEDCOM 5.5): @@ -91,13 +100,20 @@ enum _COMPAT { - Family Origins: - '@' not written as '@@' in values + - CONC needs an extra space + + - EasyTree: + - no GEDC.FORM field + - no submitter link in the header + - NOTE doesn't have a value + - NOTE.NOTE instead of NOTE.COND */ int compat_matrix[] = { - /* C_NO_SUBMITTER */ C_FTREE | C_LIFELINES | C_PAF2, + /* C_NO_SUBMITTER */ C_FTREE | C_LIFELINES | C_PAF2 | C_EASYTREE, /* C_INDI_ADDR */ C_FTREE, - /* C_NOTE_NO_VALUE */ C_FTREE, + /* C_NOTE_NO_VALUE */ C_FTREE | C_EASYTREE, /* C_NO_GEDC */ C_LIFELINES | C_PAF2, /* C_NO_CHAR */ C_LIFELINES, /* C_HEAD_TIME */ C_LIFELINES, @@ -106,7 +122,10 @@ int compat_matrix[] = /* C_551_TAGS */ C_PAF5, /* C_NO_SLGC_FAMC */ C_PAF5, /* C_SUBM_COMM */ C_PAF2, - /* C_DOUBLE_DATES_4 */ C_PAF2 + /* C_DOUBLE_DATES_4 */ C_PAF2, + /* C_CONC_NEEDS_SPACE */ C_FAMORIG, + /* C_NO_GEDC_FORM */ C_EASYTREE, + /* C_NOTE_NOTE */ C_EASYTREE }; int compat_state[C_NR_OF_RULES]; @@ -160,6 +179,9 @@ void set_compatibility_program(const char* program) else if (program_equal(program, "FamilyOrigins")) { compatibility_program = CP_FAMORIG; } + else if (program_equal(program, "EasyTree")) { + compatibility_program = CP_EASYTREE; + } } } @@ -174,13 +196,6 @@ void compute_compatibility() compat_state[i] = 0; switch (compatibility_program) { - case CP_FTREE: - compatibility = C_FTREE; - break; - case CP_LIFELINES: - compatibility = C_LIFELINES; - default_charset = "ANSI"; - break; case CP_PAF: if (compatibility_version >= 20000 && compatibility_version < 30000) { compatibility = C_PAF2; @@ -191,14 +206,14 @@ void compute_compatibility() version = 5; } break; - case CP_FAMORIG: - compatibility = C_FAMORIG; - break; default: + compatibility = data[compatibility_program].default_compat; break; } - if (compatibility) - enable_compat_msg(program_name[compatibility_program], version); + if (compatibility) { + default_charset = data[compatibility_program].default_charset; + enable_compat_msg(data[compatibility_program].name, version); + } } void set_compatibility_version(const char* version) @@ -298,19 +313,33 @@ void compat_generate_gedcom(Gedcom_ctxt parent) end_element(ELT_HEAD_GEDC_VERS, self1, self2, NULL); /* then generate "2 FORM */ + compat_generate_gedcom_form(self1); + + /* close "1 GEDC" */ + end_element(ELT_HEAD_GEDC, parent, self1, NULL); +} + +/********************************************************************/ +/* C_NO_GEDC_FORM */ +/********************************************************************/ + +void compat_generate_gedcom_form(Gedcom_ctxt parent) +{ + struct tag_struct ts; + Gedcom_ctxt self; + + /* 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)); + self = start_element(ELT_HEAD_GEDC_FORM, parent, 2, ts, + DEFAULT_GEDCOM_FORM, + GEDCOM_MAKE_STRING(val1, DEFAULT_GEDCOM_FORM)); /* close "2 FORM" */ - end_element(ELT_HEAD_GEDC_FORM, self1, self2, NULL); + end_element(ELT_HEAD_GEDC_FORM, parent, self, NULL); - /* close "1 GEDC" */ - end_element(ELT_HEAD_GEDC, parent, self1, NULL); } - + /********************************************************************/ /* C_NO_CHAR */ /********************************************************************/ diff --git a/gedcom/compat.h b/gedcom/compat.h index a901197..b575469 100644 --- a/gedcom/compat.h +++ b/gedcom/compat.h @@ -40,6 +40,9 @@ typedef enum _COMPAT_RULES { C_NO_SLGC_FAMC, C_SUBM_COMM, C_DOUBLE_DATES_4, + C_CONC_NEEDS_SPACE, + C_NO_GEDC_FORM, + C_NOTE_NOTE, C_NR_OF_RULES } Compat_rule; @@ -52,6 +55,7 @@ void compat_generate_submitter_link(Gedcom_ctxt parent); void compat_generate_submitter(); void compat_generate_gedcom(Gedcom_ctxt parent); +void compat_generate_gedcom_form(Gedcom_ctxt parent); int compat_generate_char(Gedcom_ctxt parent); diff --git a/gedcom/gedcom.y b/gedcom/gedcom.y index f6d281e..41c5935 100644 --- a/gedcom/gedcom.y +++ b/gedcom/gedcom.y @@ -261,7 +261,7 @@ void clean_up(); } %token_table -%expect 308 +%expect 309 %token BADTOKEN %token OPEN @@ -755,7 +755,13 @@ head_gedc_sect : OPEN DELIM TAG_GEDC START(GEDC, $1, $$) } head_gedc_subs - { CHECK2(VERS, FORM) } + { if (compat_mode(C_NO_GEDC_FORM) && ! CHK_COND(FORM)) + compat_generate_gedcom_form($4); + else CHK(FORM); + + CHECK1(VERS) + } + CLOSE { end_element(ELT_HEAD_GEDC, PARENT, $4, GEDCOM_MAKE_NULL(val1)); @@ -1439,9 +1445,32 @@ note_sub : continuation_sub /* 0:M */ | source_cit_sub /* 0:M */ | ident_struc_sub /* 0:1 */ | change_date_sub /* 0:1 */ + | note_note_sect { if (!compat_mode(C_NOTE_NOTE)) + INVALID_TAG("NOTE"); + } | no_std_sub ; +/* Same actions as cont_sect, for compatibility */ +note_note_sect : OPEN DELIM TAG_NOTE opt_line_item + { $3.string = "CONT"; + $3.value = TAG_CONT; + $$ = start_element(ELT_SUB_CONT, + PARENT, $1, $3, $4, + GEDCOM_MAKE_NULL_OR_STRING(val1, $4)); + SAFE_BUF_ADDCHAR(&concat_buffer, '\n'); + if (GEDCOM_IS_STRING(&val1)) + safe_buf_append(&concat_buffer, $4); + START(CONT, $1, $$) + } + no_std_subs + { CHECK0 } + CLOSE + { end_element(ELT_SUB_CONT, PARENT, $5, + GEDCOM_MAKE_NULL(val1)); + } + ; + /*********************************************************************/ /**** Repository record ****/ /*********************************************************************/ @@ -2302,6 +2331,9 @@ conc_sect : OPEN DELIM TAG_CONC mand_line_item { $$ = start_element(ELT_SUB_CONC, PARENT, $1, $3, $4, GEDCOM_MAKE_STRING(val1, $4)); + if (compat_mode(C_CONC_NEEDS_SPACE)) { + safe_buf_append(&concat_buffer, " "); + } safe_buf_append(&concat_buffer, $4); START(CONC, $1, $$) } -- 2.30.2