Tag names are now auto-generated.
[gedcom-parse.git] / gedcom / date.c
index c145f213d3fe9a6c6911e1980c9b891025b5bc93..e866c809cc9441cc1434fea5ff2b242dbc02541a 100644 (file)
@@ -1,5 +1,5 @@
 /* Date manipulation routines.
-   Copyright (C) 2001 The Genes Development Team
+   Copyright (C) 2001,2002 The Genes Development Team
    This file is part of the Gedcom parser library.
    Contributed by Peter Verthez <Peter.Verthez@advalvas.be>, 2001.
 
@@ -21,9 +21,9 @@
 /* $Id$ */
 /* $Name$ */
 
-#include <stdio.h>
 #include "gedcom_internal.h"
 #include "sdncal.h"
+#include "buffer.h"
 #include "date.h"
 
 struct date_value dv_s;
@@ -32,6 +32,16 @@ struct date date_s;
 struct date_value def_date_val;
 struct date def_date;
 
+const char* curr_line_value;
+
+void cleanup_date_buffer();
+struct safe_buffer date_buffer = { NULL, 0, NULL, 0, cleanup_date_buffer };
+
+void cleanup_date_buffer()
+{
+  cleanup_buffer(&date_buffer);
+}
+
 int max_month[] = { 12,  /* CAL_GREGORIAN */
                    12,  /* CAL_JULIAN */
                    13,  /* CAL_HEBREW */
@@ -39,6 +49,14 @@ int max_month[] = { 12,  /* CAL_GREGORIAN */
                    0    /* CAL_UNKNOWN */
                   };
 
+typedef long int (*cal_func_type) (int, int, int);
+
+cal_func_type cal_func[] = { &GregorianToSdn,   /* CAL_GREGORIAN */
+                            &JulianToSdn,      /* CAL_JULIAN */
+                            &JewishToSdn,      /* CAL_JEWISH */
+                            &FrenchToSdn       /* CAL_FRENCH_REV */
+                           };
+
 void copy_date(struct date *to, struct date from)
 {
   memcpy(to, &from, sizeof(struct date));
@@ -60,7 +78,7 @@ void init_date(struct date *d)
 }
 
 struct date_value make_date_value(Date_value_type t, struct date d1,
-                                 struct date d2, char* p)
+                                 struct date d2, const char* p)
 {
   dv_s.type = t;
   copy_date(&dv_s.date1, d1);
@@ -75,6 +93,7 @@ void make_date_complete(struct date *d)
     d->type = DATE_UNRECOGNIZED;
   else {
     struct date end_date;
+    cal_func_type to_sdn;
     if (d->day == -1 || d->month == -1 || d->year == -1) {
       d->type = DATE_BOUNDED;
       copy_date(&end_date, *d);
@@ -95,42 +114,21 @@ void make_date_complete(struct date *d)
     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;
-      }
+
+    to_sdn = cal_func[d->cal];
+    d->sdn1 = (*to_sdn)(d->year, d->month, d->day);
+    if (d->type == DATE_BOUNDED) {
+      d->sdn2 = (*to_sdn)(end_date.year, end_date.month, end_date.day);
+      d->sdn2 -= 1;
     }
   }
 }
 
-struct date_value gedcom_parse_date(char* line_value)
+struct date_value gedcom_parse_date(const char* line_value)
 {
   init_date(&date_s);
   init_date(&def_date);
+  curr_line_value = line_value;
   init_gedcom_date_lex(line_value);
   gedcom_date_parse();
   close_gedcom_date_lex();
@@ -139,3 +137,75 @@ struct date_value gedcom_parse_date(char* line_value)
   return dv_s;
 }
 
+void add_date(struct date* d)
+{
+  switch (d->cal) {
+    case CAL_GREGORIAN: break;
+    case CAL_JULIAN:
+      safe_buf_append(&date_buffer, "@#DJULIAN@ "); break;
+    case CAL_HEBREW:
+      safe_buf_append(&date_buffer, "@#DHEBREW@ "); break;
+    case CAL_FRENCH_REV:
+      safe_buf_append(&date_buffer, "@#DFRENCH R@ "); break;
+    case CAL_UNKNOWN:
+      safe_buf_append(&date_buffer, "@#DUNKNOWN@ "); break;
+    default:
+      break;
+  }
+  if (d->day_str[0])
+    safe_buf_append(&date_buffer, "%s ", d->day_str);
+  if (d->month_str[0])
+    safe_buf_append(&date_buffer, "%s ", d->month_str);
+  safe_buf_append(&date_buffer, "%s", d->year_str);
+}
+
+char* gedcom_date_to_string(struct date_value* val)
+{
+  reset_buffer(&date_buffer);
+  
+  switch (val->type) {
+    case DV_NO_MODIFIER:
+      add_date(&val->date1); break;
+    case DV_BEFORE:
+      safe_buf_append(&date_buffer, "BEF ");
+      add_date(&val->date1); break;
+    case DV_AFTER:
+      safe_buf_append(&date_buffer, "AFT ");
+      add_date(&val->date1); break;
+    case DV_BETWEEN:
+      safe_buf_append(&date_buffer, "BET ");
+      add_date(&val->date1);
+      safe_buf_append(&date_buffer, " AND ");
+      add_date(&val->date2); break;
+    case DV_FROM:
+      safe_buf_append(&date_buffer, "FROM ");
+      add_date(&val->date1); break;
+    case DV_TO:
+      safe_buf_append(&date_buffer, "TO ");
+      add_date(&val->date1); break;
+    case DV_FROM_TO:
+      safe_buf_append(&date_buffer, "FROM ");
+      add_date(&val->date1);
+      safe_buf_append(&date_buffer, " TO ");
+      add_date(&val->date2); break;
+    case DV_ABOUT:
+      safe_buf_append(&date_buffer, "ABT ");
+      add_date(&val->date1); break;
+    case DV_CALCULATED:
+      safe_buf_append(&date_buffer, "CAL ");
+      add_date(&val->date1); break;
+    case DV_ESTIMATED:
+      safe_buf_append(&date_buffer, "EST ");
+      add_date(&val->date1); break;
+    case DV_INTERPRETED:
+      safe_buf_append(&date_buffer, "INT ");
+      add_date(&val->date1);
+      safe_buf_append(&date_buffer, " (%s)", val->phrase); break;
+    case DV_PHRASE:
+      safe_buf_append(&date_buffer, "(%s)", val->phrase); break;
+    default:
+      break;
+  }
+  
+  return get_buf_string(&date_buffer);
+}