Gedcom_err_mech error_mechanism = IMMED_FAIL;
Gedcom_val_struct val1;
Gedcom_val_struct val2;
-
-char line_item_buf[MAXGEDCLINELEN * UTF_FACTOR + 1];
-char *line_item_buf_ptr;
+
+void cleanup_line_item_buffer();
+struct safe_buffer line_item_buffer = { NULL, 0, NULL, 0,
+ cleanup_line_item_buffer };
void cleanup_concat_buffer();
-struct safe_buffer concat_buffer = { NULL, 0, cleanup_concat_buffer };
+struct safe_buffer concat_buffer = { NULL, 0, NULL, 0, cleanup_concat_buffer };
+void cleanup_usertag_buffer();
+struct safe_buffer usertag_buffer = { NULL, 0, NULL, 0,
+ cleanup_usertag_buffer};
+
/* These are defined at the bottom of the file */
void push_countarray(int level);
void set_parenttag(const char* tag);
int check_occurrence(int tag);
void clean_up();
-#define CLEAR_BUFFER(BUF) \
- memset(BUF, 0, sizeof(BUF));
-
#define HANDLE_ERROR \
{ if (error_mechanism == IMMED_FAIL) { \
clean_up(); YYABORT; \
#TAG, parenttag); \
HANDLE_ERROR; \
} \
- }
+ }
+#define CHK_COND(TAG) \
+ check_occurrence(TAG_##TAG)
#define POP \
{ pop_countarray(); \
--count_level; \
NULL, GEDCOM_MAKE_NULL(val2));
START(HEAD, $1, $<ctxt>$) }
head_subs
- { if (compat_mode(C_FTREE)) {
- CHECK3(SOUR, GEDC, CHAR);
- compat_generate_submitter_link($<ctxt>4);
- }
- else if (compat_mode(C_LIFELINES)) {
- CHECK1(SOUR);
+ { if (compat_mode(C_NO_SUBMITTER) && ! CHK_COND(SUBM))
compat_generate_submitter_link($<ctxt>4);
+ else CHK(SUBM);
+
+ if (compat_mode(C_NO_GEDC) && ! CHK_COND(GEDC))
compat_generate_gedcom($<ctxt>4);
+ else CHK(GEDC);
+
+ if (compat_mode(C_NO_CHAR) && ! CHK_COND(CHAR)) {
if (compat_generate_char($<ctxt>4)) HANDLE_ERROR;
- }
- else
- CHECK4(SOUR, SUBM, GEDC, CHAR)
+ }
+ else CHK(CHAR);
+
+ CHECK1(SOUR);
}
CLOSE
{ end_record(REC_HEAD, $<ctxt>4, GEDCOM_MAKE_NULL(val1));
- if (compat_mode(C_FTREE | C_LIFELINES))
+ if (compat_mode(C_NO_SUBMITTER))
compat_generate_submitter();
}
;
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))
+ | head_time_sect { if (!compat_mode(C_HEAD_TIME))
INVALID_TAG("TIME");
OCCUR2(TIME, 0, 1) }
| head_subm_sect { OCCUR2(SUBM, 1, 1) }
}
;
-/* HEAD.TIME (Only for 'Lifelines' compatibility) */
+/* HEAD.TIME (Only for compatibility) */
/* Just ignore the time... */
head_time_sect : OPEN DELIM TAG_TIME opt_line_item CLOSE
{ gedcom_warning(_("Header change time lost in the compatibility"));
indi_subs
{ CHECK0 }
CLOSE
- { end_record(REC_INDI, $<ctxt>6, GEDCOM_MAKE_NULL(val1)); }
+ { end_record(REC_INDI, $<ctxt>6, GEDCOM_MAKE_NULL(val1));
+ if (compat_mode(C_NO_SLGC_FAMC))
+ compat_generate_slgc_famc_fam();
+ }
;
indi_subs : /* empty */
| indi_afn_sect /* 0:M */
| ident_struc_sub /* 0:1 */
| change_date_sub /* 0:1 */
- | ftree_addr_sect { if (!compat_mode(C_FTREE))
+ | indi_addr_sect { if (!compat_mode(C_INDI_ADDR))
INVALID_TAG("ADDR");
}
| no_std_sub
}
;
-/* INDI.ADDR (Only for 'ftree' compatibility) */
-ftree_addr_sect : OPEN DELIM TAG_ADDR opt_line_item
- { if (compat_mode(C_FTREE)) {
+/* INDI.ADDR (Only for compatibility) */
+indi_addr_sect : OPEN DELIM TAG_ADDR opt_line_item
+ { if (compat_mode(C_INDI_ADDR)) {
Gedcom_ctxt par = compat_generate_resi_start(PARENT);
START(RESI, $1, par);
$<ctxt>$
= start_element(ELT_SUB_ADDR,
par, $1 + 1, $3, $4,
GEDCOM_MAKE_NULL_OR_STRING(val2, $4));
- START(ADDR, $1, $<ctxt>$);
+ START(ADDR, $1 + 1, $<ctxt>$);
}
else { START(ADDR, $1, NULL) }
}
ftree_addr_subs
{ CHECK0 }
CLOSE
- { if (compat_mode(C_FTREE)) {
+ { if (compat_mode(C_INDI_ADDR)) {
Gedcom_ctxt par = PARENT;
end_element(ELT_SUB_ADDR, par, $<ctxt>5,
GEDCOM_MAKE_NULL(val1));
PARENT, $1, $3, NULL,
GEDCOM_MAKE_NULL(val1));
reset_buffer(&concat_buffer);
- safe_buf_append(&concat_buffer, "");
START(BLOB, $1, $<ctxt>$)
}
obje_blob_subs
;
note_line_item : /* empty */
- { if (!compat_mode(C_FTREE)) {
+ { if (!compat_mode(C_NOTE_NO_VALUE)) {
gedcom_error(_("Missing value")); YYERROR;
}
else {
{ $<ctxt>$ = start_element(ELT_SUB_ADDR_CONT,
PARENT, $1, $3, $4,
GEDCOM_MAKE_STRING(val1, $4));
- safe_buf_append(&concat_buffer, "\n");
+ SAFE_BUF_ADDCHAR(&concat_buffer, '\n');
safe_buf_append(&concat_buffer, $4);
START(CONT, $1, $<ctxt>$)
}
{ $<ctxt>$ = start_element(ELT_SUB_CONT,
PARENT, $1, $3, $4,
GEDCOM_MAKE_STRING(val1, $4));
- safe_buf_append(&concat_buffer, "\n");
+ SAFE_BUF_ADDCHAR(&concat_buffer, '\n');
safe_buf_append(&concat_buffer, $4);
START(CONT, $1, $<ctxt>$)
}
START(SLGC, $1, $<ctxt>$)
}
lio_slgc_subs
- { CHECK1(FAMC) }
+ { if (compat_mode(C_NO_SLGC_FAMC) && ! CHK_COND(FAMC))
+ compat_generate_slgc_famc_link($<ctxt>4);
+ else CHK(FAMC);
+ CHECK0;
+ }
CLOSE
{ end_element(ELT_SUB_LIO_SLGC, PARENT, $<ctxt>4,
GEDCOM_MAKE_NULL(val1));
user_rec : OPEN DELIM opt_xref USERTAG
{ if ($4.string[0] != '_') {
- gedcom_error(_("Undefined tag (and not a valid user tag): %s"),
- $4);
- YYERROR;
+ if (compat_mode(C_551_TAGS)
+ && compat_check_551_tag($4.string, &usertag_buffer)) {
+ $4.string = get_buf_string(&usertag_buffer);
+ }
+ else {
+ gedcom_error(_("Undefined tag (and not a valid user tag): %s"),
+ $4);
+ YYERROR;
+ }
}
}
opt_value
;
user_sect : OPEN DELIM opt_xref USERTAG
{ if ($4.string[0] != '_') {
- gedcom_error(_("Undefined tag (and not a valid user tag): %s"),
- $4);
- YYERROR;
+ if (compat_mode(C_551_TAGS)
+ && compat_check_551_tag($4.string, &usertag_buffer)) {
+ $4.string = get_buf_string(&usertag_buffer);
+ }
+ else {
+ gedcom_error(_("Undefined tag (and not a valid user tag): %s"),
+ $4);
+ YYERROR;
+ }
}
}
opt_value
;
mand_line_item : /* empty */
- { if (compat_mode(C_LIFELINES)) {
- /* Lifelines tends to not care about mandatory values */
- gedcom_debug_print("==Val: ==");
+ { if (compat_mode(C_NO_REQUIRED_VALUES)) {
+ gedcom_debug_print("==Val: ==");
$$ = "";
}
else {
;
line_item : anychar { size_t i;
- CLEAR_BUFFER(line_item_buf);
- line_item_buf_ptr = line_item_buf;
- /* The following also takes care of '@@' */
+ reset_buffer(&line_item_buffer);
+ /* The following also takes care of '@@' */
if (!strncmp($1, "@@", 3))
- *line_item_buf_ptr++ = '@';
+ SAFE_BUF_ADDCHAR(&line_item_buffer, '@')
else
for (i=0; i < strlen($1); i++)
- *line_item_buf_ptr++ = $1[i];
- $$ = line_item_buf;
+ SAFE_BUF_ADDCHAR(&line_item_buffer, $1[i])
+ $$ = get_buf_string(&line_item_buffer);
}
| ESCAPE { size_t i;
- CLEAR_BUFFER(line_item_buf);
- line_item_buf_ptr = line_item_buf;
- for (i=0; i < strlen($1); i++)
- *line_item_buf_ptr++ = $1[i];
- $$ = line_item_buf;
+ reset_buffer(&line_item_buffer);
+ for (i=0; i < strlen($1); i++)
+ SAFE_BUF_ADDCHAR(&line_item_buffer, $1[i])
+ $$ = get_buf_string(&line_item_buffer);
}
| line_item anychar
{ size_t i;
/* The following also takes care of '@@' */
if (!strncmp($2, "@@", 3))
- *line_item_buf_ptr++ = '@';
+ SAFE_BUF_ADDCHAR(&line_item_buffer, '@')
else
for (i=0; i < strlen($2); i++)
- *line_item_buf_ptr++ = $2[i];
- $$ = line_item_buf;
+ SAFE_BUF_ADDCHAR(&line_item_buffer, $2[i])
+ $$ = get_buf_string(&line_item_buffer);
}
| line_item ESCAPE
{ size_t i;
for (i=0; i < strlen($2); i++)
- *line_item_buf_ptr++ = $2[i];
- $$ = line_item_buf;
+ SAFE_BUF_ADDCHAR(&line_item_buffer, $2[i])
+ $$ = get_buf_string(&line_item_buffer);
}
| line_item error anychar { HANDLE_ERROR; }
| line_item error ESCAPE { HANDLE_ERROR; }
cleanup_buffer(&concat_buffer);
}
+void cleanup_line_item_buffer()
+{
+ cleanup_buffer(&line_item_buffer);
+}
+
+void cleanup_usertag_buffer()
+{
+ cleanup_buffer(&usertag_buffer);
+}
+
/* Enabling debug mode */
/* level 0: no debugging */
/* level 1: only internal */