C_PAF5 = 0x0004,
C_PAF2 = 0x0008,
C_FAMORIG = 0x0010,
- C_EASYTREE = 0x0020
+ C_EASYTREE = 0x0020,
+ C_PAF4 = 0x0040
};
struct program_data data[] = {
- '@' not written as '@@' in values
- 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)
- Personal Ancestral File 2:
- '@' not written as '@@' in values
- no submitter link in the header
- NOTE doesn't have a value
- NOTE.NOTE instead of NOTE.COND
+
+ - Personal Ancestral File 4:
+ - '@' not written as '@@' in values
*/
int compat_matrix[] =
/* C_NO_GEDC */ C_LIFELINES | C_PAF2,
/* C_NO_CHAR */ C_LIFELINES,
/* C_HEAD_TIME */ C_LIFELINES,
- /* C_NO_DOUBLE_AT */ C_LIFELINES | C_PAF5 | C_PAF2 | C_FAMORIG,
- /* C_NO_REQUIRED_VALUES */ 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_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_PAF5 | C_PAF4,
/* C_CONC_NEEDS_SPACE */ C_FAMORIG,
/* C_NO_GEDC_FORM */ C_EASYTREE,
- /* C_NOTE_NOTE */ C_EASYTREE
+ /* C_NOTE_NOTE */ C_EASYTREE,
+ /* C_TAB_CHARACTER */ C_PAF5
};
int compat_state[C_NR_OF_RULES];
compatibility = C_PAF2;
version = 2;
}
+ if (compatibility_version >= 40000 && compatibility_version < 50000) {
+ compatibility = C_PAF4;
+ version = 4;
+ }
else if (compatibility_version >= 50000) {
compatibility = C_PAF5;
version = 5;
static int current_level = -1;
static int level_diff=MAXGEDCLEVEL;
static size_t line_len = 0;
+static int tab_space = 0;
static struct conv_buffer* ptr_buffer = NULL;
static struct conv_buffer* tag_buffer = NULL;
gedcom_error(_("'@' character should be written as '@@' in values"));
}
+static void error_tab_character()
+{
+ gedcom_error(_("Tab character is not allowed in values"));
+}
+
static void error_unexpected_character(const char* str, char ch)
{
gedcom_error(_("Unexpected character: '%s' (0x%02x)"), str, ch);
} \
}
+#define GENERATE_TAB_SPACE \
+ { gedcom_lval.string = " "; \
+ tab_space--; \
+ return DELIM; \
+ }
+
#define MKTAGACTION(THETAG) \
{ CHECK_LINE_LEN; \
gedcom_lval.tag.string = TO_INTERNAL(yytext, tag_buffer); \
But because this means that one token is converted into a series
of tokens, there is some initial code following immediately here
- that returns "pending" tokens. */
+ that returns "pending" tokens.
+
+ Also, for compatibility tabs are converted into spaces, which is
+ also handled here */
#define ACTION_BEFORE_REGEXPS \
- { if (level_diff < 1) { \
+ { if (compat_mode(C_TAB_CHARACTER) && tab_space-- > 0) { \
+ GENERATE_TAB_SPACE; \
+ } \
+ else if (level_diff < 1) { \
level_diff++; \
return CLOSE; \
} \
} \
}
+#define ACTION_TAB \
+ { if (compat_mode(C_TAB_CHARACTER)) { \
+ tab_space = 8; \
+ GENERATE_TAB_SPACE; \
+ } \
+ else { \
+ error_tab_character(); \
+ return BADTOKEN; \
+ } \
+ }
+
#define ACTION_UNEXPECTED \
{ error_unexpected_character(yytext, yytext[0]); \
return BADTOKEN; \