Add compatibility for Lifelines.
authorPeter Verthez <Peter.Verthez@advalvas.be>
Fri, 16 Aug 2002 16:12:38 +0000 (16:12 +0000)
committerPeter Verthez <Peter.Verthez@advalvas.be>
Fri, 16 Aug 2002 16:12:38 +0000 (16:12 +0000)
gedcom/compat.c
gedcom/compat.h
gedcom/gedcom.y
gedcom/gedcom_1byte.lex
gedcom/gedcom_hilo.lex
gedcom/gedcom_lohi.lex

index f18e1bef844d4c3b4f46febe70a33bccfe62cdbd..59e61d313e8ece4954693c2ab0f3fab32f529926 100644 (file)
 
 #include "compat.h"
 #include "interface.h"
+#include "encoding.h"
 #include "xref.h"
 #include "gedcom_internal.h"
 #include "gedcom.h"
 
-#define SUBMITTER_LINK "@__COMPAT__SUBM__@"
+int compat_at = 0;
+
+#define SUBMITTER_LINK         "@__COMPAT__SUBM__@"
 #define DEFAULT_SUBMITTER_NAME "Submitter"
+#define DEFAULT_GEDCOM_VERS    "5.5"
+#define DEFAULT_GEDCOM_FORM    "LINEAGE-LINKED"
+/* Make default character set ANSI, for all 'special characters'
+   typically used in non-compliant gedcom generators */
+#define DEFAULT_CHAR           "ANSI"
 
 /* Incompatibily list (with GEDCOM 5.5):
 
        - INDI.ADDR instead of INDI.RESI.ADDR
        - NOTE doesn't have a value
 
+    - Lifelines (3.0.2):
+        - no submitter record, no submitter link in the header
+       - no GEDC field in the header
+       - no CHAR field in the header
+       - TIME field outside of DATE field in the header (will be ignored here)
+       - '@' not written as '@@' in values
  */
 
 void compat_generate_submitter_link(Gedcom_ctxt parent)
@@ -80,6 +94,60 @@ void compat_generate_submitter()
   end_record(REC_SUBM, self1);
 }
 
+void compat_generate_gedcom(Gedcom_ctxt parent)
+{
+  struct tag_struct ts;
+  Gedcom_ctxt self1, self2;
+  
+  /* first generate "1 GEDC" */
+  ts.string = "GEDC";
+  ts.value  = TAG_GEDC;
+  self1 = start_element(ELT_HEAD_GEDC, parent, 1, ts, NULL,
+                       GEDCOM_MAKE_NULL(val1));
+  
+  /* then generate "2 VERS <DEFAULT_GEDC_VERS>" */
+  ts.string = "VERS";
+  ts.value  = TAG_VERS;
+  self2 = start_element(ELT_HEAD_GEDC_VERS, self1, 2, ts,
+                       DEFAULT_GEDCOM_VERS,
+                       GEDCOM_MAKE_STRING(val1, DEFAULT_GEDCOM_VERS));
+  
+  /* close "2 VERS" */
+  end_element(ELT_HEAD_GEDC_VERS, self1, self2, NULL);
+  
+  /* then generate "2 FORM <DEFAULT_GEDCOM_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));
+  
+  /* close "2 FORM" */
+  end_element(ELT_HEAD_GEDC_FORM, self1, self2, NULL);
+  
+  /* close "1 GEDC" */
+  end_element(ELT_HEAD_GEDC, parent, self1, NULL);
+}
+
+int compat_generate_char(Gedcom_ctxt parent)
+{
+  struct tag_struct ts;
+  Gedcom_ctxt self1;
+  
+  /* first generate "1 CHAR <DEFAULT_CHAR>" */
+  ts.string = "CHAR";
+  ts.value  = TAG_CHAR;
+  self1 = start_element(ELT_HEAD_CHAR, parent, 1, ts, DEFAULT_CHAR,
+                       GEDCOM_MAKE_STRING(val1, DEFAULT_CHAR));
+  
+  /* close "1 CHAR" */
+  end_element(ELT_HEAD_CHAR, parent, self1, NULL);
+  if (open_conv_to_internal(DEFAULT_CHAR) == 0)
+    return 1;
+  else
+    return 0;
+}
+
 Gedcom_ctxt compat_generate_resi_start(Gedcom_ctxt parent)
 {
   Gedcom_ctxt self;
index 2bd454f63e9247c5fd5435cfe615776aa4df3407..f92293c5629f8a560104f229b8cd76dcf64e99fb 100644 (file)
 
 #include "gedcom.h"
 
+extern int compat_at;
+
 void compat_generate_submitter_link(Gedcom_ctxt parent);
 void compat_generate_submitter();
+void compat_generate_gedcom(Gedcom_ctxt parent);
+int  compat_generate_char(Gedcom_ctxt parent);
 Gedcom_ctxt compat_generate_resi_start(Gedcom_ctxt parent);
 void compat_generate_resi_end(Gedcom_ctxt parent, Gedcom_ctxt self);
 
index 48847192e1ed1ed8a7d0d1b8e7abdb3bdd848923..911b5fdf85b0a049002b59bc80de634792efe2f1 100644 (file)
@@ -162,7 +162,8 @@ char line_item_buf[MAXGEDCLINELEN * UTF_FACTOR + 1];
 char *line_item_buf_ptr;
 
 enum _COMPAT {
-  C_FTREE = 0x01
+  C_FTREE = 0x01,
+  C_LIFELINES = 0x02
 };
 
 /* These are defined at the bottom of the file */ 
@@ -259,7 +260,7 @@ int  compat_mode(int flags);
 }
 
 %token_table
-%expect 303
+%expect 304
 
 %token <string> BADTOKEN
 %token <number> OPEN
@@ -452,12 +453,18 @@ head_sect    : OPEN DELIM TAG_HEAD
                   CHECK3(SOUR, GEDC, CHAR);
                   compat_generate_submitter_link($<ctxt>4);
                 }
+                else if (compat_mode(C_LIFELINES)) {
+                  CHECK1(SOUR);
+                  compat_generate_submitter_link($<ctxt>4);
+                  compat_generate_gedcom($<ctxt>4);
+                  if (compat_generate_char($<ctxt>4)) YYABORT;
+                }
                 else
                   CHECK4(SOUR, SUBM, GEDC, CHAR)
               }
                CLOSE
                { end_record(REC_HEAD, $<ctxt>4);
-                if (compat_mode(C_FTREE))
+                if (compat_mode(C_FTREE | C_LIFELINES))
                   compat_generate_submitter();
               }
              ;
@@ -469,6 +476,9 @@ head_subs    : /* empty */
 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))
+                                 INVALID_TAG("TIME");
+                                OCCUR2(TIME, 0, 1) }
              | head_subm_sect  { OCCUR2(SUBM, 1, 1) }
              | head_subn_sect  { OCCUR2(SUBN, 0, 1) }
              | head_file_sect  { OCCUR2(FILE, 0, 1) }
@@ -660,6 +670,13 @@ head_date_time_sect : OPEN DELIM TAG_TIME mand_line_item
                      }
                     ;
 
+/* HEAD.TIME (Only for 'Lifelines' compatibility) */
+/* Just ignore the time... */
+head_time_sect : OPEN DELIM TAG_TIME opt_line_item
+                 { }
+                 CLOSE
+              ;
+
 /* HEAD.SUBM */
 head_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
                  { struct xref_value *xr = gedcom_parse_xref($4, XREF_USED,
@@ -3545,7 +3562,16 @@ mand_pointer : /* empty */ { gedcom_error(_("Missing pointer")); YYERROR; }
                                $$ = $2; }
              ;
 
-mand_line_item : /* empty */ { gedcom_error(_("Missing value")); YYERROR; }
+mand_line_item : /* empty */
+                 { if (compat_mode(C_LIFELINES)) {
+                     /* Lifelines tends to not care about mandatory values */
+                    gedcom_debug_print("==Val: ==");
+                    $$ = "";
+                  }
+                  else {
+                    gedcom_error(_("Missing value")); YYERROR;
+                  }
+                }
                | DELIM line_item { gedcom_debug_print("==Val: %s==", $2);
                                    $$ = $2; }
                ;
@@ -3897,6 +3923,12 @@ void set_compatibility(char* program)
       gedcom_warning(_("Enabling compatibility with 'ftree'"));
       compatibility = C_FTREE;
     }
+    else if (! strncmp(program, "LIFELINES", 9)) {
+      /* Matches "LIFELINES 3.0.2" */
+      gedcom_warning(_("Enabling compatibility with 'Lifelines'"));
+      compatibility = C_LIFELINES;
+      compat_at = 1;
+    }
     else {
       compatibility = 0;
     }
index be4496552302ca447157f51714b8b6541df48951..6431dcfdcbdae061043c5947331fd376c1b7d9f1 100644 (file)
@@ -37,6 +37,7 @@ delim        " "
 tab          [\t]
 hash         #
 literal_at   @@
+normal_at    @
 otherchar    [\x21-\x22\x24-\x2F\x3A-\x3F\x5B-\x5E\x60\x7B-\x7E\x80-\xFE]
 terminator   \x0D|\x0A|\x0D\x0A|\x0A\x0D
 
@@ -209,6 +210,8 @@ ACTION_BEFORE_REGEXPS
 
 <<EOF>>                   ACTION_EOF
 
+{normal_at}               ACTION_NORMAL_AT
+
 .                         ACTION_UNEXPECTED
 
 %%
index 60b7a1a280bd41f4eea0ab9c026109251ab1045a..c7a715133d8f596fa43f1f56d3c91b8a4d634a86 100644 (file)
@@ -40,6 +40,7 @@ delim        \x00\x20
 tab          \x00[\t]
 hash         \x00#
 literal_at   \x00@\x00@
+normal_at    \x00@
 otherchar    \x00[\x21-\x22\x24-\x2F\x3A-\x3F\x5B-\x5E\x60\x7B-\x7E\x80-\xFF]|[\x01-\xFF][\x00-\xFF]
 terminator   \x00\x0D|\x00\x0A|\x00\x0D\x00\x0A|\x00\x0A\x00\x0D
 
@@ -212,6 +213,8 @@ ACTION_BEFORE_REGEXPS
 
 <<EOF>>                  ACTION_EOF
 
+{normal_at}              ACTION_NORMAL_AT
+
 .                        ACTION_UNEXPECTED
 
 %%
index 13f45152138656cf26b1f81670b6e88895f88e3a..d6092a6d67d158c3bb2e9a8c7baf27b53dc72826 100644 (file)
@@ -40,6 +40,7 @@ delim        \x20\x00
 tab          [\t]\x00
 hash         #\x00
 literal_at   @\x00@\x00
+normal_at    @\x00
 otherchar    [\x21-\x22\x24-\x2F\x3A-\x3F\x5B-\x5E\x60\x7B-\x7E\x80-\xFF]\x00|[\x00-\xFF][\x01-\xFF]
 terminator   \x0D\x00|\x0A\x00|\x0D\x00\x0A\x00|\x0A\x00\x0D\x00
 
@@ -212,6 +213,8 @@ ACTION_BEFORE_REGEXPS
 
 <<EOF>>                  ACTION_EOF
 
+{normal_at}              ACTION_NORMAL_AT
+
 .                        ACTION_UNEXPECTED
 
 %%