Fix for ftree compatibility
[gedcom-parse.git] / gedcom / gedcom.y
index ed3f3033e57cf049c137b40ba7d26f5bac9b337c..e4d8a70dca7a9493378aed6758ec7db568ddc5cc 100644 (file)
@@ -168,9 +168,9 @@ enum _COMPAT {
 /* These are defined at the bottom of the file */ 
 void push_countarray();
 void set_parenttag(char* tag);
-char* get_parenttag(); 
+char* get_parenttag(int offset); 
 void set_parentctxt(Gedcom_ctxt ctxt);
-Gedcom_ctxt get_parentctxt();
+Gedcom_ctxt get_parentctxt(int offset);
 void pop_countarray();
 int  count_tag(int tag);
 int  check_occurrence(int tag);
@@ -204,10 +204,12 @@ int  compat_mode(int flags);
        START2(PARENTCTXT);                                                    \
      }
 #define PARENT                                                                \
-     get_parentctxt()
+     get_parentctxt(0)
+#define GRANDPARENT(OFF)                                                      \
+     get_parentctxt(OFF)
 #define CHK(TAG)                                                              \
      { if (!check_occurrence(TAG_##TAG)) {                                    \
-         char* parenttag = get_parenttag();                                   \
+         char* parenttag = get_parenttag(0);                                  \
          gedcom_error(_("The tag '%s' is mandatory within '%s', but missing"),\
                      #TAG, parenttag);                                       \
          HANDLE_ERROR;                                                        \
@@ -229,14 +231,14 @@ int  compat_mode(int flags);
 #define OCCUR2(CHILDTAG, MIN, MAX)                                            \
      { int num = count_tag(TAG_##CHILDTAG);                                   \
        if (num > MAX) {                                                       \
-         char* parenttag = get_parenttag();                                   \
+         char* parenttag = get_parenttag(0);                                  \
          gedcom_error(_("The tag '%s' can maximally occur %d time(s) within '%s'"),                                                                          \
                      #CHILDTAG, MAX, parenttag);                             \
          HANDLE_ERROR;                                                        \
        }                                                                      \
      }
 #define INVALID_TAG(CHILDTAG)                                                 \
-     { char* parenttag = get_parenttag();                                     \
+     { char* parenttag = get_parenttag(0);                                    \
        gedcom_error(_("The tag '%s' is not a valid tag within '%s'"),         \
                    CHILDTAG, parenttag);                                     \
        HANDLE_ERROR;                                                          \
@@ -257,7 +259,7 @@ int  compat_mode(int flags);
 }
 
 %token_table
-%expect 300
+%expect 303
 
 %token <string> BADTOKEN
 %token <number> OPEN
@@ -1172,23 +1174,52 @@ indi_afn_sect  : OPEN DELIM TAG_AFN mand_line_item
 
 /* INDI.ADDR (Only for 'ftree' compatibility) */
 ftree_addr_sect : OPEN DELIM TAG_ADDR opt_line_item
-                  { Gedcom_ctxt par = compat_generate_resi_start(PARENT);
-                   START(RESI, par);
-                   $<ctxt>$
-                     = start_element(ELT_SUB_ADDR,
-                                     par, $1 + 1, $3, $4,
-                                     GEDCOM_MAKE_NULL_OR_STRING(val2, $4));
-                   START(ADDR, $<ctxt>$)
+                  { if (compat_mode(C_FTREE)) {
+                     Gedcom_ctxt par = compat_generate_resi_start(PARENT);
+                     START(RESI, par);
+                     $<ctxt>$
+                       = start_element(ELT_SUB_ADDR,
+                                       par, $1 + 1, $3, $4,
+                                       GEDCOM_MAKE_NULL_OR_STRING(val2, $4));
+                     START(ADDR, $<ctxt>$);
+                   }
+                 else { START(ADDR, NULL) }
                  }
-                  no_std_subs
+                  ftree_addr_subs
                   { CHECK0 }
                   CLOSE
-                  { Gedcom_ctxt par = PARENT;
-                   end_element(ELT_SUB_ADDR, par, $<ctxt>5, NULL);
-                   CHECK0;
-                   compat_generate_resi_end(PARENT, par);
+                  { if (compat_mode(C_FTREE)) {
+                     Gedcom_ctxt par = PARENT;
+                     end_element(ELT_SUB_ADDR, par, $<ctxt>5, NULL);
+                     CHECK0;
+                     compat_generate_resi_end(PARENT, par);
+                   } 
                  }
 
+ftree_addr_subs : /* empty */
+                | ftree_addr_subs ftree_addr_sub
+                ;
+
+ftree_addr_sub  : continuation_sub
+                | ftree_addr_phon_sect
+                | no_std_sub
+                ;
+
+ftree_addr_phon_sect : OPEN DELIM TAG_PHON mand_line_item              
+                       { $<ctxt>$
+                          = start_element(ELT_SUB_PHON,
+                                          GRANDPARENT(1), $1, $3, $4, 
+                                          GEDCOM_MAKE_STRING(val1, $4));
+                        START(PHON, $<ctxt>$)               
+                      }               
+                       no_std_subs               
+                       { CHECK0 }               
+                       CLOSE               
+                       { end_element(ELT_SUB_PHON, GRANDPARENT(1),
+                                    $<ctxt>5, NULL);
+                      }
+            ;
+
 /*********************************************************************/
 /**** Multimedia record                                           ****/
 /*********************************************************************/
@@ -3773,14 +3804,14 @@ void set_parentctxt(Gedcom_ctxt ctxt)
   ctxt_stack[count_level+1] = ctxt;
 }
 
-char* get_parenttag()
+char* get_parenttag(int offset)
 {
-  return tag_stack[count_level];
+  return tag_stack[count_level - offset];
 }
 
-Gedcom_ctxt get_parentctxt()
+Gedcom_ctxt get_parentctxt(int offset)
 {
-  return ctxt_stack[count_level];
+  return ctxt_stack[count_level - offset];
 }
 
 int count_tag(int tag)