]> diplodocus.org Git - nmh/blobdiff - sbr/datetime.c
ssequal.c: Move interface to own file.
[nmh] / sbr / datetime.c
index 9ecff53cf8a014e15a6bec69da831716a0d03bb0..e4d2d148924588edafad3bef70e968edaaaf63aa 100644 (file)
@@ -6,8 +6,9 @@
  */
 
 #include "h/mh.h"
  */
 
 #include "h/mh.h"
+#include "error.h"
 #include "h/icalendar.h"
 #include "h/icalendar.h"
-#include <h/fmt_scan.h>
+#include "h/fmt_scan.h"
 #include "h/tws.h"
 #include "h/utils.h"
 #include "unquote.h"
 #include "h/tws.h"
 #include "h/utils.h"
 #include "unquote.h"
@@ -58,10 +59,11 @@ struct tzdesc {
  * struct tws.
  */
 static int
  * struct tws.
  */
 static int
-parse_datetime (const char *datetime, const char *zone, int dst,
-                struct tws *tws) {
+parse_datetime (const char *datetime, const char *zone, bool dst,
+                struct tws *tws)
+{
     char utc_indicator;
     char utc_indicator;
-    int form_1 = 0;
+    bool form_1;
     int items_matched;
 
     ZERO(tws);
     int items_matched;
 
     ZERO(tws);
@@ -72,23 +74,22 @@ parse_datetime (const char *datetime, const char *zone, int dst,
                 &utc_indicator);
     tws->tw_flags = TW_NULL;
 
                 &utc_indicator);
     tws->tw_flags = TW_NULL;
 
+    form_1 = false;
     if (items_matched == 7) {
         /* The 'Z' must be capital according to RFC 5545 Sec. 3.3.5. */
         if (utc_indicator != 'Z') {
     if (items_matched == 7) {
         /* The 'Z' must be capital according to RFC 5545 Sec. 3.3.5. */
         if (utc_indicator != 'Z') {
-            inform("%s has invalid timezone indicator of 0x%x",
+            inform("%s has invalid timezone-indicator byte: %#x",
                     datetime, utc_indicator);
             return NOTOK;
         }
     } else if (zone == NULL) {
                     datetime, utc_indicator);
             return NOTOK;
         }
     } else if (zone == NULL) {
-        form_1 = 1;
+        form_1 = true;
     }
 
     /* 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) {
     }
 
     /* 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;
 
         /* struct tws defines tw_mon over [0, 11]. */
         --tws->tw_mon;
 
@@ -105,7 +106,11 @@ parse_datetime (const char *datetime, const char *zone, int dst,
            - the only flag in tw_flags used is TW_DST
          */
         tws->tw_yday = tws->tw_clock = 0;
            - the only flag in tw_flags used is TW_DST
          */
         tws->tw_yday = tws->tw_clock = 0;
-        tws->tw_zone = 60 * (offset / 100)  +  offset % 100;
+        if (zone) {
+            int offset = atoi(zone);
+            tws->tw_zone = 60 * (offset / 100)  +  offset % 100;
+        } else
+            tws->tw_zone = 0;
         if (dst) {
             tws->tw_zone -= 60;  /* per dlocaltime() */
             tws->tw_flags |= TW_DST;
         if (dst) {
             tws->tw_zone -= 60;  /* per dlocaltime() */
             tws->tw_flags |= TW_DST;
@@ -150,14 +155,15 @@ parse_datetime (const char *datetime, const char *zone, int dst,
 }
 
 tzdesc_t
 }
 
 tzdesc_t
-load_timezones (const contentline *clines) {
+load_timezones (const contentline *clines)
+{
     tzdesc_t timezones = NULL, timezone = NULL;
     tzdesc_t timezones = NULL, timezone = NULL;
-    int in_vtimezone, in_standard, in_daylight;
+    bool in_vtimezone, in_standard, in_daylight;
     tzparams *params = NULL;
     const contentline *node;
 
     /* Interpret each VTIMEZONE section. */
     tzparams *params = NULL;
     const contentline *node;
 
     /* Interpret each VTIMEZONE section. */
-    in_vtimezone = in_standard = in_daylight = 0;
+    in_vtimezone = in_standard = in_daylight = false;
     for (node = clines; node; node = node->next) {
         /* node->name will be NULL if the line was "deleted". */
         if (! node->name) { continue; }
     for (node = clines; node; node = node->next) {
         /* node->name will be NULL if the line was "deleted". */
         if (! node->name) { continue; }
@@ -168,21 +174,21 @@ load_timezones (const contentline *clines) {
                  (in_daylight  &&  ! strcasecmp ("DAYLIGHT", node->value)))) {
                 struct tws tws;
 
                  (in_daylight  &&  ! strcasecmp ("DAYLIGHT", node->value)))) {
                 struct tws tws;
 
-                if (in_standard) { in_standard = 0; }
-                else if (in_daylight) { in_daylight = 0; }
-                if (parse_datetime (params->dtstart, params->offsetfrom,
-                                    in_daylight,
-                                    &tws) == OK) {
-                    if (tws.tw_year >= 1970) {
-                        /* dmktime() falls apart for, e.g., the year 1601. */
-                        params->start_dt = tws.tw_clock;
-                    }
-                } else {
+                if (in_standard) { in_standard = false; }
+                else if (in_daylight) { in_daylight = false; }
+
+                if (parse_datetime(params->dtstart, params->offsetfrom,
+                    in_daylight, &tws) != OK) {
                     inform("failed to parse start time %s for %s",
                     inform("failed to parse start time %s for %s",
-                            params->dtstart,
-                            in_standard ? "standard" : "daylight");
+                        params->dtstart,
+                        in_daylight ? "daylight" : "standard");
                     return NULL;
                 }
                     return NULL;
                 }
+
+                if (tws.tw_year >= 1970) {
+                    /* dmktime() falls apart for, e.g., the year 1601. */
+                    params->start_dt = tws.tw_clock;
+                }
                 params = NULL;
             } else if (! strcasecmp ("DTSTART", node->name)) {
                 /* Save DTSTART for use after getting TZOFFSETFROM. */
                 params = NULL;
             } else if (! strcasecmp ("DTSTART", node->name)) {
                 /* Save DTSTART for use after getting TZOFFSETFROM. */
@@ -197,14 +203,14 @@ load_timezones (const contentline *clines) {
         } else if (in_vtimezone) {
             if (! strcasecmp ("END", node->name)  &&
                 ! strcasecmp ("VTIMEZONE", node->value)) {
         } else if (in_vtimezone) {
             if (! strcasecmp ("END", node->name)  &&
                 ! strcasecmp ("VTIMEZONE", node->value)) {
-                in_vtimezone = 0;
+                in_vtimezone = false;
             } else if (! strcasecmp ("BEGIN", node->name)  &&
                 ! strcasecmp ("STANDARD", node->value)) {
             } else if (! strcasecmp ("BEGIN", node->name)  &&
                 ! strcasecmp ("STANDARD", node->value)) {
-                in_standard = 1;
+                in_standard = true;
                 params = &timezone->standard_params;
             } else if (! strcasecmp ("BEGIN", node->name)  &&
                 ! strcasecmp ("DAYLIGHT", node->value)) {
                 params = &timezone->standard_params;
             } else if (! strcasecmp ("BEGIN", node->name)  &&
                 ! strcasecmp ("DAYLIGHT", node->value)) {
-                in_daylight = 1;
+                in_daylight = true;
                 params = &timezone->daylight_params;
             } else if (! strcasecmp ("TZID", node->name)) {
                 /* See comment below in format_datetime() about removing any enclosing quotes from a
                 params = &timezone->daylight_params;
             } else if (! strcasecmp ("TZID", node->name)) {
                 /* See comment below in format_datetime() about removing any enclosing quotes from a
@@ -217,7 +223,7 @@ load_timezones (const contentline *clines) {
             if (! strcasecmp ("BEGIN", node->name)  &&
                 ! strcasecmp ("VTIMEZONE", node->value)) {
 
             if (! strcasecmp ("BEGIN", node->name)  &&
                 ! strcasecmp ("VTIMEZONE", node->value)) {
 
-                in_vtimezone = 1;
+                in_vtimezone = true;
                 NEW0(timezone);
                 if (timezones) {
                     tzdesc_t t;
                 NEW0(timezone);
                 if (timezones) {
                     tzdesc_t t;
@@ -237,7 +243,8 @@ load_timezones (const contentline *clines) {
 }
 
 void
 }
 
 void
-free_timezones (tzdesc_t timezone) {
+free_timezones (tzdesc_t timezone)
+{
     tzdesc_t next;
 
     for ( ; timezone; timezone = next) {
     tzdesc_t next;
 
     for ( ; timezone; timezone = next) {
@@ -267,7 +274,8 @@ free_timezones (tzdesc_t timezone) {
  */
 time_t
 rrule_clock (const char *rrule, const char *starttime, const char *zone,
  */
 time_t
 rrule_clock (const char *rrule, const char *starttime, const char *zone,
-             unsigned int year) {
+             unsigned int year)
+{
     time_t clock = 0;
 
     if (nmh_strcasestr (rrule, "FREQ=YEARLY;INTERVAL=1")  ||
     time_t clock = 0;
 
     if (nmh_strcasestr (rrule, "FREQ=YEARLY;INTERVAL=1")  ||
@@ -330,7 +338,8 @@ fail:
 }
 
 char *
 }
 
 char *
-format_datetime (tzdesc_t timezones, const contentline *node) {
+format_datetime (tzdesc_t timezones, const contentline *node)
+{
     param_list *p;
     char *dt_timezone = NULL;
     int dst = 0;
     param_list *p;
     char *dt_timezone = NULL;
     int dst = 0;
@@ -357,11 +366,11 @@ format_datetime (tzdesc_t timezones, const contentline *node) {
     if (! dt_timezone) {
         /* Form #1: DATE WITH LOCAL TIME, i.e., no time zone, or
            Form #2: DATE WITH UTC TIME */
     if (! dt_timezone) {
         /* Form #1: DATE WITH LOCAL TIME, i.e., no time zone, or
            Form #2: DATE WITH UTC TIME */
-        if (parse_datetime (node->value, NULL, 0, &tws[0]) == OK) {
-            return strdup (dasctime (&tws[0], 0));
+        if (parse_datetime(node->value, NULL, false, &tws[0]) != OK) {
+            inform("unable to parse datetime %s", node->value);
+            return NULL;
         }
         }
-        inform("unable to parse datetime %s", node->value);
-        return NULL;
+        return strdup (dasctime (&tws[0], 0));
     }
 
     /*
     }
 
     /*
@@ -379,13 +388,12 @@ format_datetime (tzdesc_t timezones, const contentline *node) {
         if (tz->tzid  &&  ! strcasecmp (dt_timezone, tz->tzid)) { break; }
     }
 
         if (tz->tzid  &&  ! strcasecmp (dt_timezone, tz->tzid)) { break; }
     }
 
-    if (tz) {
-        free(dt_timezone);
-    } else {
+    if (!tz) {
         inform("did not find VTIMEZONE section for %s", dt_timezone);
         free(dt_timezone);
         return NULL;
     }
         inform("did not find VTIMEZONE section for %s", dt_timezone);
         free(dt_timezone);
         return NULL;
     }
+    free(dt_timezone);
 
     /* Determine if it's Daylight Saving. */
     tp_std = strchr (tz->standard_params.dtstart, 'T');
 
     /* Determine if it's Daylight Saving. */
     tp_std = strchr (tz->standard_params.dtstart, 'T');
@@ -430,28 +438,23 @@ format_datetime (tzdesc_t timezones, const contentline *node) {
             return NULL;
         }
 
             return NULL;
         }
 
-        if (parse_datetime (node->value, tz->standard_params.offsetto,
-                            0, &tws[0]) == OK) {
-            dt[0] = tws[0].tw_clock;
-        } else {
+        if (parse_datetime(node->value, tz->standard_params.offsetto,
+            false, &tws[0]) != OK) {
             inform("unable to parse datetime %s", node->value);
             return NULL;
         }
             inform("unable to parse datetime %s", node->value);
             return NULL;
         }
+        dt[0] = tws[0].tw_clock;
 
         if (tp_dst) {
             if (dt[0] < transition[1]) {
                 dst = 0;
             } else {
 
         if (tp_dst) {
             if (dt[0] < transition[1]) {
                 dst = 0;
             } else {
-                if (parse_datetime (node->value,
-                                    tz->daylight_params.offsetto, 1,
-                                    &tws[1]) == OK) {
-                    dt[1] = tws[1].tw_clock;
-                } else {
-                    inform("unable to parse datetime %s",
-                            node->value);
+                if (parse_datetime(node->value,
+                    tz->daylight_params.offsetto, true, &tws[1]) != OK) {
+                    inform("unable to parse datetime %s", node->value);
                     return NULL;
                 }
                     return NULL;
                 }
-
+                dt[1] = tws[1].tw_clock;
                 dst = dt[1] <= transition[0];
             }
         }
                 dst = dt[1] <= transition[0];
             }
         }