From 51285ba56b69a19c1a12269c76ee814102fa3256 Mon Sep 17 00:00:00 2001 From: Peter Verthez Date: Wed, 12 Feb 2003 20:15:58 +0000 Subject: [PATCH] Better handling of PAF double dates ('1815/1820'). --- gedcom/compat.c | 61 ++++++++++++++++++++++++++++++++++++++++---- gedcom/compat.h | 9 ++++++- gedcom/date.c | 6 +++++ gedcom/gedcom_date.y | 35 +++++++++++++------------ 4 files changed, 89 insertions(+), 22 deletions(-) diff --git a/gedcom/compat.c b/gedcom/compat.c index 2cbf818..ce45d41 100644 --- a/gedcom/compat.c +++ b/gedcom/compat.c @@ -36,6 +36,14 @@ int compatibility_program = 0; int compatibility_version = 0; const char* default_charset = ""; +void cleanup_compat_buffer(); +struct safe_buffer compat_buffer = { NULL, 0, NULL, 0, cleanup_compat_buffer }; + +void cleanup_compat_buffer() +{ + cleanup_buffer(&compat_buffer); +} + #define SUBMITTER_LINK "@__COMPAT__SUBM__@" #define SLGC_FAMC_LINK "@__COMPAT__FAM_SLGC__@" #define DEFAULT_SUBMITTER_NAME "Submitter" @@ -96,13 +104,12 @@ struct program_data data[] = { - no FAMC field in SLGC - uses tab character (will be converted to 8 spaces here) - lines too long - - non-standard date formats + - double dates written as e.g. '1815/1816' - Personal Ancestral File 2: - '@' not written as '@@' in values - COMM tag in submitter record - - double dates written as e.g. '1815/1816' instead of '1815/16' - - non-standard date formats + - double dates written as e.g. '1815/1816' - Family Origins: - '@' not written as '@@' in values @@ -120,7 +127,7 @@ struct program_data data[] = { - '@' not written as '@@' in values - SUBM.CTRY instead of SUBM.ADDR.CTRY - lines too long - - non-standard date formats + - double dates written as e.g. '1815/1816' */ int compat_matrix[] = @@ -146,7 +153,6 @@ int compat_matrix[] = /* C_NOTE_TOO_LONG */ C_PAF4 | C_PAF5, /* C_NOTE_CONC_SOUR */ C_EASYTREE, /* C_NONSTD_SOUR_TAGS */ C_EASYTREE, - /* C_PAF_DATES */ C_PAF2 | C_PAF4 | C_PAF5 }; union _COMPAT_STATE { @@ -645,6 +651,51 @@ void compat_subm_comm_cont_end(Gedcom_ctxt parent, Gedcom_ctxt self) } } +/********************************************************************/ +/* C_DOUBLE_DATES_4 */ +/********************************************************************/ + +void compat_date_start() +{ + if (compat_mode(C_DOUBLE_DATES_4)) { + reset_buffer(&compat_buffer); + compat_state[C_DOUBLE_DATES_4].i = 0; + } +} + +int compat_double_date_check(char* year2) +{ + return (compat_mode(C_DOUBLE_DATES_4) + && !compat_state[C_DOUBLE_DATES_4].i + && strlen(year2) == 4); +} + +int compat_double_date_final(struct date_value* dv, const char** curr_line) +{ + char* compat_line_value = get_buf_string(&compat_buffer); + compat_state[C_DOUBLE_DATES_4].i = 1; + if (compat_line_value && compat_line_value[0] + && (dv->type == DV_NO_MODIFIER || dv->type == DV_ABOUT) + && dv->date1.day == -1 + && dv->date1.month == -1) { + gedcom_warning(_("Converting '%s' to standard '%s'"), + *curr_line, compat_line_value); + *curr_line = compat_line_value; + } + return 1; +} + +int compat_date_check(struct date_value* dv, const char** curr_line) +{ + if (compat_mode(C_DOUBLE_DATES_4) + && compat_double_date_final(dv, curr_line)) { + return 1; + } + else { + return 0; + } +} + /********************************************************************/ /* C_NOTE_TOO_LONG */ /********************************************************************/ diff --git a/gedcom/compat.h b/gedcom/compat.h index 055b0f0..2dea0e3 100644 --- a/gedcom/compat.h +++ b/gedcom/compat.h @@ -49,10 +49,11 @@ typedef enum _COMPAT_RULES { C_NOTE_TOO_LONG, C_NOTE_CONC_SOUR, C_NONSTD_SOUR_TAGS, - C_PAF_DATES, C_NR_OF_RULES } Compat_rule; +extern struct safe_buffer compat_buffer; + void set_compatibility_program(const char* program); void set_compatibility_version(const char* version); void compute_compatibility(); @@ -102,6 +103,12 @@ int compat_check_subm_comm_cont(const char* tag); Gedcom_ctxt compat_subm_comm_cont_start(Gedcom_ctxt parent, char* str); void compat_subm_comm_cont_end(Gedcom_ctxt parent, Gedcom_ctxt self); +/* C_DOUBLE_DATES_4 */ +void compat_date_start(); +int compat_date_check(struct date_value* dv, const char** curr_line); + +int compat_double_date_check(char* year2); + /* C_NOTE_TOO_LONG */ int compat_long_line(int level, int tag); char* compat_long_line_get_prefix(char* str); diff --git a/gedcom/date.c b/gedcom/date.c index 19fd434..a6a8eb5 100644 --- a/gedcom/date.c +++ b/gedcom/date.c @@ -416,9 +416,15 @@ struct date_value gedcom_parse_date(const char* line_value) result = 1; } else { + compat_date_start(); init_gedcom_date_lex(line_value); gedcom_date_parse(); close_gedcom_date_lex(); + if (compat_date_check(&dv_s, &curr_line_value)) { + init_gedcom_date_lex(curr_line_value); + gedcom_date_parse(); + close_gedcom_date_lex(); + } if (dv_s.date1.cal != CAL_UNKNOWN) result |= numbers_to_sdn(&dv_s.date1); if (dv_s.date2.cal != CAL_UNKNOWN) diff --git a/gedcom/gedcom_date.y b/gedcom/gedcom_date.y index a8c829c..79af990 100644 --- a/gedcom/gedcom_date.y +++ b/gedcom/gedcom_date.y @@ -324,24 +324,32 @@ year_greg : NUMBER else YYERROR; } | NUMBER SLASH NUMBER - { int y = _get_year_num(YEAR_DOUBLE, $1, $3); - if (y != -1) { - sprintf(date_s.year_str, "%d/%02d", y-1, y%100); - date_s.year = y; - date_s.year_type = YEAR_DOUBLE; + { if (compat_double_date_check($3)) { + safe_buf_append(&compat_buffer, "BET %s AND %s", + $1, $3); + } + else { + int y = _get_year_num(YEAR_DOUBLE, $1, $3); + if (y != -1) { + sprintf(date_s.year_str, "%d/%02d", y-1, y%100); + date_s.year = y; + date_s.year_type = YEAR_DOUBLE; + } + else YYERROR; } - else YYERROR; } ; %% -void error_missing_year() { +void error_missing_year() +{ gedcom_date_error(_("Year is missing: '%s'"), curr_line_value); } -void error_missing_month() { +void error_missing_month() +{ gedcom_date_error(_("Month is missing: '%s'"), curr_line_value); } @@ -406,14 +414,9 @@ int _get_year_num(Year_type ytype, const char* input1, const char* input2) } else { if (strlen(input2) != 2) { - if (compat_mode(C_DOUBLE_DATES_4) && strlen(input2) == 4) { - input2 += 2; - } - else { - gedcom_date_error(_("Year after slash should be two digits: '%s/%s'"), - input1, input2); - return -1; - } + gedcom_date_error(_("Year after slash should be two digits: '%s/%s'"), + input1, input2); + return -1; } if (strlen(input1) <= MAX_YEAR_LEN - 3) { int year1 = atoi(input1) + 1; -- 2.30.2