Parsing of dates via a separate yacc parser.
authorPeter Verthez <Peter.Verthez@advalvas.be>
Fri, 28 Dec 2001 20:43:06 +0000 (20:43 +0000)
committerPeter Verthez <Peter.Verthez@advalvas.be>
Fri, 28 Dec 2001 20:43:06 +0000 (20:43 +0000)
Added some more callbacks in gedcom.y (not complete yet).

gedcom/Makefile.am
gedcom/date.c [new file with mode: 0644]
gedcom/date.h [new file with mode: 0644]
gedcom/gedcom.y
gedcom/gedcom_date.lex [new file with mode: 0644]
gedcom/gedcom_date.y [new file with mode: 0644]
gedcom/interface.c
gedcom/interface.h

index afc9e9eea8b7286c418272d273fb62b1fe01c76f..21d8b2020879428697c7acc7e8ddeffc94126b28 100644 (file)
@@ -2,10 +2,12 @@
 # $Id$
 # $Name$
 
+SUBDIRS = calendar .
+
 localedir = $(datadir)/locale
-INCLUDES = -I $(srcdir)/../intl -I $(srcdir)/../include \
+INCLUDES = -I $(srcdir)/../intl -I $(srcdir)/../include -I $(srcdir)/calendar \
            -DPKGDATADIR=\"$(pkgdatadir)\" -DLOCALEDIR=\"$(localedir)\"
-YFLAGS   = --debug --defines --name-prefix=gedcom_
+YFLAGS   = --debug --defines
 LFLAGS   = -8
 CFLAGS   = -g -O2 -W -Wall -pedantic
 
@@ -13,30 +15,43 @@ lib_LTLIBRARIES = libgedcom.la
 libgedcom_la_SOURCES = lex.gedcom_1byte_.c \
                       lex.gedcom_hilo_.c \
                       lex.gedcom_lohi_.c \
+                      lex.gedcom_date_.c \
                       gedcom.tab.c \
+                      gedcom_date.tab.c \
                        message.c \
                        multilex.c \
                        encoding.c \
-                       interface.c
+                       interface.c \
+                      date.c
 libgedcom_la_LDFLAGS = -version-info $(LIBVERSION)
+libgedcom_la_LIBADD  = calendar/libcalendar.la
 BUILT_SOURCES = lex.gedcom_1byte_.c \
                lex.gedcom_hilo_.c \
                lex.gedcom_lohi_.c \
+               lex.gedcom_date_.c \
                gedcom.tab.c \
-               gedcom.tab.h
+               gedcom.tab.h \
+               gedcom_date.tab.c \
+               gedcom_date.tab.h
 noinst_HEADERS = encoding.h \
                 gedcom_internal.h \
                 interface.h \
-                multilex.h
+                multilex.h \
+                date.h
 EXTRA_DIST = gedcom.y \
+            gedcom_date.y \
             gedcom_1byte.lex \
             gedcom_hilo.lex \
             gedcom_lohi.lex \
+            gedcom_date.lex \
             gedcom_lex_common.c
 
 gedcom.tab.c gedcom.tab.h:     gedcom.y
        $(YACC) $(YFLAGS) --name-prefix=gedcom_ $<
 
+gedcom_date.tab.c gedcom_date.tab.h:   gedcom_date.y
+       $(YACC) $(YFLAGS) --name-prefix=gedcom_date_ $<
+
 lex.gedcom_1byte_.c:   gedcom_1byte.lex
        $(LEX) $(LFLAGS) -Pgedcom_1byte_ $<
 
@@ -46,9 +61,13 @@ lex.gedcom_hilo_.c:  gedcom_hilo.lex
 lex.gedcom_lohi_.c:    gedcom_lohi.lex
        $(LEX) $(LFLAGS) -Pgedcom_lohi_ $<
 
+lex.gedcom_date_.c:    gedcom_date.lex
+       $(LEX) $(LFLAGS) -Pgedcom_date_ $<
+
 lex.gedcom_1byte_.c:   gedcom.tab.h gedcom_lex_common.c
 lex.gedcom_hilo_.c:    gedcom.tab.h gedcom_lex_common.c
 lex.gedcom_lohi_.c:    gedcom.tab.h gedcom_lex_common.c
+lex.gedcom_date_.c:    gedcom_date.tab.h
 
 # Lexer test programs
 
diff --git a/gedcom/date.c b/gedcom/date.c
new file mode 100644 (file)
index 0000000..c145f21
--- /dev/null
@@ -0,0 +1,141 @@
+/* Date manipulation routines.
+   Copyright (C) 2001 The Genes Development Team
+   This file is part of the Gedcom parser library.
+   Contributed by Peter Verthez <Peter.Verthez@advalvas.be>, 2001.
+
+   The Gedcom parser library is free software; you can redistribute it
+   and/or modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The Gedcom parser library is distributed in the hope that it will be
+   useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the Gedcom parser library; if not, write to the
+   Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* $Id$ */
+/* $Name$ */
+
+#include <stdio.h>
+#include "gedcom_internal.h"
+#include "sdncal.h"
+#include "date.h"
+
+struct date_value dv_s;
+struct date date_s;
+
+struct date_value def_date_val;
+struct date def_date;
+
+int max_month[] = { 12,  /* CAL_GREGORIAN */
+                   12,  /* CAL_JULIAN */
+                   13,  /* CAL_HEBREW */
+                   13,  /* CAL_FRENCH_REV */
+                   0    /* CAL_UNKNOWN */
+                  };
+
+void copy_date(struct date *to, struct date from)
+{
+  memcpy(to, &from, sizeof(struct date));
+}
+
+void init_date(struct date *d)
+{
+  d->cal = CAL_UNKNOWN;
+  d->day_str[0] = '\0';
+  d->month_str[0] = '\0';
+  d->year_str[0] = '\0';
+  d->day = -1;
+  d->month = -1;
+  d->year = -1;
+  d->year_type = YEAR_SINGLE;
+  d->type = DATE_UNRECOGNIZED;
+  d->sdn1 = -1;
+  d->sdn2 = -1;
+}
+
+struct date_value make_date_value(Date_value_type t, struct date d1,
+                                 struct date d2, char* p)
+{
+  dv_s.type = t;
+  copy_date(&dv_s.date1, d1);
+  copy_date(&dv_s.date2, d2);
+  strncpy(dv_s.phrase, p, MAX_PHRASE_LEN + 1);
+  return dv_s;
+}
+
+void make_date_complete(struct date *d)
+{
+  if (d->cal == CAL_UNKNOWN)
+    d->type = DATE_UNRECOGNIZED;
+  else {
+    struct date end_date;
+    if (d->day == -1 || d->month == -1 || d->year == -1) {
+      d->type = DATE_BOUNDED;
+      copy_date(&end_date, *d);
+      if (d->month == -1) {
+       d->month = 1; end_date.month = 1;
+       d->day   = 1; end_date.day   = 1;
+       end_date.year += 1;
+      }
+      else if (d->day == -1) {
+       d->day   = 1; end_date.day   = 1;
+       end_date.month += 1;
+       if (end_date.month > max_month[d->cal]) {
+         end_date.month -= max_month[d->cal];
+         end_date.year  += 1;
+       }
+      }
+    }
+    else {
+      d->type = DATE_EXACT;
+    }
+    
+    if (d->cal == CAL_GREGORIAN) {
+      d->sdn1 = GregorianToSdn(d->year, d->month, d->day);
+      if (d->type == DATE_BOUNDED) {
+       d->sdn2 = GregorianToSdn(end_date.year, end_date.month, end_date.day);
+       d->sdn2 -= 1;
+      }
+    }
+    else if (d->cal == CAL_JULIAN) {
+      d->sdn1 = JulianToSdn(d->year, d->month, d->day);
+      if (d->type == DATE_BOUNDED) {
+       d->sdn2 = JulianToSdn(end_date.year, end_date.month, end_date.day);
+       d->sdn2 -= 1;
+      }
+    }
+    else if (d->cal == CAL_HEBREW) {
+      d->sdn1 = JewishToSdn(d->year, d->month, d->day);
+      if (d->type == DATE_BOUNDED) {
+       d->sdn2 = JewishToSdn(end_date.year, end_date.month, end_date.day);
+       d->sdn2 -= 1;
+      }
+    }
+    else if (d->cal == CAL_FRENCH_REV) {
+      d->sdn1 = FrenchToSdn(d->year, d->month, d->day);
+      if (d->type == DATE_BOUNDED) {
+       d->sdn2 = FrenchToSdn(end_date.year, end_date.month, end_date.day);
+       d->sdn2 -= 1;
+      }
+    }
+  }
+}
+
+struct date_value gedcom_parse_date(char* line_value)
+{
+  init_date(&date_s);
+  init_date(&def_date);
+  init_gedcom_date_lex(line_value);
+  gedcom_date_parse();
+  close_gedcom_date_lex();
+  make_date_complete(&dv_s.date1);
+  make_date_complete(&dv_s.date2);
+  return dv_s;
+}
+
diff --git a/gedcom/date.h b/gedcom/date.h
new file mode 100644 (file)
index 0000000..3db5829
--- /dev/null
@@ -0,0 +1,49 @@
+/* Header for date manipulation routines.
+   Copyright (C) 2001 The Genes Development Team
+   This file is part of the Gedcom parser library.
+   Contributed by Peter Verthez <Peter.Verthez@advalvas.be>, 2001.
+
+   The Gedcom parser library is free software; you can redistribute it
+   and/or modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The Gedcom parser library is distributed in the hope that it will be
+   useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the Gedcom parser library; if not, write to the
+   Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* $Id$ */
+/* $Name$ */
+
+#ifndef __DATE_H
+#define __DATE_H
+
+#include <stdlib.h>
+#include "gedcom_internal.h"
+#include "gedcom.h"
+
+#define gedcom_date_error gedcom_error
+#define MAX_DATE_TOKEN 10
+
+extern struct date_value dv_s;
+extern struct date date_s;
+extern struct date def_date;
+
+int               gedcom_date_parse();
+int               gedcom_date_lex();
+
+/* These are defined in gedcom_date.lex */
+void              init_gedcom_date_lex(char* string);
+void              close_gedcom_date_lex();
+
+struct date_value make_date_value(Date_value_type t, struct date d1,
+                                 struct date d2, char* p);
+void              copy_date(struct date *to, struct date from);
+
+#endif /* __DATE_H */
index c8aaed00805bbf9f994914e8ae417f0da9da2ee3..7cab98ec52b3332213a28063a8d51f19003d94d4 100644 (file)
 #include "multilex.h"
 #include "encoding.h"
 #include "interface.h"
+#include "date.h"
 
 int  count_level    = 0;
 int  fail           = 0;
@@ -152,6 +153,7 @@ int  compat_enabled = 1;
 int  gedcom_high_level_debug = 0; 
 int  compatibility  = 0; 
 Gedcom_err_mech error_mechanism = IMMED_FAIL;
+Gedcom_val_struct val; 
  
 char line_item_buf[MAXGEDCLINELEN * UTF_FACTOR + 1];
 char *line_item_buf_ptr;
@@ -457,7 +459,8 @@ head_sub     : head_sour_sect  { OCCUR2(SOUR, 1, 1) }
 head_sour_sect : OPEN DELIM TAG_SOUR mand_line_item 
                  { set_compatibility($4);
                   $<ctxt>$ = start_element(ELT_HEAD_SOUR, PARENT,
-                                           $1, $3, $4, $4);
+                                           $1, $3, $4,
+                                           GEDCOM_MAKE_STRING($4));
                   START(SOUR, $<ctxt>$)
                 }
                  head_sour_subs
@@ -479,7 +482,8 @@ head_sour_sub : head_sour_vers_sect  { OCCUR2(VERS, 0, 1) }
 
 head_sour_vers_sect : OPEN DELIM TAG_VERS mand_line_item
                       { $<ctxt>$ = start_element(ELT_HEAD_SOUR_VERS, PARENT,
-                                                $1, $3, $4, $4);
+                                                $1, $3, $4,
+                                                GEDCOM_MAKE_STRING($4));
                        START(VERS, $<ctxt>$)
                      }
                       no_std_subs
@@ -491,7 +495,8 @@ head_sour_vers_sect : OPEN DELIM TAG_VERS mand_line_item
                     ;
 head_sour_name_sect : OPEN DELIM TAG_NAME mand_line_item
                       { $<ctxt>$ = start_element(ELT_HEAD_SOUR_NAME, PARENT,
-                                                $1, $3, $4, $4);
+                                                $1, $3, $4,
+                                                GEDCOM_MAKE_STRING($4));
                        START(NAME, $<ctxt>$)
                      }
                       no_std_subs
@@ -503,7 +508,8 @@ head_sour_name_sect : OPEN DELIM TAG_NAME mand_line_item
                     ;
 head_sour_corp_sect : OPEN DELIM TAG_CORP mand_line_item 
                       { $<ctxt>$ = start_element(ELT_HEAD_SOUR_CORP, PARENT,
-                                                $1, $3, $4, $4);
+                                                $1, $3, $4, 
+                                                GEDCOM_MAKE_STRING($4));
                        START(CORP, $<ctxt>$)
                      }
                       head_sour_corp_subs
@@ -524,7 +530,8 @@ head_sour_corp_sub : addr_struc_sub  /* 0:1 */
 
 head_sour_data_sect : OPEN DELIM TAG_DATA mand_line_item 
                       { $<ctxt>$ = start_element(ELT_HEAD_SOUR_DATA, PARENT,
-                                                $1, $3, $4, $4);
+                                                $1, $3, $4, 
+                                                GEDCOM_MAKE_STRING($4));
                        START(DATA, $<ctxt>$)
                      }
                       head_sour_data_subs
@@ -545,8 +552,10 @@ head_sour_data_sub : head_sour_data_date_sect  { OCCUR2(DATE, 0, 1) }
                    ;
 
 head_sour_data_date_sect : OPEN DELIM TAG_DATE mand_line_item
-                           { $<ctxt>$ = start_element(ELT_HEAD_SOUR_DATA_DATE,
-                                                     PARENT, $1, $3, $4, $4);
+                           { struct date_value dv = gedcom_parse_date($4);
+                            $<ctxt>$ = start_element(ELT_HEAD_SOUR_DATA_DATE,
+                                                     PARENT, $1, $3, $4, 
+                                                     GEDCOM_MAKE_DATE(dv));
                             START(DATE, $<ctxt>$)
                           }
                            no_std_subs
@@ -558,7 +567,8 @@ head_sour_data_date_sect : OPEN DELIM TAG_DATE mand_line_item
                          ;
 head_sour_data_copr_sect : OPEN DELIM TAG_COPR mand_line_item
                            { $<ctxt>$ = start_element(ELT_HEAD_SOUR_DATA_COPR,
-                                                     PARENT, $1, $3, $4, $4);
+                                                     PARENT, $1, $3, $4, 
+                                                     GEDCOM_MAKE_STRING($4));
                             START(COPR, $<ctxt>$)
                           }
                            no_std_subs
@@ -572,7 +582,8 @@ head_sour_data_copr_sect : OPEN DELIM TAG_COPR mand_line_item
 /* HEAD.DEST */
 head_dest_sect : OPEN DELIM TAG_DEST mand_line_item
                  { $<ctxt>$ = start_element(ELT_HEAD_DEST,
-                                           PARENT, $1, $3, $4, $4);
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
                   START(DEST, $<ctxt>$)
                 }
                  no_std_subs
@@ -585,8 +596,10 @@ head_dest_sect : OPEN DELIM TAG_DEST mand_line_item
 
 /* HEAD.DATE */
 head_date_sect : OPEN DELIM TAG_DATE mand_line_item 
-                 { $<ctxt>$ = start_element(ELT_HEAD_DATE,
-                                           PARENT, $1, $3, $4, $4);
+                 { struct date_value dv = gedcom_parse_date($4);
+                  $<ctxt>$ = start_element(ELT_HEAD_DATE,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_DATE(dv));
                   START(DATE, $<ctxt>$)
                 }
                  head_date_subs
@@ -607,7 +620,8 @@ head_date_sub  : head_date_time_sect  { OCCUR2(TIME, 0, 1) }
 
 head_date_time_sect : OPEN DELIM TAG_TIME mand_line_item
                       { $<ctxt>$ = start_element(ELT_HEAD_DATE_TIME,
-                                                PARENT, $1, $3, $4, $4);
+                                                PARENT, $1, $3, $4, 
+                                                GEDCOM_MAKE_STRING($4));
                        START(TIME, $<ctxt>$)
                      }
                       no_std_subs
@@ -621,7 +635,8 @@ head_date_time_sect : OPEN DELIM TAG_TIME mand_line_item
 /* HEAD.SUBM */
 head_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
                  { $<ctxt>$ = start_element(ELT_HEAD_SUBM,
-                                           PARENT, $1, $3, $4, $4);
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
                   START(SUBM, $<ctxt>$)
                 }
                  no_std_subs
@@ -634,7 +649,8 @@ head_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
 /* HEAD.SUBN */
 head_subn_sect : OPEN DELIM TAG_SUBN mand_pointer 
                  { $<ctxt>$ = start_element(ELT_HEAD_SUBN,
-                                           PARENT, $1, $3, $4, $4);
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
                   START(SUBN, $<ctxt>$)
                 }
                  no_std_subs
@@ -647,7 +663,8 @@ head_subn_sect : OPEN DELIM TAG_SUBN mand_pointer
 /* HEAD.FILE */
 head_file_sect : OPEN DELIM TAG_FILE mand_line_item 
                  { $<ctxt>$ = start_element(ELT_HEAD_FILE,
-                                           PARENT, $1, $3, $4, $4);
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
                   START(FILE, $<ctxt>$)
                 }
                  no_std_subs
@@ -659,7 +676,8 @@ head_file_sect : OPEN DELIM TAG_FILE mand_line_item
 /* HEAD.COPR */
 head_copr_sect : OPEN DELIM TAG_COPR mand_line_item 
                  { $<ctxt>$ = start_element(ELT_HEAD_COPR,
-                                           PARENT, $1, $3, $4, $4);
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
                   START(COPR, $<ctxt>$)
                 }
                  no_std_subs
@@ -691,7 +709,8 @@ head_gedc_sub  : head_gedc_vers_sect  { OCCUR2(VERS, 1, 1) }
                ;
 head_gedc_vers_sect : OPEN DELIM TAG_VERS mand_line_item  
                       { $<ctxt>$ = start_element(ELT_HEAD_GEDC_VERS,
-                                                PARENT, $1, $3, $4, $4);
+                                                PARENT, $1, $3, $4, 
+                                                GEDCOM_MAKE_STRING($4));
                        START(VERS, $<ctxt>$)
                      }
                       no_std_subs
@@ -703,7 +722,8 @@ head_gedc_vers_sect : OPEN DELIM TAG_VERS mand_line_item
                     ;
 head_gedc_form_sect : OPEN DELIM TAG_FORM mand_line_item   
                       { $<ctxt>$ = start_element(ELT_HEAD_GEDC_FORM,
-                                                PARENT, $1, $3, $4, $4);
+                                                PARENT, $1, $3, $4, 
+                                                GEDCOM_MAKE_STRING($4));
                        START(FORM, $<ctxt>$)
                      }
                       no_std_subs
@@ -718,7 +738,8 @@ head_gedc_form_sect : OPEN DELIM TAG_FORM mand_line_item
 head_char_sect : OPEN DELIM TAG_CHAR mand_line_item 
                  { if (open_conv_to_internal($4) == 0) YYERROR;
                   $<ctxt>$ = start_element(ELT_HEAD_CHAR,
-                                           PARENT, $1, $3, $4, $4);
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
                   START(CHAR, $<ctxt>$)
                 }
                  head_char_subs
@@ -737,7 +758,8 @@ head_char_sub  : head_char_vers_sect  { OCCUR2(VERS, 0, 1) }
                ;
 head_char_vers_sect : OPEN DELIM TAG_VERS mand_line_item   
                       { $<ctxt>$ = start_element(ELT_HEAD_CHAR_VERS,
-                                                PARENT, $1, $3, $4, $4);
+                                                PARENT, $1, $3, $4, 
+                                                GEDCOM_MAKE_STRING($4));
                        START(VERS, $<ctxt>$)
                      }
                       no_std_subs
@@ -751,7 +773,8 @@ head_char_vers_sect : OPEN DELIM TAG_VERS mand_line_item
 /* HEAD.LANG */
 head_lang_sect : OPEN DELIM TAG_LANG mand_line_item   
                  { $<ctxt>$ = start_element(ELT_HEAD_LANG,
-                                           PARENT, $1, $3, $4, $4);
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
                   START(LANG, $<ctxt>$)
                 }
                  no_std_subs
@@ -782,7 +805,8 @@ head_plac_sub  : head_plac_form_sect  { OCCUR2(FORM, 1, 1) }
                ;
 head_plac_form_sect : OPEN DELIM TAG_FORM mand_line_item   
                       { $<ctxt>$ = start_element(ELT_HEAD_PLAC_FORM,
-                                                PARENT, $1, $3, $4, $4);
+                                                PARENT, $1, $3, $4, 
+                                                GEDCOM_MAKE_STRING($4));
                        START(FORM, $<ctxt>$)
                      }
                       no_std_subs
@@ -796,7 +820,8 @@ head_plac_form_sect : OPEN DELIM TAG_FORM mand_line_item
 /* HEAD.NOTE */
 head_note_sect : OPEN DELIM TAG_NOTE mand_line_item 
                  { $<ctxt>$ = start_element(ELT_HEAD_NOTE,
-                                           PARENT, $1, $3, $4, $4);
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
                   START(NOTE, $<ctxt>$)
                 }
                  head_note_subs
@@ -855,7 +880,8 @@ fam_sub      : fam_event_struc_sub  /* 0:M */
 /* FAM.HUSB */
 fam_husb_sect : OPEN DELIM TAG_HUSB mand_pointer    
                 { $<ctxt>$ = start_element(ELT_FAM_HUSB,
-                                          PARENT, $1, $3, $4, $4);
+                                          PARENT, $1, $3, $4, 
+                                          GEDCOM_MAKE_STRING($4));
                  START(HUSB, $<ctxt>$)
                }
                 no_std_subs
@@ -868,7 +894,8 @@ fam_husb_sect : OPEN DELIM TAG_HUSB mand_pointer
 /* FAM.WIFE */
 fam_wife_sect : OPEN DELIM TAG_WIFE mand_pointer 
                 { $<ctxt>$ = start_element(ELT_FAM_WIFE,
-                                          PARENT, $1, $3, $4, $4);
+                                          PARENT, $1, $3, $4, 
+                                          GEDCOM_MAKE_STRING($4));
                  START(WIFE, $<ctxt>$)
                }
                 no_std_subs
@@ -881,7 +908,8 @@ fam_wife_sect : OPEN DELIM TAG_WIFE mand_pointer
 /* FAM.CHIL */
 fam_chil_sect : OPEN DELIM TAG_CHIL mand_pointer
                 { $<ctxt>$ = start_element(ELT_FAM_CHIL,
-                                          PARENT, $1, $3, $4, $4);
+                                          PARENT, $1, $3, $4, 
+                                          GEDCOM_MAKE_STRING($4));
                  START(CHIL, $<ctxt>$) 
                } 
                no_std_subs 
@@ -894,7 +922,8 @@ fam_chil_sect : OPEN DELIM TAG_CHIL mand_pointer
 /* FAM.NCHI */
 fam_nchi_sect : OPEN DELIM TAG_NCHI mand_line_item    
                 { $<ctxt>$ = start_element(ELT_FAM_NCHI,
-                                          PARENT, $1, $3, $4, $4);
+                                          PARENT, $1, $3, $4, 
+                                          GEDCOM_MAKE_STRING($4));
                  START(NCHI, $<ctxt>$)  
                }  
                no_std_subs  
@@ -907,7 +936,8 @@ fam_nchi_sect : OPEN DELIM TAG_NCHI mand_line_item
 /* FAM.SUBM */
 fam_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
                 { $<ctxt>$ = start_element(ELT_FAM_SUBM,
-                                          PARENT, $1, $3, $4, $4);
+                                          PARENT, $1, $3, $4, 
+                                          GEDCOM_MAKE_STRING($4));
                  START(SUBM, $<ctxt>$)   
                }   
                no_std_subs   
@@ -962,7 +992,8 @@ indi_sub    : indi_resn_sect  { OCCUR2(RESN, 0, 1) }
 /* INDI.RESN */
 indi_resn_sect : OPEN DELIM TAG_RESN mand_line_item     
                  { $<ctxt>$ = start_element(ELT_INDI_RESN,
-                                           PARENT, $1, $3, $4, $4);
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
                   START(RESN, $<ctxt>$)    
                 }    
                 no_std_subs     
@@ -975,7 +1006,8 @@ indi_resn_sect : OPEN DELIM TAG_RESN mand_line_item
 /* INDI.SEX */
 indi_sex_sect  : OPEN DELIM TAG_SEX mand_line_item     
                  { $<ctxt>$ = start_element(ELT_INDI_SEX,
-                                           PARENT, $1, $3, $4, $4);
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
                   START(SEX, $<ctxt>$)     
                 }     
                 no_std_subs     
@@ -988,7 +1020,8 @@ indi_sex_sect  : OPEN DELIM TAG_SEX mand_line_item
 /* INDI.SUBM */
 indi_subm_sect : OPEN DELIM TAG_SUBM mand_pointer 
                  { $<ctxt>$ = start_element(ELT_INDI_SUBM,
-                                           PARENT, $1, $3, $4, $4);
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
                   START(SUBM, $<ctxt>$)      
                 }      
                 no_std_subs      
@@ -1001,7 +1034,8 @@ indi_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
 /* INDI.ALIA */
 indi_alia_sect : OPEN DELIM TAG_ALIA mand_pointer
                  { $<ctxt>$ = start_element(ELT_INDI_ALIA,
-                                           PARENT, $1, $3, $4, $4);
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
                   START(ALIA, $<ctxt>$)       
                 }       
                 no_std_subs       
@@ -1014,7 +1048,8 @@ indi_alia_sect : OPEN DELIM TAG_ALIA mand_pointer
 /* INDI.ANCI */
 indi_anci_sect : OPEN DELIM TAG_ANCI mand_pointer
                  { $<ctxt>$ = start_element(ELT_INDI_ANCI,
-                                           PARENT, $1, $3, $4, $4);
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
                   START(ANCI, $<ctxt>$)        
                 }        
                 no_std_subs        
@@ -1027,7 +1062,8 @@ indi_anci_sect : OPEN DELIM TAG_ANCI mand_pointer
 /* INDI.DESI */
 indi_desi_sect : OPEN DELIM TAG_DESI mand_pointer
                  { $<ctxt>$ = start_element(ELT_INDI_DESI,
-                                           PARENT, $1, $3, $4, $4);
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
                   START(DESI, $<ctxt>$)         
                 }         
                 no_std_subs         
@@ -1040,7 +1076,8 @@ indi_desi_sect : OPEN DELIM TAG_DESI mand_pointer
 /* INDI.RFN */
 indi_rfn_sect  : OPEN DELIM TAG_RFN mand_line_item     
                  { $<ctxt>$ = start_element(ELT_INDI_RFN,
-                                           PARENT, $1, $3, $4, $4);
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
                   START(RFN, $<ctxt>$)          
                 }          
                 no_std_subs          
@@ -1053,7 +1090,8 @@ indi_rfn_sect  : OPEN DELIM TAG_RFN mand_line_item
 /* INDI.AFN */
 indi_afn_sect  : OPEN DELIM TAG_AFN mand_line_item      
                  { $<ctxt>$ = start_element(ELT_INDI_AFN,
-                                           PARENT, $1, $3, $4, $4);
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
                   START(AFN, $<ctxt>$)           
                 }           
                 no_std_subs           
@@ -1096,7 +1134,8 @@ obje_sub    : obje_form_sect  { OCCUR2(FORM, 1, 1) }
 /* OBJE.FORM */
 obje_form_sect : OPEN DELIM TAG_FORM mand_line_item       
                  { $<ctxt>$ = start_element(ELT_OBJE_FORM,
-                                           PARENT, $1, $3, $4, $4);
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
                   START(FORM, $<ctxt>$)            
                 }            
                 no_std_subs            
@@ -1109,7 +1148,8 @@ obje_form_sect : OPEN DELIM TAG_FORM mand_line_item
 /* OBJE.TITL */
 obje_titl_sect : OPEN DELIM TAG_TITL mand_line_item       
                  { $<ctxt>$ = start_element(ELT_OBJE_TITL,
-                                           PARENT, $1, $3, $4, $4);
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
                   START(TITL, $<ctxt>$)             
                 }             
                 no_std_subs             
@@ -1142,7 +1182,8 @@ obje_blob_sub  : obje_blob_cont_sect  { OCCUR1(CONT, 1) }
 
 obje_blob_cont_sect : OPEN DELIM TAG_CONT mand_line_item        
                       { $<ctxt>$ = start_element(ELT_OBJE_BLOB_CONT,
-                                                PARENT, $1, $3, $4, $4);
+                                                PARENT, $1, $3, $4, 
+                                                GEDCOM_MAKE_STRING($4));
                        START(CONT, $<ctxt>$)               
                      }                
                      no_std_subs                
@@ -1156,7 +1197,8 @@ obje_blob_cont_sect : OPEN DELIM TAG_CONT mand_line_item
 /* OBJE.OBJE */
 obje_obje_sect : OPEN DELIM TAG_OBJE mand_pointer 
                  { $<ctxt>$ = start_element(ELT_OBJE_OBJE,
-                                           PARENT, $1, $3, $4, $4);
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
                   START(OBJE, $<ctxt>$)  
                  }  
                  no_std_subs  
@@ -1226,7 +1268,8 @@ repo_sub    : repo_name_sect  { OCCUR2(NAME, 0, 1) }
 /* REPO.NAME */
 repo_name_sect : OPEN DELIM TAG_NAME mand_line_item         
                  { $<ctxt>$ = start_element(ELT_REPO_NAME,
-                                           PARENT, $1, $3, $4, $4);
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
                   START(NAME, $<ctxt>$)          
                  }          
                  no_std_subs          
@@ -1268,10 +1311,15 @@ sour_sub    : sour_data_sect  { OCCUR2(DATA, 0, 1) }
 
 /* SOUR.DATA */
 sour_data_sect : OPEN DELIM TAG_DATA
-                 { START(DATA, NULL) }
+                 { $<ctxt>$ = start_element(ELT_SOUR_DATA,
+                                           PARENT, $1, $3, NULL, NULL);
+                  START(DATA, $<ctxt>$) 
+                 }
                  sour_data_subs
                 { CHECK0 }
-                 CLOSE { }
+                 CLOSE 
+                 { end_element(ELT_SOUR_DATA, PARENT, $<ctxt>4, NULL);
+                }
                ;
 
 sour_data_subs : /* empty */
@@ -1285,10 +1333,17 @@ sour_data_sub  : sour_data_even_sect  /* 0:M */
                ;
 
 sour_data_even_sect : OPEN DELIM TAG_EVEN mand_line_item 
-                      { START(EVEN, NULL) }
+                      { $<ctxt>$ = start_element(ELT_SOUR_DATA_EVEN,
+                                                PARENT, $1, $3, $4, 
+                                                GEDCOM_MAKE_STRING($4));
+                       START(EVEN, $<ctxt>$)  
+                      }
                       sour_data_even_subs
                      { CHECK0 }
-                      CLOSE { }
+                      CLOSE  
+                      { end_element(ELT_SOUR_DATA_EVEN, PARENT,
+                                   $<ctxt>5, NULL);
+                     }
                     ;
 
 sour_data_even_subs : /* empty */
@@ -1301,23 +1356,60 @@ sour_data_even_sub  : sour_data_even_date_sect { OCCUR2(DATE, 0, 1) }
                     ;
 
 sour_data_even_date_sect : OPEN DELIM TAG_DATE mand_line_item          
-                           { START(DATE, NULL) } no_std_subs { CHECK0 } CLOSE { }
+                           { struct date_value dv = gedcom_parse_date($4);
+                            $<ctxt>$ = start_element(ELT_SOUR_DATA_EVEN_DATE,
+                                                     PARENT, $1, $3, $4, 
+                                                     GEDCOM_MAKE_DATE(dv));
+                            START(DATE, $<ctxt>$)           
+                           }           
+                           no_std_subs           
+                           { CHECK0 }           
+                           CLOSE           
+                           { end_element(ELT_SOUR_DATA_EVEN_DATE, PARENT,
+                                        $<ctxt>5, NULL);
+                          }
                          ;
 
 sour_data_even_plac_sect : OPEN DELIM TAG_PLAC mand_line_item          
-                           { START(PLAC, NULL) } no_std_subs { CHECK0 } CLOSE { }
+                           { $<ctxt>$ = start_element(ELT_SOUR_DATA_EVEN_PLAC,
+                                                     PARENT, $1, $3, $4, 
+                                                     GEDCOM_MAKE_STRING($4));
+                            START(PLAC, $<ctxt>$)           
+                           }           
+                           no_std_subs           
+                           { CHECK0 }           
+                           CLOSE           
+                           { end_element(ELT_SOUR_DATA_EVEN_PLAC, PARENT,
+                                        $<ctxt>5, NULL);
+                          }
                          ;
 
 sour_data_agnc_sect : OPEN DELIM TAG_AGNC mand_line_item          
-                      { START(AGNC, NULL) } no_std_subs { CHECK0 } CLOSE { }
+                      { $<ctxt>$ = start_element(ELT_SOUR_DATA_AGNC,
+                                                PARENT, $1, $3, $4, 
+                                                GEDCOM_MAKE_STRING($4));
+                       START(AGNC, $<ctxt>$)           
+                      }           
+                      no_std_subs           
+                      { CHECK0 }           
+                      CLOSE           
+                      { end_element(ELT_SOUR_DATA_AGNC, PARENT,
+                                   $<ctxt>5, NULL);
+                     }
                     ;
 
 /* SOUR.AUTH */
 sour_auth_sect : OPEN DELIM TAG_AUTH mand_line_item
-                 { START(AUTH, NULL) }
+                 { $<ctxt>$ = start_element(ELT_SOUR_AUTH,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(AUTH, $<ctxt>$) 
+                 }
                  sour_auth_subs
                 { CHECK0 }
-                 CLOSE { }
+                 CLOSE 
+                 { end_element(ELT_SOUR_AUTH, PARENT, $<ctxt>5, NULL);
+                }
                ;
 
 sour_auth_subs : /* empty */
@@ -1330,10 +1422,16 @@ sour_auth_sub  : continuation_sub  /* 0:M */
 
 /* SOUR.TITL */
 sour_titl_sect : OPEN DELIM TAG_TITL mand_line_item  
-                 { START(TITL, NULL) }
+                 { $<ctxt>$ = start_element(ELT_SOUR_TITL,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(TITL, $<ctxt>$)   
+                 }
                  sour_titl_subs 
                 { CHECK0 }
-                 CLOSE { }
+                 CLOSE   
+                 { end_element(ELT_SOUR_TITL, PARENT, $<ctxt>5, NULL);
+                }
                ;
 
 sour_titl_subs : /* empty */
@@ -1346,15 +1444,30 @@ sour_titl_sub  : continuation_sub  /* 0:M */
 
 /* SOUR.ABBR */
 sour_abbr_sect : OPEN DELIM TAG_ABBR mand_line_item           
-                 { START(ABBR, NULL) } no_std_subs { CHECK0 } CLOSE { }
+                 { $<ctxt>$ = start_element(ELT_SOUR_ABBR,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(ABBR, $<ctxt>$)            
+                 }            
+                 no_std_subs            
+                 { CHECK0 }            
+                 CLOSE            
+                 { end_element(ELT_SOUR_ABBR, PARENT, $<ctxt>5, NULL);
+                }
                ;
 
 /* SOUR.PUBL */
 sour_publ_sect : OPEN DELIM TAG_PUBL mand_line_item  
-                 { START(PUBL, NULL) }
+                 { $<ctxt>$ = start_element(ELT_SOUR_PUBL,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(PUBL, $<ctxt>$)            
+                 }
                  sour_publ_subs  
                 { CHECK0 }
-                 CLOSE { }
+                 CLOSE            
+                 { end_element(ELT_SOUR_PUBL, PARENT, $<ctxt>5, NULL);
+                }
                ;
 
 sour_publ_subs : /* empty */
@@ -1367,10 +1480,16 @@ sour_publ_sub  : continuation_sub  /* 0:M */
 
 /* SOUR.TEXT */
 sour_text_sect : OPEN DELIM TAG_TEXT mand_line_item   
-                 { START(TEXT, NULL) }
+                 { $<ctxt>$ = start_element(ELT_SOUR_TEXT,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(TEXT, $<ctxt>$)    
+                 }
                  sour_text_subs  
                 { CHECK0 }
-                 CLOSE { }
+                 CLOSE    
+                 { end_element(ELT_SOUR_TEXT, PARENT, $<ctxt>5, NULL);
+                }
                ;
 
 sour_text_subs : /* empty */
@@ -1409,37 +1528,100 @@ subn_sub    : subn_subm_sect  { OCCUR2(SUBM, 0, 1) }
 
 /* SUBN.SUBM */
 subn_subm_sect : OPEN DELIM TAG_SUBM mand_pointer
-                 { START(SUBM, NULL) } no_std_subs { CHECK0 } CLOSE { }
+                 { $<ctxt>$ = start_element(ELT_SUBN_SUBM,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(SUBM, $<ctxt>$) 
+                 } 
+                 no_std_subs 
+                 { CHECK0 } 
+                 CLOSE 
+                 { end_element(ELT_SUBN_SUBM, PARENT, $<ctxt>5, NULL);
+                }
                ;
 
 /* SUBN.FAMF */
 subn_famf_sect : OPEN DELIM TAG_FAMF mand_line_item            
-                 { START(FAMF, NULL) } no_std_subs { CHECK0 } CLOSE { }
+                 { $<ctxt>$ = start_element(ELT_SUBN_FAMF,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(FAMF, $<ctxt>$)             
+                 }             
+                 no_std_subs             
+                 { CHECK0 }             
+                 CLOSE             
+                 { end_element(ELT_SUBN_FAMF, PARENT, $<ctxt>5, NULL);
+                }
                ;
 
 /* SUBN.TEMP */
 subn_temp_sect : OPEN DELIM TAG_TEMP mand_line_item            
-                 { START(TEMP, NULL) } no_std_subs { CHECK0 } CLOSE { }
+                 { $<ctxt>$ = start_element(ELT_SUBN_TEMP,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(TEMP, $<ctxt>$)             
+                 }             
+                 no_std_subs             
+                 { CHECK0 }             
+                 CLOSE             
+                 { end_element(ELT_SUBN_TEMP, PARENT, $<ctxt>5, NULL);
+                }
                ;
 
 /* SUBN.ANCE */
 subn_ance_sect : OPEN DELIM TAG_ANCE mand_line_item            
-                 { START(ANCE, NULL) } no_std_subs { CHECK0 } CLOSE { }
+                 { $<ctxt>$ = start_element(ELT_SUBN_ANCE,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(ANCE, $<ctxt>$)             
+                 }             
+                 no_std_subs             
+                 { CHECK0 }             
+                 CLOSE             
+                 { end_element(ELT_SUBN_ANCE, PARENT, $<ctxt>5, NULL);
+                }
                ;
 
 /* SUBN.DESC */
 subn_desc_sect : OPEN DELIM TAG_DESC mand_line_item            
-                 { START(DESC, NULL) } no_std_subs { CHECK0 } CLOSE { }
+                 { $<ctxt>$ = start_element(ELT_SUBN_DESC,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(DESC, $<ctxt>$)             
+                 }             
+                 no_std_subs             
+                 { CHECK0 }             
+                 CLOSE             
+                 { end_element(ELT_SUBN_DESC, PARENT, $<ctxt>5, NULL);
+                }
                ;
 
 /* SUBN.ORDI */
 subn_ordi_sect : OPEN DELIM TAG_ORDI mand_line_item            
-                 { START(ORDI, NULL) } no_std_subs { CHECK0 } CLOSE { }
+                 { $<ctxt>$ = start_element(ELT_SUBN_ORDI,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(ORDI, $<ctxt>$)             
+                 }             
+                 no_std_subs             
+                 { CHECK0 }             
+                 CLOSE             
+                 { end_element(ELT_SUBN_ORDI, PARENT, $<ctxt>5, NULL);
+                }
                ;
 
 /* SUBN.RIN */
 subn_rin_sect  : OPEN DELIM TAG_RIN mand_line_item            
-                 { START(RIN, NULL) } no_std_subs { CHECK0 } CLOSE { }
+                 { $<ctxt>$ = start_element(ELT_SUBN_RIN,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(RIN, $<ctxt>$)             
+                 }             
+                 no_std_subs             
+                 { CHECK0 }             
+                 CLOSE             
+                 { end_element(ELT_SUBN_RIN, PARENT, $<ctxt>5, NULL);
+                }
                ;
 
 /*********************************************************************/
@@ -1470,22 +1652,58 @@ subm_sub   : subm_name_sect  { OCCUR2(NAME, 0, 1) }
 
 /* SUBM.NAME */
 subm_name_sect : OPEN DELIM TAG_NAME mand_line_item             
-                 { START(NAME, NULL) } no_std_subs { CHECK0 } CLOSE { }
+                 { $<ctxt>$ = start_element(ELT_SUBM_NAME,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(NAME, $<ctxt>$)              
+                 }              
+                 no_std_subs              
+                 { CHECK0 }              
+                 CLOSE              
+                 { end_element(ELT_SUBM_NAME, PARENT, $<ctxt>5, NULL);
+                }
                ;
 
 /* SUBM.LANG */
 subm_lang_sect : OPEN DELIM TAG_LANG mand_line_item             
-                 { START(LANG, NULL) } no_std_subs { CHECK0 } CLOSE { }
+                 { $<ctxt>$ = start_element(ELT_SUBM_LANG,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(LANG, $<ctxt>$)              
+                 }              
+                 no_std_subs              
+                 { CHECK0 }              
+                 CLOSE              
+                 { end_element(ELT_SUBM_LANG, PARENT, $<ctxt>5, NULL);
+                }
                ;
 
 /* SUBM.RFN */
 subm_rfn_sect  : OPEN DELIM TAG_RFN mand_line_item             
-                 { START(RFN, NULL) } no_std_subs { CHECK0 } CLOSE { }
+                 { $<ctxt>$ = start_element(ELT_SUBM_RFN,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(RFN, $<ctxt>$)              
+                 }              
+                 no_std_subs              
+                 { CHECK0 }              
+                 CLOSE              
+                 { end_element(ELT_SUBM_RFN, PARENT, $<ctxt>5, NULL);
+                }
                ;
 
 /* SUBM.RIN */
 subm_rin_sect  : OPEN DELIM TAG_RIN mand_line_item             
-                 { START(RIN, NULL) } no_std_subs { CHECK0 } CLOSE { }
+                 { $<ctxt>$ = start_element(ELT_SUBM_RIN,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(RIN, $<ctxt>$)              
+                 }              
+                 no_std_subs              
+                 { CHECK0 }              
+                 CLOSE              
+                 { end_element(ELT_SUBM_RIN, PARENT, $<ctxt>5, NULL);
+                }
                ;
 
 /*********************************************************************/
@@ -1498,10 +1716,16 @@ addr_struc_sub : addr_sect { OCCUR2(ADDR, 0, 1) }
                ;
 
 addr_sect   : OPEN DELIM TAG_ADDR mand_line_item 
-              { START(ADDR, NULL) }
+              { $<ctxt>$ = start_element(ELT_SUB_ADDR,
+                                        PARENT, $1, $3, $4, 
+                                        GEDCOM_MAKE_STRING($4));
+               START(ADDR, $<ctxt>$)  
+              }
               addr_subs
              { CHECK0 }
-              CLOSE { }
+              CLOSE  
+              { end_element(ELT_SUB_ADDR, PARENT, $<ctxt>5, NULL);
+             }
             ;
 
 addr_subs   : /* empty */
@@ -1519,29 +1743,101 @@ addr_sub    : addr_cont_sect  /* 0:M */
             ;
 
 addr_cont_sect : OPEN DELIM TAG_CONT mand_line_item              
-                 { START(CONT, NULL) } no_std_subs { CHECK0 } CLOSE { }
+                 { $<ctxt>$ = start_element(ELT_SUB_ADDR_CONT,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(CONT, $<ctxt>$)               
+                 }               
+                 no_std_subs               
+                 { CHECK0 }               
+                 CLOSE               
+                 { end_element(ELT_SUB_ADDR_CONT, PARENT, $<ctxt>5, NULL);
+                }
                ;
 addr_adr1_sect : OPEN DELIM TAG_ADR1 mand_line_item              
-                 { START(ADR1, NULL) } no_std_subs { CHECK0 } CLOSE { }
+                 { $<ctxt>$ = start_element(ELT_SUB_ADDR_ADR1,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(ADR1, $<ctxt>$)               
+                 }               
+                 no_std_subs               
+                 { CHECK0 }               
+                 CLOSE               
+                 { end_element(ELT_SUB_ADDR_ADR1, PARENT, $<ctxt>5, NULL);
+                }
                ;
 addr_adr2_sect : OPEN DELIM TAG_ADR2 mand_line_item              
-                 { START(ADR2, NULL) } no_std_subs { CHECK0 } CLOSE { }
+                 { $<ctxt>$ = start_element(ELT_SUB_ADDR_ADR2,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(ADR2, $<ctxt>$)               
+                 }               
+                 no_std_subs               
+                 { CHECK0 }               
+                 CLOSE               
+                 { end_element(ELT_SUB_ADDR_ADR2, PARENT, $<ctxt>5, NULL);
+                }
                ;
 addr_city_sect : OPEN DELIM TAG_CITY mand_line_item              
-                 { START(CITY, NULL) } no_std_subs { CHECK0 } CLOSE { }
+                 { $<ctxt>$ = start_element(ELT_SUB_ADDR_CITY,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(CITY, $<ctxt>$)               
+                 }               
+                 no_std_subs               
+                 { CHECK0 }               
+                 CLOSE               
+                 { end_element(ELT_SUB_ADDR_CITY, PARENT, $<ctxt>5, NULL);
+                }
                ;
 addr_stae_sect : OPEN DELIM TAG_STAE mand_line_item              
-                 { START(STAE, NULL) } no_std_subs { CHECK0 } CLOSE { }
+                 { $<ctxt>$ = start_element(ELT_SUB_ADDR_STAE,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(STAE, $<ctxt>$)               
+                 }               
+                 no_std_subs               
+                 { CHECK0 }               
+                 CLOSE               
+                 { end_element(ELT_SUB_ADDR_STAE, PARENT, $<ctxt>5, NULL);
+                }
                ;
 addr_post_sect : OPEN DELIM TAG_POST mand_line_item              
-                 { START(POST, NULL) } no_std_subs { CHECK0 } CLOSE { }
+                 { $<ctxt>$ = start_element(ELT_SUB_ADDR_POST,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(POST, $<ctxt>$)               
+                 }               
+                 no_std_subs               
+                 { CHECK0 }               
+                 CLOSE               
+                 { end_element(ELT_SUB_ADDR_POST, PARENT, $<ctxt>5, NULL);
+                }
                ;
 addr_ctry_sect : OPEN DELIM TAG_CTRY mand_line_item              
-                 { START(CTRY, NULL) } no_std_subs { CHECK0 } CLOSE { }
+                 { $<ctxt>$ = start_element(ELT_SUB_ADDR_CTRY,
+                                           PARENT, $1, $3, $4, 
+                                           GEDCOM_MAKE_STRING($4));
+                  START(CTRY, $<ctxt>$)               
+                 }               
+                 no_std_subs               
+                 { CHECK0 }               
+                 CLOSE               
+                 { end_element(ELT_SUB_ADDR_CTRY, PARENT, $<ctxt>5, NULL);
+                }
                ;
 
 phon_sect   : OPEN DELIM TAG_PHON mand_line_item              
-              { START(PHON, NULL) } no_std_subs { CHECK0 } CLOSE { }
+              { $<ctxt>$ = start_element(ELT_SUB_PHON,
+                                        PARENT, $1, $3, $4, 
+                                        GEDCOM_MAKE_STRING($4));
+               START(PHON, $<ctxt>$)               
+              }               
+              no_std_subs               
+              { CHECK0 }               
+              CLOSE               
+              { end_element(ELT_SUB_PHON, PARENT, $<ctxt>5, NULL);
+             }
             ;
 
 /* ASSOCIATION STRUCTURE */
@@ -2435,7 +2731,8 @@ user_sect   : OPEN DELIM opt_xref USERTAG
                }
              }
               opt_value
-              { $<ctxt>$ = start_element(ELT_USER, PARENT, $1, $4, $6, $6);
+              { $<ctxt>$ = start_element(ELT_USER, PARENT, $1, $4, $6,  
+                                        GEDCOM_MAKE_STRING($6));
                START($4, $<ctxt>$);
              }
              user_sects
diff --git a/gedcom/gedcom_date.lex b/gedcom/gedcom_date.lex
new file mode 100644 (file)
index 0000000..5767768
--- /dev/null
@@ -0,0 +1,139 @@
+/* Lexer for Gedcom dates
+   Copyright (C) 2001 The Genes Development Team
+   This file is part of the Gedcom parser library.
+   Contributed by Peter Verthez <Peter.Verthez@advalvas.be>, 2001.
+
+   The Gedcom parser library is free software; you can redistribute it
+   and/or modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The Gedcom parser library is distributed in the hope that it will be
+   useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the Gedcom parser library; if not, write to the
+   Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* $Id$ */
+/* $Name$ */
+
+%{
+#include "date.h"
+#include "gedcom_date.tab.h"
+  
+#define YY_NO_UNPUT
+
+static char buf[MAX_DATE_TOKEN][MAX_PHRASE_LEN+1];
+static int token_nr = 0; 
+%}
+
+%option case-insensitive
+%s PHRASE
+
+%%
+
+%{
+
+#define SIMPLE_RETURN(TOKEN) \
+  { if (token_nr >= MAX_DATE_TOKEN) { \
+      gedcom_date_error(_("Date token stack overflow")); \
+      return BADTOKEN; \
+    } \
+    memset(buf[token_nr], 0, MAX_PHRASE_LEN+1); \
+    strncpy(buf[token_nr], yytext, yyleng); \
+    gedcom_date_lval.string = buf[token_nr++]; \
+    return TOKEN; \
+  }
+%}
+
+[ \t]+          /* ignore whitespace between tokens */
+
+@#DGREGORIAN@   SIMPLE_RETURN(ESC_DATE_GREG)
+@#DJULIAN@      SIMPLE_RETURN(ESC_DATE_JULN)
+@#DHEBREW@      SIMPLE_RETURN(ESC_DATE_HEBR)
+"@#DFRENCH R@"  SIMPLE_RETURN(ESC_DATE_FREN)
+     
+FROM            SIMPLE_RETURN(MOD_FROM)
+TO              SIMPLE_RETURN(MOD_TO)  
+BEF             SIMPLE_RETURN(MOD_BEF) 
+AFT             SIMPLE_RETURN(MOD_AFT) 
+BET             SIMPLE_RETURN(MOD_BET) 
+AND             SIMPLE_RETURN(MOD_AND) 
+ABT             SIMPLE_RETURN(MOD_ABT) 
+CAL             SIMPLE_RETURN(MOD_CAL) 
+EST             SIMPLE_RETURN(MOD_EST) 
+INT             SIMPLE_RETURN(MOD_INT)
+     
+JAN             SIMPLE_RETURN(MON_JAN) 
+FEB             SIMPLE_RETURN(MON_FEB) 
+MAR             SIMPLE_RETURN(MON_MAR) 
+APR             SIMPLE_RETURN(MON_APR) 
+MAY             SIMPLE_RETURN(MON_MAY) 
+JUN             SIMPLE_RETURN(MON_JUN) 
+JUL             SIMPLE_RETURN(MON_JUL) 
+AUG             SIMPLE_RETURN(MON_AUG) 
+SEP             SIMPLE_RETURN(MON_SEP) 
+OCT             SIMPLE_RETURN(MON_OCT) 
+NOV             SIMPLE_RETURN(MON_NOV) 
+DEC             SIMPLE_RETURN(MON_DEC) 
+TSH             SIMPLE_RETURN(MON_TSH) 
+CSH             SIMPLE_RETURN(MON_CSH) 
+KSL             SIMPLE_RETURN(MON_KSL) 
+TVT             SIMPLE_RETURN(MON_TVT) 
+SHV             SIMPLE_RETURN(MON_SHV) 
+ADR             SIMPLE_RETURN(MON_ADR) 
+ADS             SIMPLE_RETURN(MON_ADS) 
+NSN             SIMPLE_RETURN(MON_NSN) 
+IYR             SIMPLE_RETURN(MON_IYR) 
+SVN             SIMPLE_RETURN(MON_SVN) 
+TMZ             SIMPLE_RETURN(MON_TMZ) 
+AAV             SIMPLE_RETURN(MON_AAV) 
+ELL             SIMPLE_RETURN(MON_ELL) 
+VEND            SIMPLE_RETURN(MON_VEND)
+BRUM            SIMPLE_RETURN(MON_BRUM)
+FRIM            SIMPLE_RETURN(MON_FRIM)
+NIVO            SIMPLE_RETURN(MON_NIVO)
+PLUV            SIMPLE_RETURN(MON_PLUV)
+VENT            SIMPLE_RETURN(MON_VENT)
+GERM            SIMPLE_RETURN(MON_GERM)
+FLOR            SIMPLE_RETURN(MON_FLOR)
+PRAI            SIMPLE_RETURN(MON_PRAI)
+MESS            SIMPLE_RETURN(MON_MESS)
+THER            SIMPLE_RETURN(MON_THER)
+FRUC            SIMPLE_RETURN(MON_FRUC)
+COMP            SIMPLE_RETURN(MON_COMP)
+
+"("             { BEGIN(PHRASE);
+                  SIMPLE_RETURN(OPEN); 
+                }
+<PHRASE>[^\)]*  SIMPLE_RETURN(TEXT);
+<PHRASE>")"     { BEGIN(INITIAL); 
+                  SIMPLE_RETURN(CLOSE);
+                }
+     
+"/"             SIMPLE_RETURN(SLASH)
+[0-9]+          SIMPLE_RETURN(NUMBER)
+
+%%
+
+int yywrap()
+{
+  return 1;
+}
+
+static YY_BUFFER_STATE hndl;
+
+void init_gedcom_date_lex(char* string)
+{
+  token_nr = 0;
+  hndl = yy_scan_string(string);
+}
+
+void close_gedcom_date_lex()
+{
+  yy_delete_buffer(hndl);
+}
diff --git a/gedcom/gedcom_date.y b/gedcom/gedcom_date.y
new file mode 100644 (file)
index 0000000..60b1016
--- /dev/null
@@ -0,0 +1,312 @@
+/* Parser for Gedcom dates.
+   Copyright (C) 2001 The Genes Development Team
+   This file is part of the Gedcom parser library.
+   Contributed by Peter Verthez <Peter.Verthez@advalvas.be>, 2001.
+
+   The Gedcom parser library is free software; you can redistribute it
+   and/or modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The Gedcom parser library is distributed in the hope that it will be
+   useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the Gedcom parser library; if not, write to the
+   Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* $Id$ */
+/* $Name$ */
+
+%{
+#include <stdlib.h>
+#include "date.h"
+%}
+
+%union {
+  char *string;
+  struct date_value date_val;
+  struct date date;
+}
+
+%token <string> ESC_DATE_GREG
+%token <string> ESC_DATE_JULN
+%token <string> ESC_DATE_HEBR
+%token <string> ESC_DATE_FREN
+%token <string> MOD_FROM
+%token <string> MOD_TO
+%token <string> MOD_BEF
+%token <string> MOD_AFT
+%token <string> MOD_BET
+%token <string> MOD_AND
+%token <string> MOD_ABT
+%token <string> MOD_CAL
+%token <string> MOD_EST
+%token <string> MOD_INT
+%token <string> MON_JAN
+%token <string> MON_FEB
+%token <string> MON_MAR
+%token <string> MON_APR
+%token <string> MON_MAY
+%token <string> MON_JUN
+%token <string> MON_JUL
+%token <string> MON_AUG
+%token <string> MON_SEP
+%token <string> MON_OCT
+%token <string> MON_NOV
+%token <string> MON_DEC
+%token <string> MON_TSH
+%token <string> MON_CSH
+%token <string> MON_KSL
+%token <string> MON_TVT
+%token <string> MON_SHV
+%token <string> MON_ADR
+%token <string> MON_ADS
+%token <string> MON_NSN
+%token <string> MON_IYR
+%token <string> MON_SVN
+%token <string> MON_TMZ
+%token <string> MON_AAV
+%token <string> MON_ELL
+%token <string> MON_VEND
+%token <string> MON_BRUM
+%token <string> MON_FRIM
+%token <string> MON_NIVO
+%token <string> MON_PLUV
+%token <string> MON_VENT
+%token <string> MON_GERM
+%token <string> MON_FLOR
+%token <string> MON_PRAI
+%token <string> MON_MESS
+%token <string> MON_THER
+%token <string> MON_FRUC
+%token <string> MON_COMP
+%token <string> OPEN
+%token <string> CLOSE
+%token <string> TEXT
+%token <string> NUMBER
+%token <string> SLASH
+%token <string> BADTOKEN
+
+%type <date_val> date_value
+%type <date_val> date_period
+%type <date_val> date_range
+%type <date_val> date_approx
+%type <date_val> date_interpr
+%type <string> date_phrase
+%type <date> date
+
+%%
+
+date_value   : date           { make_date_value(DV_NO_MODIFIER,
+                                               $1, def_date, ""); }
+             | date_period    
+             | date_range
+             | date_approx
+             | date_interpr
+             | date_phrase    { make_date_value(DV_PHRASE,
+                                               def_date, def_date, $1); }
+             ;
+
+date         : ESC_DATE_GREG date_greg { copy_date(&$$, date_s);
+                                         $$.cal = CAL_GREGORIAN; }
+             | ESC_DATE_JULN date_juln { copy_date(&$$, date_s);
+                                         $$.cal = CAL_JULIAN;  }
+             | ESC_DATE_HEBR date_hebr { copy_date(&$$, date_s);
+                                         $$.cal = CAL_HEBREW;  }
+             | ESC_DATE_FREN date_fren { copy_date(&$$, date_s);
+                                         $$.cal = CAL_FRENCH_REV;  }
+             | date_greg               { copy_date(&$$, date_s);
+                                         $$.cal = CAL_GREGORIAN;  }
+             ;
+
+date_period  : MOD_FROM date   { make_date_value(DV_FROM,
+                                                $2, def_date, ""); }
+             | MOD_TO date     { make_date_value(DV_TO,
+                                                $2, def_date, ""); }
+             | MOD_FROM date   { copy_date(&$<date>$, $2); }
+              MOD_TO date
+                      { make_date_value(DV_FROM_TO, $<date>3, $5, ""); }
+             ;
+
+date_range   : MOD_BEF date    { make_date_value(DV_BEFORE,
+                                                $2, def_date, ""); }
+             | MOD_AFT date    { make_date_value(DV_AFTER,
+                                                $2, def_date, ""); }
+             | MOD_BET date    { copy_date(&$<date>$, $2); }
+              MOD_AND date
+                      { make_date_value(DV_BETWEEN, $<date>3, $5, ""); }
+             ;
+
+date_approx  : MOD_ABT date    { make_date_value(DV_ABOUT,
+                                                $2, def_date, ""); }
+             | MOD_CAL date    { make_date_value(DV_CALCULATED,
+                                                $2, def_date, ""); }
+             | MOD_EST date    { make_date_value(DV_ESTIMATED,
+                                                $2, def_date, ""); }
+             ;
+
+date_interpr : MOD_INT date date_phrase
+                 { make_date_value(DV_INTERPRETED, $2, def_date, $3); }
+             ;
+
+date_phrase  : OPEN TEXT CLOSE { $$ = $2; }
+             ;
+
+date_greg    : day month_greg year_greg
+             | month_greg year_greg
+             | year_greg
+             ;
+
+date_juln    : day month_greg year
+             | month_greg year
+             | year
+             ;
+
+date_hebr    : day month_hebr year
+             | month_hebr year
+             | year
+             ;
+
+date_fren    : day month_fren year
+             | month_fren year
+             | year
+             ;
+
+day          : NUMBER
+               {
+                if (strlen($1) <= MAX_DAY_LEN) {
+                  strcpy(date_s.day_str, $1);
+                  date_s.day = atoi($1);
+                }
+                else {
+                  gedcom_date_error(_("Too many characters in day '%s'"),
+                                    $1); 
+                }
+              }
+             ;
+
+month_greg   : MON_JAN { strcpy(date_s.month_str, $1);
+                         date_s.month = 1; }
+             | MON_FEB { strcpy(date_s.month_str, $1);
+                         date_s.month = 2; }
+             | MON_MAR { strcpy(date_s.month_str, $1);
+                         date_s.month = 3; }
+             | MON_APR { strcpy(date_s.month_str, $1);
+                         date_s.month = 4; }
+             | MON_MAY { strcpy(date_s.month_str, $1);
+                         date_s.month = 5; }
+             | MON_JUN { strcpy(date_s.month_str, $1);
+                         date_s.month = 6; }
+             | MON_JUL { strcpy(date_s.month_str, $1);
+                         date_s.month = 7; }
+             | MON_AUG { strcpy(date_s.month_str, $1);
+                         date_s.month = 8; }
+             | MON_SEP { strcpy(date_s.month_str, $1);
+                         date_s.month = 9; }
+             | MON_OCT { strcpy(date_s.month_str, $1);
+                         date_s.month = 10; }
+             | MON_NOV { strcpy(date_s.month_str, $1);
+                         date_s.month = 11; }
+             | MON_DEC { strcpy(date_s.month_str, $1);
+                         date_s.month = 12; }
+             ;
+
+month_hebr   : MON_TSH { strcpy(date_s.month_str, $1);
+                         date_s.month = 1; }
+             | MON_CSH { strcpy(date_s.month_str, $1);
+                         date_s.month = 2; }
+             | MON_KSL { strcpy(date_s.month_str, $1);
+                         date_s.month = 3; }
+             | MON_TVT { strcpy(date_s.month_str, $1);
+                         date_s.month = 4; }
+             | MON_SHV { strcpy(date_s.month_str, $1);
+                         date_s.month = 5; }
+             | MON_ADR { strcpy(date_s.month_str, $1);
+                         date_s.month = 6; }
+             | MON_ADS { strcpy(date_s.month_str, $1);
+                         date_s.month = 7; }
+             | MON_NSN { strcpy(date_s.month_str, $1);
+                         date_s.month = 8; }
+             | MON_IYR { strcpy(date_s.month_str, $1);
+                         date_s.month = 9; }
+             | MON_SVN { strcpy(date_s.month_str, $1);
+                         date_s.month = 10; }
+             | MON_TMZ { strcpy(date_s.month_str, $1);
+                         date_s.month = 11; }
+             | MON_AAV { strcpy(date_s.month_str, $1);
+                         date_s.month = 12; }
+             | MON_ELL { strcpy(date_s.month_str, $1);
+                         date_s.month = 13; }
+             ;
+
+month_fren   : MON_VEND { strcpy(date_s.month_str, $1);
+                         date_s.month = 1; }
+             | MON_BRUM { strcpy(date_s.month_str, $1);
+                         date_s.month = 2; }
+             | MON_FRIM { strcpy(date_s.month_str, $1);
+                         date_s.month = 3; }
+             | MON_NIVO { strcpy(date_s.month_str, $1);
+                         date_s.month = 4; }
+             | MON_PLUV { strcpy(date_s.month_str, $1);
+                         date_s.month = 5; }
+             | MON_VENT { strcpy(date_s.month_str, $1);
+                         date_s.month = 6; }
+             | MON_GERM { strcpy(date_s.month_str, $1);
+                         date_s.month = 7; }
+             | MON_FLOR { strcpy(date_s.month_str, $1);
+                         date_s.month = 8; }
+             | MON_PRAI { strcpy(date_s.month_str, $1);
+                         date_s.month = 9; }
+             | MON_MESS { strcpy(date_s.month_str, $1);
+                         date_s.month = 10; }
+             | MON_THER { strcpy(date_s.month_str, $1);
+                         date_s.month = 11; }
+             | MON_FRUC { strcpy(date_s.month_str, $1);
+                         date_s.month = 12; }
+             | MON_COMP { strcpy(date_s.month_str, $1);
+                         date_s.month = 13; }
+             ;
+
+year         : NUMBER
+                 { if (strlen($1) <= MAX_YEAR_LEN) {
+                    strcpy(date_s.year_str, $1);
+                    date_s.year = atoi($1);
+                    date_s.year_type = YEAR_SINGLE;
+                  }
+                  else {
+                    gedcom_date_error(_("Too many characters in year '%s'"),
+                                    $1); 
+                  }
+                }
+             ;
+
+year_greg    : NUMBER
+                 { if (strlen($1) <= MAX_YEAR_LEN) {
+                    strcpy(date_s.year_str, $1);
+                    date_s.year = atoi($1);
+                    date_s.year_type = YEAR_SINGLE;
+                  }
+                  else {
+                    gedcom_date_error(_("Too many characters in year '%s'"),
+                                    $1); 
+                  }
+                }
+             | NUMBER SLASH NUMBER
+                 { if (strlen($1) + strlen($3) + 1 <= MAX_YEAR_LEN) {
+                    sprintf(date_s.year_str, "%s/%s", $1, $3);
+                    date_s.year = atoi($1) + 1;
+                    date_s.year_type = YEAR_DOUBLE;
+                  }
+                  else {
+                    gedcom_date_error(_("Too many characters in year '%s/%s'"),
+                                    $1, $3); 
+                  }
+                
+                }
+             ;
+
+%%
index ec156bda512355d2720107c970e14588a0294eab..5f7ceee13c06398cf0b90d399490155ecccb8548 100644 (file)
@@ -89,3 +89,7 @@ void end_element(Gedcom_elt elt, Gedcom_ctxt parent, Gedcom_ctxt self,
     (*cb)(parent, self, parsed_value);
 }
 
+void gedcom_cast_error(char* file, int line)
+{
+  gedcom_warning(_("Wrong cast of value in file %s, at line %d"), file, line);
+}
index 7b73dbfdc08d676c31d88e60f5acf30aa0467079..7e4474860211c3e00cdd381c82fdaae80ff68dc8 100644 (file)
@@ -35,5 +35,16 @@ Gedcom_ctxt start_element(Gedcom_elt elt, Gedcom_ctxt parent,
 void        end_element(Gedcom_elt elt, Gedcom_ctxt parent, Gedcom_ctxt self,
                        Gedcom_val parsed_value);
 
+extern Gedcom_val_struct val;
+
+#define GEDCOM_MAKE(VALUE, TYPE, MEMBER) \
+   (val.type = TYPE, val.value.MEMBER = VALUE, &val)
+
+#define GEDCOM_MAKE_STRING(STRING) \
+   GEDCOM_MAKE(STRING, GV_CHAR_PTR, string_val)
+
+#define GEDCOM_MAKE_DATE(DATE) \
+   GEDCOM_MAKE(DATE, GV_DATE_VALUE, date_val)
+
 
 #endif /* __INTERFACE_H */