]> diplodocus.org Git - nmh/blobdiff - sbr/datetime.c
md5.h: Remove unused UINT2 typedef for unsigned short.
[nmh] / sbr / datetime.c
index 34287b2331c54ca50f058b99a042719b3ffe64b0..20b4be66901f89289cdfab0623215af0bf698831 100644 (file)
@@ -1,5 +1,4 @@
-/*
- * datetime.c -- functions for manipulating RFC 5545 date-time values
+/* datetime.c -- functions for manipulating RFC 5545 date-time values
  *
  * This code is Copyright (c) 2014, by the authors of nmh.
  * See the COPYRIGHT file in the root directory of the nmh
@@ -62,7 +61,10 @@ parse_datetime (const char *datetime, const char *zone, int dst,
                 struct tws *tws) {
     char utc_indicator;
     int form_1 = 0;
-    int items_matched =
+    int items_matched;
+
+    memset(tws, 0, sizeof *tws);
+    items_matched =
         sscanf (datetime, "%4d%2d%2dT%2d%2d%2d%c",
                 &tws->tw_year, &tws->tw_mon, &tws->tw_mday,
                 &tws->tw_hour, &tws->tw_min, &tws->tw_sec,
@@ -72,7 +74,7 @@ parse_datetime (const char *datetime, const char *zone, int dst,
     if (items_matched == 7) {
         /* The 'Z' must be capital according to RFC 5545 Sec. 3.3.5. */
         if (utc_indicator != 'Z') {
-            advise (NULL, "%s has invalid timezone indicator of 0x%x",
+            inform("%s has invalid timezone indicator of 0x%x",
                     datetime, utc_indicator);
             return NOTOK;
         }
@@ -80,12 +82,16 @@ parse_datetime (const char *datetime, const char *zone, int dst,
         form_1 = 1;
     }
 
-    if (items_matched >= 6) {
+    /* items_matched of 3 is for, e.g., 20151230.  Assume that means
+       the entire day.  The time fields of the tws struct were
+       initialized to 0 by the memset() above. */
+    if (items_matched >= 6  ||  items_matched == 3) {
         int offset = atoi (zone ? zone : "0");
 
         /* struct tws defines tw_mon over [0, 11]. */
         --tws->tw_mon;
 
+        /* Fill out rest of tws, i.e., its tw_wday and tw_flags. */
         set_dotw (tws);
         /* set_dotw() sets TW_SIMP.  Replace that with TW_SEXP so that
            dasctime() outputs the dotw before the date instead of after. */
@@ -136,9 +142,9 @@ parse_datetime (const char *datetime, const char *zone, int dst,
         }
 
         return OK;
-    } else {
-        return NOTOK;
     }
+
+    return NOTOK;
 }
 
 tzdesc_t
@@ -170,7 +176,7 @@ load_timezones (const contentline *clines) {
                         params->start_dt = tws.tw_clock;
                     }
                 } else {
-                    advise (NULL, "failed to parse start time %s for %s",
+                    inform("failed to parse start time %s for %s",
                             params->dtstart,
                             in_standard ? "standard" : "daylight");
                     return NULL;
@@ -210,7 +216,7 @@ load_timezones (const contentline *clines) {
                 ! strcasecmp ("VTIMEZONE", node->value)) {
 
                 in_vtimezone = 1;
-                timezone = mh_xcalloc (1, sizeof (struct tzdesc));
+                NEW0(timezone);
                 if (timezones) {
                     tzdesc_t t;
 
@@ -262,7 +268,8 @@ rrule_clock (const char *rrule, const char *starttime, const char *zone,
              unsigned int year) {
     time_t clock = 0;
 
-    if (nmh_strcasestr (rrule, "FREQ=YEARLY;INTERVAL=1")) {
+    if (nmh_strcasestr (rrule, "FREQ=YEARLY;INTERVAL=1")  ||
+        (nmh_strcasestr (rrule, "FREQ=YEARLY")  &&  nmh_strcasestr(rrule, "INTERVAL") == NULL)) {
         struct tws *tws;
         const char *cp;
         int wday = -1, month = -1;
@@ -313,9 +320,8 @@ rrule_clock (const char *rrule, const char *starttime, const char *zone,
 
 fail:
     if (clock == 0) {
-        admonish (NULL,
-                  "Unsupported RRULE format: %s, assume local timezone",
-                  rrule);
+        inform("Unsupported RRULE format: %s, assume local timezone, continuing...",
+           rrule);
     }
 
     return clock;
@@ -351,10 +357,9 @@ format_datetime (tzdesc_t timezones, const contentline *node) {
            Form #2: DATE WITH UTC TIME */
         if (parse_datetime (node->value, NULL, 0, &tws[0]) == OK) {
             return strdup (dasctime (&tws[0], 0));
-        } else {
-            advise (NULL, "unable to parse datetime %s", node->value);
-            return NULL;
         }
+        inform("unable to parse datetime %s", node->value);
+        return NULL;
     }
 
     /*
@@ -375,7 +380,7 @@ format_datetime (tzdesc_t timezones, const contentline *node) {
     if (tz) {
         free(dt_timezone);
     } else {
-        advise (NULL, "did not find VTIMEZONE section for %s", dt_timezone);
+        inform("did not find VTIMEZONE section for %s", dt_timezone);
         free(dt_timezone);
         return NULL;
     }
@@ -417,7 +422,7 @@ format_datetime (tzdesc_t timezones, const contentline *node) {
         }
 
         if (transition[0] < transition[1]) {
-            advise (NULL, "format_datetime() requires that daylight "
+            inform("format_datetime() requires that daylight "
                     "saving time transition precede standard time "
                     "transition");
             return NULL;
@@ -427,7 +432,7 @@ format_datetime (tzdesc_t timezones, const contentline *node) {
                             0, &tws[0]) == OK) {
             dt[0] = tws[0].tw_clock;
         } else {
-            advise (NULL, "unable to parse datetime %s", node->value);
+            inform("unable to parse datetime %s", node->value);
             return NULL;
         }
 
@@ -440,7 +445,7 @@ format_datetime (tzdesc_t timezones, const contentline *node) {
                                     &tws[1]) == OK) {
                     dt[1] = tws[1].tw_clock;
                 } else {
-                    advise (NULL, "unable to parse datetime %s",
+                    inform("unable to parse datetime %s",
                             node->value);
                     return NULL;
                 }
@@ -452,7 +457,7 @@ format_datetime (tzdesc_t timezones, const contentline *node) {
         if (dst) {
             if (tz->daylight_params.start_dt > 0  &&
                 dt[dst] < tz->daylight_params.start_dt) {
-                advise (NULL, "date-time of %s is before VTIMEZONE start "
+                inform("date-time of %s is before VTIMEZONE start "
                         "of %s", node->value,
                         tz->daylight_params.dtstart);
                 return NULL;
@@ -460,7 +465,7 @@ format_datetime (tzdesc_t timezones, const contentline *node) {
         } else {
             if (tz->standard_params.start_dt > 0  &&
                 dt[dst] < tz->standard_params.start_dt) {
-                advise (NULL, "date-time of %s is before VTIMEZONE start "
+                inform("date-time of %s is before VTIMEZONE start "
                         "of %s", node->value,
                         tz->standard_params.dtstart);
                 return NULL;
@@ -468,12 +473,12 @@ format_datetime (tzdesc_t timezones, const contentline *node) {
         }
     } else {
         if (! tp_std) {
-            advise (NULL, "unsupported date-time format: %s",
+            inform("unsupported date-time format: %s",
                     tz->standard_params.dtstart);
             return NULL;
         }
         if (! tp_dt) {
-            advise (NULL, "unsupported date-time format: %s", node->value);
+            inform("unsupported date-time format: %s", node->value);
             return NULL;
         }
     }