*/
#include "h/mh.h"
+#include "error.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"
/*
* This doesn't try to support all of the myriad date-time formats
* 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;
- int form_1 = 0;
+ bool form_1;
int items_matched;
- memset(tws, 0, sizeof *tws);
+ ZERO(tws);
items_matched =
sscanf (datetime, "%4d%2d%2dT%2d%2d%2d%c",
&tws->tw_year, &tws->tw_mon, &tws->tw_mday,
&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') {
- 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) {
- 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) {
- int offset = atoi (zone ? zone : "0");
-
/* struct tws defines tw_mon over [0, 11]. */
--tws->tw_mon;
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. */
- tws->tw_flags &= ~TW_SDAY, tws->tw_flags |= TW_SEXP;
+ tws->tw_flags &= ~TW_SDAY;
+ tws->tw_flags |= TW_SEXP;
/* For the call to dmktime():
- don't need tw_yday
- 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;
}
tzdesc_t
-load_timezones (const contentline *clines) {
+load_timezones (const contentline *clines)
+{
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. */
- 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; }
(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 ? 1 : 0,
- &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",
- params->dtstart,
- in_standard ? "standard" : "daylight");
+ params->dtstart,
+ in_daylight ? "daylight" : "standard");
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. */
} 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)) {
- in_standard = 1;
+ in_standard = true;
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
if (! strcasecmp ("BEGIN", node->name) &&
! strcasecmp ("VTIMEZONE", node->value)) {
- in_vtimezone = 1;
+ in_vtimezone = true;
NEW0(timezone);
if (timezones) {
tzdesc_t t;
}
void
-free_timezones (tzdesc_t timezone) {
+free_timezones (tzdesc_t timezone)
+{
tzdesc_t next;
for ( ; timezone; timezone = next) {
*/
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") ||
}
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;
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));
}
/*
/* Find the corresponding tzdesc. */
for (tz = timezones; dt_timezone && tz; tz = tz->next) {
- /* Property parameter values are case insenstive (RFC 5545
+ /* Property parameter values are case insensitive (RFC 5545
Sec. 2) and time zone identifiers are property parameters
(RFC 5545 Sec. 3.8.2.4), though it would seem odd to use
different case in the same file for identifiers that are
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;
}
+ free(dt_timezone);
/* Determine if it's Daylight Saving. */
tp_std = strchr (tz->standard_params.dtstart, 'T');
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;
}
+ dt[0] = tws[0].tw_clock;
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;
}
-
- dst = dt[1] > transition[0] ? 0 : 1;
+ dt[1] = tws[1].tw_clock;
+ dst = dt[1] <= transition[0];
}
}