Support for the date handling functions.
authorPeter Verthez <Peter.Verthez@advalvas.be>
Sat, 21 Dec 2002 15:35:25 +0000 (15:35 +0000)
committerPeter Verthez <Peter.Verthez@advalvas.be>
Sat, 21 Dec 2002 15:35:25 +0000 (15:35 +0000)
gedcom/date.h
gedcom/gedcom_date.lex
gedcom/gedcom_date.y

index e7e82cad682945df0bdf8ef48e0375e85d829fa1..ccf5a7fb3963fa1c33c26ee648101ca1cf1711be 100644 (file)
@@ -39,6 +39,13 @@ extern const char* curr_line_value;
 int               gedcom_date_parse();
 int               gedcom_date_lex();
 
+int get_date_token(const char* input);
+int get_year_tokens(const char* str, char** year1, char** year2);
+
+int get_day_num(const char* input);
+int get_month_num(Calendar_type cal, const char* input);
+int get_year_num(const char* input, Year_type* ytype);
+
 /* These are defined in gedcom_date.lex */
 void              init_gedcom_date_lex(const char* string);
 void              close_gedcom_date_lex();
index 50daf3f876f013c12ea9175fbfb4591aec1d8934..bba60ef5f4f15f36bca44e3bc025dd2f6a74a579 100644 (file)
@@ -133,6 +133,55 @@ COMP            SIMPLE_RETURN(MON_COMP)
 
 %%
 
+int get_date_token(const char* str)
+{
+  int token;
+  YY_BUFFER_STATE buffer;
+
+  token_nr = 0;
+  yy_delete_buffer(YY_CURRENT_BUFFER);
+  buffer = yy_scan_string(str);
+  token = yylex();
+  yy_delete_buffer(buffer);
+  return token;
+}
+
+int get_year_tokens(const char* str, char** year1, char** year2)
+{
+  int token;
+  YY_BUFFER_STATE buffer;
+
+  token_nr = 0;
+  yy_delete_buffer(YY_CURRENT_BUFFER);
+  buffer = yy_scan_string(str);
+
+  token = yylex();
+  switch (token) {
+    case NUMBER: {
+      *year1 = buf[token_nr - 1];
+      token  = yylex();
+      switch (token) {
+       case SLASH: {
+         token = yylex();
+         switch (token) {
+           case NUMBER: {
+             *year2 = buf[token_nr - 1];
+             return 2;
+           }
+           default:  return 0;
+         }
+         break;
+       }
+       case 0:   return 1;
+       default:  return 0;
+      }
+      break;
+    }
+    case 0:   return 0;
+    default:  return 0;
+  }
+}
+
 int yywrap()
 {
   return 1;
index 1ba65fa4698b42797403162667123129f47399c0..11c5c0d2a43185cfeed7afc5570d8884c9f91ef9 100644 (file)
 %{
 #include <stdlib.h>
 #include "date.h"
+
+int _get_day_num(const char* input);
+int _get_year_num(Year_type ytype, const char* input1, const char* input2);
+  
 %}
 
 %union {
@@ -191,13 +195,10 @@ date_fren    : day month_fren year
 
 day          : NUMBER
                {
-                if (strlen($1) <= MAX_DAY_LEN) {
+                int d = _get_day_num($1);
+                if (d != -1) {
                   strcpy(date_s.day_str, $1);
-                  date_s.day = atoi($1);
-                }
-                else {
-                  gedcom_date_error(_("Too many characters in day '%s'"),
-                                    $1); 
+                  date_s.day = d;
                 }
               }
              ;
@@ -285,41 +286,115 @@ month_fren   : MON_VEND { strcpy(date_s.month_str, $1);
              ;
 
 year         : NUMBER
-                 { if (strlen($1) <= MAX_YEAR_LEN) {
+                 { int y = _get_year_num(YEAR_SINGLE, $1, NULL);
+                  if (y != -1) {
                     strcpy(date_s.year_str, $1);
-                    date_s.year = atoi($1);
+                    date_s.year = y;
                     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) {
+                 { int y = _get_year_num(YEAR_SINGLE, $1, NULL);
+                  if (y != -1) {
                     strcpy(date_s.year_str, $1);
-                    date_s.year = atoi($1);
+                    date_s.year = y;
                     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) {
+                 { int y = _get_year_num(YEAR_DOUBLE, $1, $3);
+                  if (y != 1) {
                     sprintf(date_s.year_str, "%s/%s", $1, $3);
-                    date_s.year = atoi($1) + 1;
+                    date_s.year = y;
                     date_s.year_type = YEAR_DOUBLE;
                   }
-                  else {
-                    gedcom_date_error(_("Too many characters in year '%s/%s'"),
-                                    $1, $3); 
-                  }
-                
                 }
              ;
 
 %%
+
+int _get_day_num(const char* input)
+{
+  if (strlen(input) <= MAX_DAY_LEN)
+    return atoi(input);
+  else {
+    gedcom_date_error(_("Too many characters in day '%s'"), input);
+    return -1;
+  }
+}
+
+int get_day_num(const char* input)
+{
+  int token = get_date_token(input);
+  if (token == NUMBER)
+    return _get_day_num(input);
+  else {
+    gedcom_date_error(_("Not a valid day number: '%s'"), input);
+    return -1;
+  }
+}
+
+int begin_month[] =
+{ /* CAL_GREGORIAN */   MON_JAN,
+  /* CAL_JULIAN */      MON_JAN,
+  /* CAL_HEBREW */      MON_TSH,
+  /* CAL_FRENCH_REV */  MON_VEND
+};
+
+int end_month[] =
+{ /* CAL_GREGORIAN */   MON_DEC,
+  /* CAL_JULIAN */      MON_DEC,
+  /* CAL_HEBREW */      MON_ELL,
+  /* CAL_FRENCH_REV */  MON_COMP
+};
+
+int get_month_num(Calendar_type cal, const char* input)
+{
+  int token = get_date_token(input);
+  if (token >= begin_month[cal] && token <= end_month[cal])
+    return token - begin_month[cal] + 1;
+  else {
+    gedcom_date_error(_("Not a valid month for the given calendar: '%s'"),
+                     input);
+    return -1;
+  }
+}
+
+int _get_year_num(Year_type ytype, const char* input1, const char* input2)
+{
+  if (ytype == YEAR_SINGLE) {
+    if (strlen(input1) <= MAX_YEAR_LEN) {
+      return atoi(input1);
+    }
+    else {
+      gedcom_date_error(_("Too many characters in year '%s'"), input1);
+      return -1;
+    }
+  }
+  else {
+    if (strlen(input1) + strlen(input2) + 1 <= MAX_YEAR_LEN) {
+      return atoi(input1) + 1;
+    }
+    else {
+      gedcom_date_error(_("Too many characters in year '%s/%s'"),
+                       input1, input2);
+      return -1;
+    }
+  }
+}
+
+int get_year_num(const char* input, Year_type* ytype)
+{
+  char *year1, *year2 = NULL;
+  int numtok = get_year_tokens(input, &year1, &year2);
+  if (numtok) {
+    *ytype = (numtok == 1 ? YEAR_SINGLE : YEAR_DOUBLE);
+    return _get_year_num (*ytype, year1, year2);
+  }
+  else {
+    gedcom_date_error(_("Not a valid year: '%s'"), input); 
+    return -1;
+  }
+}