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"
- some 5.5.1 (draft) tags are used: EMAIL, FONE, ROMN
- no FAMC field in SLGC
- uses tab character (will be converted to 8 spaces here)
+ - lines too long
+ - 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'
+ - double dates written as e.g. '1815/1816'
- Family Origins:
- '@' not written as '@@' in values
- no submitter link in the header
- NOTE doesn't have a value
- NOTE.NOTE instead of NOTE.COND
+ - NOTE.CONC.SOUR instead of NOTE.SOUR
+ - non-standard tags in SOUR records
- Personal Ancestral File 4:
- '@' not written as '@@' in values
- SUBM.CTRY instead of SUBM.ADDR.CTRY
- lines too long
+ - double dates written as e.g. '1815/1816'
*/
int compat_matrix[] =
/* C_HEAD_TIME */ C_LIFELINES,
/* C_NO_DOUBLE_AT */ C_LIFELINES | C_PAF5 | C_PAF2 | C_FAMORIG
| C_PAF4,
- /* C_NO_REQUIRED_VALUES */ C_LIFELINES | C_PAF5,
+ /* C_NO_REQUIRED_VALUES */ C_LIFELINES | C_PAF5 | C_EASYTREE,
/* C_551_TAGS */ C_PAF5,
/* C_NO_SLGC_FAMC */ C_PAF5,
/* C_SUBM_COMM */ C_PAF2,
/* C_NOTE_NOTE */ C_EASYTREE,
/* C_TAB_CHARACTER */ C_PAF5,
/* C_SUBM_CTRY */ C_PAF4,
- /* C_NOTE_TOO_LONG */ C_PAF4
+ /* C_NOTE_TOO_LONG */ C_PAF4 | C_PAF5,
+ /* C_NOTE_CONC_SOUR */ C_EASYTREE,
+ /* C_NONSTD_SOUR_TAGS */ C_EASYTREE,
};
union _COMPAT_STATE {
return (compat_matrix[rule] & compatibility);
}
+void compat_close()
+{
+ compatibility_program = 0;
+ compatibility = 0;
+}
+
/********************************************************************/
/* C_NO_SUBMITTER */
/********************************************************************/
}
}
+/********************************************************************/
+/* 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 */
/********************************************************************/
end_element(ELT_SUB_CONC, parent, ctxt, GEDCOM_MAKE_NULL(val1));
}
}
+
+/********************************************************************/
+/* C_NOTE_CONC_SOUR */
+/********************************************************************/
+
+Gedcom_ctxt compat_generate_note_sour_start(Gedcom_ctxt parent,
+ int level, struct tag_struct ts,
+ char* pointer)
+{
+ Gedcom_ctxt self;
+ struct xref_value *xr = gedcom_parse_xref(pointer, XREF_USED, XREF_SOUR);
+ if (xr == NULL) {
+ self = (void*)-1;
+ }
+ else {
+ self = start_element(ELT_SUB_SOUR, parent, level-1, ts, pointer,
+ GEDCOM_MAKE_XREF_PTR(val1, xr));
+ }
+ compat_state[C_NOTE_CONC_SOUR].vp = parent;
+ return self;
+}
+
+void compat_generate_note_sour_end(Gedcom_ctxt self)
+{
+ if (self != (void*) -1) {
+ end_element(ELT_SUB_SOUR, compat_state[C_NOTE_CONC_SOUR].vp,
+ self, GEDCOM_MAKE_NULL(val1));
+ }
+}
+
+/********************************************************************/
+/* C_NONSTD_SOUR_TAGS */
+/********************************************************************/
+
+int is_nonstd_sour_tag(const char* tag)
+{
+ if (strncmp(tag, "FILN", 5))
+ return 1;
+ else if (strncmp(tag, "URL", 4))
+ return 1;
+ else if (strncmp(tag, "LOCA", 5))
+ return 1;
+ else if (strncmp(tag, "REGI", 5))
+ return 1;
+ else if (strncmp(tag, "VOL", 4))
+ return 1;
+ else
+ return 0;
+}
+
+int compat_check_sour_tag(const char* tag, struct safe_buffer* b)
+{
+ if (is_nonstd_sour_tag(tag)) {
+ reset_buffer(b);
+ SAFE_BUF_ADDCHAR(b, '_');
+ safe_buf_append(b, tag);
+ gedcom_warning(_("Converting undefined tag '%s' to user tag '%s'"),
+ tag, get_buf_string(b));
+ return 1;
+ }
+ else
+ return 0;
+}
+
+Gedcom_ctxt compat_generate_nonstd_sour_start(Gedcom_ctxt parent, int level,
+ struct tag_struct ts,
+ char* value,
+ struct safe_buffer* b)
+{
+ Gedcom_ctxt self = NULL;
+ reset_buffer(b);
+ SAFE_BUF_ADDCHAR(b, '_');
+ safe_buf_append(b, ts.string);
+ gedcom_warning(_("Converting invalidly used tag '%s' to user tag '%s'"),
+ ts.string, get_buf_string(b));
+ ts.string = get_buf_string(b);
+
+ self = start_element(ELT_USER, parent, level, ts, value,
+ GEDCOM_MAKE_NULL_OR_STRING(val1, value));
+ compat_state[C_NONSTD_SOUR_TAGS].i = 1;
+ return self;
+}
+
+void compat_generate_nonstd_sour_end(Gedcom_ctxt parent, Gedcom_ctxt self)
+{
+ end_element(ELT_USER, parent, self, NULL);
+ compat_state[C_NONSTD_SOUR_TAGS].i = 0;
+}
+
+int compat_generate_nonstd_sour_state()
+{
+ return compat_state[C_NONSTD_SOUR_TAGS].i;
+}