Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 20 Mar 2018 02:52:28 +0000 (UTC)
From:      Don Lewis <truckman@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r465060 - in head/devel/libical: . files
Message-ID:  <201803200252.w2K2qShi006793@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: truckman
Date: Tue Mar 20 02:52:28 2018
New Revision: 465060
URL: https://svnweb.freebsd.org/changeset/ports/465060

Log:
  Import upstream patch:
  https://github.com/libical/libical/commit/77f82ba88abbb633dc52335fcc050bec3b41c2
  69
  
    icaltzutil_fetch_timezone now creates VTIMEZONE components using
    RRULEs rather than expanding out every year (if
    USE_INTEROPERATIVE_VTIMEZONES was off) or using a single time zone
    back to 1970 (if it was one).
  
    This creates more accurate time zones that are compatible with dates
    whose time zones have since transitioned to a different offset (such
    as a date in America/New_York in 1980).  Removed
    icaltzutil_set_exact_vtimezones_support and
    icaltzutil_get_exact_vtimezones_support.  Removed
    USE_INTEROPERABLE_VTIMEZONES.
  
  Add missing USE_GNOME=introspection:build
  
  Fix segmentation fault with evolution-calendar-factory
  
  Pet portlint, USE_* comes before USES
  
  PR:		226460
  Submitted by:	cpm
  Obtained from:	github libical/libical (partially)

Added:
  head/devel/libical/files/
  head/devel/libical/files/patch-src_libical_icaltz-util.c   (contents, props changed)
  head/devel/libical/files/patch-src_libical_icaltz-util.h   (contents, props changed)
  head/devel/libical/files/patch-src_test_timezones.c   (contents, props changed)
Modified:
  head/devel/libical/Makefile

Modified: head/devel/libical/Makefile
==============================================================================
--- head/devel/libical/Makefile	Tue Mar 20 02:47:17 2018	(r465059)
+++ head/devel/libical/Makefile	Tue Mar 20 02:52:28 2018	(r465060)
@@ -4,7 +4,7 @@
 PORTNAME=	libical
 PORTVERSION=	2.0.0
 DISTVERSIONPREFIX=	v
-PORTREVISION=	2
+PORTREVISION=	3
 CATEGORIES=	devel
 
 MAINTAINER=	gnome@FreeBSD.org
@@ -15,9 +15,9 @@ LICENSE_COMB=	dual
 
 LIB_DEPENDS=	libicuuc.so:devel/icu
 
-USE_GITHUB=	yes
-
 USES=		cmake pathfix perl5
+USE_GITHUB=	yes
+USE_GNOME=	introspection:build
 USE_PERL5=	build
 USE_LDCONFIG=	yes
 

Added: head/devel/libical/files/patch-src_libical_icaltz-util.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/devel/libical/files/patch-src_libical_icaltz-util.c	Tue Mar 20 02:52:28 2018	(r465060)
@@ -0,0 +1,520 @@
+--- src/libical/icaltz-util.c.orig	2018-03-09 22:23:47 UTC
++++ src/libical/icaltz-util.c
+@@ -4,20 +4,18 @@
+  *
+  * Copyright 2007, Novell, Inc.
+  *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of version 2 of the GNU Lesser General Public
+- * License as published by the Free Software Foundation.
++ * This library is free software; you can redistribute it and/or modify
++ * it under the terms of either:
+  *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU Lesser General Public License for more details.
++ *   The LGPL as published by the Free Software Foundation, version
++ *   2.1, available at: http://www.gnu.org/licenses/lgpl-2.1.html
+  *
+- * * You should have received a copy of the GNU Lesser General Public
+- * License along with this library; if not, write to the
+- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
++ * Or:
++ *
++ *   The Mozilla Public License Version 2.0. You may obtain a copy of
++ *   the License at http://www.mozilla.org/MPL/
+  */
++//krazy:excludeall=cpp
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+@@ -93,9 +91,9 @@ typedef struct
+     char charcnt[4];
+ } tzinfo;
+ 
+-static char *zdir = NULL;
++static const char *zdir = NULL;
+ 
+-static char *search_paths[] = {
++static const char *search_paths[] = {
+     "/usr/share/zoneinfo",
+     "/usr/lib/zoneinfo",
+     "/etc/zoneinfo",
+@@ -144,6 +142,7 @@ static int decode(const void *ptr)
+         const unsigned char *p = ptr;
+         int result = *p & (1 << (CHAR_BIT - 1)) ? ~0 : 0;
+ 
++        /* cppcheck-suppress shiftNegative */
+         result = (result << 8) | *p++;
+         result = (result << 8) | *p++;
+         result = (result << 8) | *p++;
+@@ -153,9 +152,9 @@ static int decode(const void *ptr)
+     }
+ }
+ 
+-static char *zname_from_stridx(char *str, long idx)
++static char *zname_from_stridx(char *str, size_t idx)
+ {
+-    long i;
++    size_t i;
+     size_t size;
+     char *ret;
+ 
+@@ -164,7 +163,7 @@ static char *zname_from_stridx(char *str
+         i++;
+     }
+ 
+-    size = (size_t)(i - idx);
++    size = i - idx;
+     str += idx;
+     ret = (char *)malloc(size + 1);
+     ret = strncpy(ret, str, size);
+@@ -197,45 +196,6 @@ const char *icaltzutil_get_zone_director
+     return zdir;
+ }
+ 
+-static void find_transidx(time_t *transitions, ttinfo *types,
+-                          int *trans_idx, long int num_trans,
+-                          int *stdidx, int *dstidx)
+-{
+-    time_t now, year_start;
+-    int i, found = 0;
+-    struct icaltimetype itime;
+-
+-    now = time(NULL);
+-    itime = icaltime_from_timet(now, 0);
+-    itime.month = itime.day = 1;
+-    itime.hour = itime.minute = itime.second = 0;
+-    year_start = icaltime_as_timet(itime);
+-
+-    /* Set this by default */
+-    *stdidx = (num_trans - 1);
+-
+-    for (i = (num_trans - 1); i >= 0; --i) {
+-        if (year_start < transitions[i]) {
+-          int idx;
+-          found = 1;
+-          idx = trans_idx[i];
+-          (types[idx].isdst) ? (*dstidx = i) : (*stdidx = i);
+-        }
+-    }
+-
+-    /* If the transition found is the last among the list, prepare to use the last two transtions.
+-     * Using this will most likely throw the DTSTART of the resulting component off by 1 or 2 days
+-     * but it would set right by the adjustment made.
+-     * NOTE: We need to use the last two transitions only because there is no data for the future
+-     * transitions.
+-     */
+-    if (found && (*dstidx == -1)) {
+-        *dstidx = ((*stdidx) - 1);
+-    }
+-
+-    return;
+-}
+-
+ static int calculate_pos(icaltimetype icaltime)
+ {
+    static int r_pos[] = {1, 2, 3, -2, -1};
+@@ -251,22 +211,6 @@ static int calculate_pos(icaltimetype ic
+    return r_pos[pos];
+ }
+ 
+-#if defined(USE_INTEROPERABLE_VTIMEZONES)
+-static int _s_use_exact_timezones = 0;
+-#else
+-static int _s_use_exact_timezones = 1;
+-#endif
+-
+-void icaltzutil_set_exact_vtimezones_support(int on)
+-{
+-    _s_use_exact_timezones = (on != 0);
+-}
+-
+-int icaltzutil_get_exact_vtimezones_support(void)
+-{
+-    return _s_use_exact_timezones;
+-}
+-
+ static void adjust_dtstart_day_to_rrule(icalcomponent *comp, struct icalrecurrencetype rule)
+ {
+     time_t now, year_start;
+@@ -274,13 +218,13 @@ static void adjust_dtstart_day_to_rrule(
+     icalrecur_iterator *iter;
+ 
+     now = time(NULL);
+-    itime = icaltime_from_timet(now, 0);
++    itime = icaltime_from_timet_with_zone(now, 0, NULL);
+     itime.month = itime.day = 1;
+     itime.hour = itime.minute = itime.second = 0;
+     year_start = icaltime_as_timet(itime);
+ 
+     comp_start = icalcomponent_get_dtstart(comp);
+-    start = icaltime_from_timet(year_start, 0);
++    start = icaltime_from_timet_with_zone(year_start, 0, NULL);
+ 
+     iter = icalrecur_iterator_new(rule, start);
+     iter_start = icalrecur_iterator_next(iter);
+@@ -298,9 +242,8 @@ icalcomponent *icaltzutil_fetch_timezone
+     size_t i, num_trans, num_chars, num_leaps, num_isstd, num_isgmt;
+     size_t num_types = 0;
+     size_t size;
+-    time_t trans;
+-    int dstidx = -1, stdidx = -1, pos, sign, zidx, zp_idx;
+-    icalcomponent *std_comp = NULL;
++    int pos, sign;
++    time_t now = time(NULL);
+ 
+     const char *zonedir;
+     FILE *f = NULL;
+@@ -313,12 +256,22 @@ icalcomponent *icaltzutil_fetch_timezone
+     leap *leaps = NULL;
+     char *tzid = NULL;
+ 
+-    time_t start, end;
+     int idx, prev_idx;
+-    icalcomponent *tz_comp = NULL, *comp = NULL, *dst_comp;
++    icalcomponent *tz_comp = NULL, *comp = NULL;
+     icalproperty *icalprop;
+-    icaltimetype dtstart, icaltime;
+-    struct icalrecurrencetype ical_recur;
++    icaltimetype icaltime;
++    struct icalrecurrencetype standard_recur;
++    struct icalrecurrencetype daylight_recur;
++    icaltimetype prev_standard_time = icaltime_null_time();
++    icaltimetype prev_daylight_time = icaltime_null_time();
++    icaltimetype prev_prev_standard_time;
++    icaltimetype prev_prev_daylight_time;
++    long prev_standard_gmtoff;
++    long prev_daylight_gmtoff;
++    icalcomponent *cur_standard_comp = NULL;
++    icalcomponent *cur_daylight_comp = NULL;
++    icalproperty *cur_standard_rrule_property;
++    icalproperty *cur_daylight_rrule_property;
+ 
+     if (icaltimezone_get_builtin_tzdata()) {
+         goto error;
+@@ -448,15 +401,8 @@ icalcomponent *icaltzutil_fetch_timezone
+     /* Read all the contents now */
+ 
+     for (i = 0; i < num_types; i++) {
+-        types[i].zname = zname_from_stridx(znames, (long)types[i].abbr);
+-    }
+-
+-    if (!_s_use_exact_timezones) {
+-        if (num_trans != 0) {
+-            find_transidx(transitions, types, trans_idx, (long int)num_trans, &stdidx, &dstidx);
+-        } else {
+-            stdidx = 0;
+-        }
++        /* coverity[tainted_data] */
++        types[i].zname = zname_from_stridx(znames, types[i].abbr);
+     }
+ 
+     tz_comp = icalcomponent_new(ICAL_VTIMEZONE_COMPONENT);
+@@ -476,140 +422,202 @@ icalcomponent *icaltzutil_fetch_timezone
+     icalproperty_set_x_name(icalprop, "X-LIC-LOCATION");
+     icalcomponent_add_property(tz_comp, icalprop);
+ 
+-    if (!_s_use_exact_timezones) {
+-        if (stdidx != -1) {
+-            if (num_trans != 0) {
+-                zidx = trans_idx[stdidx];
++    prev_idx = 0;
++    if (num_trans == 0) {
++        prev_idx = idx = 0;
++    } else {
++        idx = trans_idx[0];
++    }
++
++    for (i = 1; i < num_trans; i++) {
++        int by_day;
++        int is_new_comp = 0;
++        time_t start;
++        struct icalrecurrencetype *recur;
++
++        prev_idx = idx;
++        idx = trans_idx[i];
++        start = transitions[i] + types[prev_idx].gmtoff;
++
++        icaltime = icaltime_from_timet_with_zone(start, 0, NULL);
++        pos = calculate_pos(icaltime);
++        pos < 0 ? (sign = -1): (sign = 1);
++        by_day = sign * ((abs(pos) * 8) + icaltime_day_of_week(icaltime));
++
++        // Figure out if the rule has changed since the previous year
++        // If it has, update the recurrence rule of the current component and create a new component
++        // If it the current component was only valid for one year then remove the recurrence rule
++        if (types[idx].isdst) {
++            if (cur_daylight_comp) {
++                // Check if the pattern for daylight has changed
++                // If it has, create a new component and update UNTIL of previous component's RRULE
++                if (daylight_recur.by_month[0] != icaltime.month ||
++                        daylight_recur.by_day[0] != by_day ||
++                        types[prev_idx].gmtoff != prev_daylight_gmtoff) {
++                    // Set UNTIL of the previous component's recurrence
++                    icaltime_adjust(&prev_daylight_time, 0, 0, 0, -types[prev_idx].gmtoff);
++                    prev_daylight_time.is_utc = 1;
++
++                    daylight_recur.until = prev_daylight_time;
++                    icalproperty_set_rrule(cur_daylight_rrule_property, daylight_recur);
++
++                    cur_daylight_comp = icalcomponent_new(ICAL_XDAYLIGHT_COMPONENT);
++                    is_new_comp = 1;
++                }
+             } else {
+-                zidx = 0;
++                cur_daylight_comp = icalcomponent_new(ICAL_XDAYLIGHT_COMPONENT);
++                is_new_comp = 1;
+             }
+ 
+-            std_comp = icalcomponent_new(ICAL_XSTANDARD_COMPONENT);
+-            icalprop = icalproperty_new_tzname(types[zidx].zname);
+-            icalcomponent_add_property(std_comp, icalprop);
++            comp = cur_daylight_comp;
++            recur = &daylight_recur;
+ 
+-            if (dstidx != -1) {
+-                zp_idx = trans_idx[stdidx-1];
++            if (icaltime_is_null_time(prev_daylight_time)) {
++                prev_prev_daylight_time = icaltime;
+             } else {
+-                zp_idx = zidx;
++                prev_prev_daylight_time = prev_daylight_time;
+             }
+-            /* DTSTART localtime uses TZOFFSETFROM UTC offset */
+-            if (num_trans != 0) {
+-                trans = transitions[stdidx] + types[zp_idx].gmtoff;
++
++            prev_daylight_time = icaltime;
++            prev_daylight_gmtoff = types[prev_idx].gmtoff;
++        } else {
++            if (cur_standard_comp) {
++                // Check if the pattern for standard has changed
++                // If it has, create a new component and update UNTIL
++                // of the previous component's RRULE
++                if (standard_recur.by_month[0] != icaltime.month ||
++                        standard_recur.by_day[0] != by_day ||
++                        types[prev_idx].gmtoff != prev_standard_gmtoff) {
++                    icaltime_adjust(&prev_standard_time, 0, 0, 0, -types[prev_idx].gmtoff);
++                    prev_standard_time.is_utc = 1;
++
++                    standard_recur.until = prev_standard_time;
++                    icalproperty_set_rrule(cur_standard_rrule_property, standard_recur);
++
++                    cur_standard_comp = icalcomponent_new(ICAL_XSTANDARD_COMPONENT);
++                    is_new_comp = 1;
++
++                    // Are we transitioning on the daylight date?
++                    // If so, that means the time zone is switching off of DST
++                    // We need to set UNTIL for the daylight component
++                    if (cur_daylight_comp && daylight_recur.by_month[0] == icaltime.month &&
++                            daylight_recur.by_day[0] == by_day) {
++                        icaltime_adjust(&prev_daylight_time, 0, 0, 0, -types[prev_idx].gmtoff);
++                        prev_daylight_time.is_utc = 1;
++
++                        daylight_recur.until = prev_daylight_time;
++                        icalproperty_set_rrule(cur_daylight_rrule_property, daylight_recur);
++                    }
++                }
+             } else {
+-                trans = (time_t)types[zp_idx].gmtoff;
++                cur_standard_comp = icalcomponent_new(ICAL_XSTANDARD_COMPONENT);
++                is_new_comp = 1;
+             }
+-            icaltime = icaltime_from_timet(trans, 0);
+-            dtstart = icaltime;
+-            dtstart.year = 1970;
+-            dtstart.minute = dtstart.second = 0;
+-            icalprop = icalproperty_new_dtstart(dtstart);
+-            icalcomponent_add_property(std_comp, icalprop);
+ 
+-            /* If DST changes are present use RRULE */
+-            if (dstidx != -1) {
+-                icalrecurrencetype_clear(&ical_recur);
+-                ical_recur.freq = ICAL_YEARLY_RECURRENCE;
+-                ical_recur.by_month[0] = icaltime.month;
+-                pos = calculate_pos(icaltime);
+-                pos < 0 ? (sign = -1): (sign = 1);
+-                ical_recur.by_day[0] = sign * ((abs(pos) * 8) + icaltime_day_of_week(icaltime));
+-                icalprop = icalproperty_new_rrule(ical_recur);
+-                icalcomponent_add_property(std_comp, icalprop);
++            comp = cur_standard_comp;
++            recur = &standard_recur;
+ 
+-                adjust_dtstart_day_to_rrule(std_comp, ical_recur);
++            if (icaltime_is_null_time(prev_standard_time)) {
++                prev_prev_standard_time = icaltime;
++            } else {
++                prev_prev_standard_time = prev_standard_time;
+             }
+-            icalprop = icalproperty_new_tzoffsetfrom(types[zp_idx].gmtoff);
+-            icalcomponent_add_property(std_comp, icalprop);
+-            icalprop = icalproperty_new_tzoffsetto(types[zidx].gmtoff);
+-            icalcomponent_add_property(std_comp, icalprop);
+-            icalcomponent_add_component(tz_comp, std_comp);
+-        } else {
+-            icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
++
++            prev_standard_time = icaltime;
++            prev_standard_gmtoff = types[prev_idx].gmtoff;
+         }
+ 
+-        if (dstidx != -1) {
+-            zidx = trans_idx[dstidx];
+-            zp_idx = trans_idx[dstidx-1];
+-            dst_comp = icalcomponent_new(ICAL_XDAYLIGHT_COMPONENT);
+-            icalprop = icalproperty_new_tzname(types[zidx].zname);
+-            icalcomponent_add_property(dst_comp, icalprop);
++        if (is_new_comp) {
++            icalprop = icalproperty_new_tzname(types[idx].zname);
++            icalcomponent_add_property(comp, icalprop);
++            icalprop = icalproperty_new_dtstart(icaltime);
++            icalcomponent_add_property(comp, icalprop);
++            icalprop = icalproperty_new_tzoffsetfrom(types[prev_idx].gmtoff);
++            icalcomponent_add_property(comp, icalprop);
++            icalprop = icalproperty_new_tzoffsetto(types[idx].gmtoff);
++            icalcomponent_add_property(comp, icalprop);
+ 
+-            /* DTSTART localtime uses TZOFFSETFROM UTC offset */
+-            if (num_trans != 0) {
+-                trans = transitions[dstidx] + types[zp_idx].gmtoff;
++            // Determine the recurrence rule for the current set of changes
++            icalrecurrencetype_clear(recur);
++            recur->freq = ICAL_YEARLY_RECURRENCE;
++            recur->by_month[0] = icaltime.month;
++            recur->by_day[0] = by_day;
++            icalprop = icalproperty_new_rrule(*recur);
++            icalcomponent_add_property(comp, icalprop);
++
++            if (types[idx].isdst) {
++                cur_daylight_rrule_property = icalprop;
+             } else {
+-                trans = (time_t)types[zp_idx].gmtoff;
++                cur_standard_rrule_property = icalprop;
+             }
+ 
+-            icaltime = icaltime_from_timet(trans, 0);
+-            dtstart = icaltime;
+-            dtstart.year = 1970;
+-            dtstart.minute = dtstart.second = 0;
+-            icalprop = icalproperty_new_dtstart(dtstart);
+-            icalcomponent_add_property(dst_comp, icalprop);
++            adjust_dtstart_day_to_rrule(comp, *recur);
+ 
+-            icalrecurrencetype_clear(&ical_recur);
+-            ical_recur.freq = ICAL_YEARLY_RECURRENCE;
+-            ical_recur.by_month[0] = icaltime.month;
+-            pos = calculate_pos(icaltime);
+-            pos < 0 ? (sign = -1): (sign = 1);
+-            ical_recur.by_day[0] = sign * ((abs(pos) * 8) + icaltime_day_of_week(icaltime));
+-            icalprop = icalproperty_new_rrule(ical_recur);
+-            icalcomponent_add_property(dst_comp, icalprop);
++            icalcomponent_add_component(tz_comp, comp);
++        }
++    }
+ 
+-            adjust_dtstart_day_to_rrule(dst_comp, ical_recur);
++    // Check if the last daylight or standard date was before now
++    // If so, set the UNTIL date to the second-to-last transition date
++    // and then insert a new component to indicate the time zone doesn't transition anymore
++    if (cur_daylight_comp && icaltime_as_timet(prev_daylight_time) < now) {
++        icaltime_adjust(&prev_prev_daylight_time, 0, 0, 0, -prev_daylight_gmtoff);
++        prev_prev_daylight_time.is_utc = 1;
+ 
+-            icalprop = icalproperty_new_tzoffsetfrom(types[zp_idx].gmtoff);
+-            icalcomponent_add_property(dst_comp, icalprop);
++        daylight_recur.until = prev_prev_daylight_time;
++        icalproperty_set_rrule(cur_daylight_rrule_property, daylight_recur);
+ 
+-            icalprop = icalproperty_new_tzoffsetto(types[zidx].gmtoff);
+-            icalcomponent_add_property(dst_comp, icalprop);
++        comp = icalcomponent_new(ICAL_XDAYLIGHT_COMPONENT);
++        icalprop = icalproperty_new_tzname(types[idx].zname);
++        icalcomponent_add_property(comp, icalprop);
++        icalprop = icalproperty_new_dtstart(prev_daylight_time);
++        icalcomponent_add_property(comp, icalprop);
++        icalprop = icalproperty_new_tzoffsetfrom(types[prev_idx].gmtoff);
++        icalcomponent_add_property(comp, icalprop);
++        icalprop = icalproperty_new_tzoffsetto(types[idx].gmtoff);
++        icalcomponent_add_property(comp, icalprop);
++        icalcomponent_add_component(tz_comp, comp);
++    }
+ 
+-            icalcomponent_add_component(tz_comp, dst_comp);
+-        }
+-    } else { /*exact vtimezones*/
+-        prev_idx = 0;
+-        if (num_trans == 0) {
+-            prev_idx = idx = 0;
++    if (cur_standard_comp && icaltime_as_timet(prev_standard_time) < now) {
++        icaltime_adjust(&prev_prev_standard_time, 0, 0, 0, -prev_standard_gmtoff);
++        prev_prev_standard_time.is_utc = 1;
++
++        standard_recur.until = prev_prev_standard_time;
++        icalproperty_set_rrule(cur_standard_rrule_property, standard_recur);
++
++        comp = icalcomponent_new(ICAL_XSTANDARD_COMPONENT);
++        icalprop = icalproperty_new_tzname(types[idx].zname);
++        icalcomponent_add_property(comp, icalprop);
++        icalprop = icalproperty_new_dtstart(prev_standard_time);
++        icalcomponent_add_property(comp, icalprop);
++        icalprop = icalproperty_new_tzoffsetfrom(types[prev_idx].gmtoff);
++        icalcomponent_add_property(comp, icalprop);
++        icalprop = icalproperty_new_tzoffsetto(types[idx].gmtoff);
++        icalcomponent_add_property(comp, icalprop);
++        icalcomponent_add_component(tz_comp, comp);
++    }
++
++    if (num_trans <= 1) {
++        time_t start;
++
++        if (num_trans == 1) {
++            start = transitions[0] + types[prev_idx].gmtoff;
+         } else {
+-            idx = trans_idx[0];
++            start = 0;
+         }
+-        start = 0;
+-        for (i = 1; i < num_trans; i++, start = end) {
+-            prev_idx = idx;
+-            idx = trans_idx[i];
+-            end = transitions[i] + types[prev_idx].gmtoff;
+-            /* don't bother starting until the epoch */
+-            if (0 > end)
+-                continue;
+ 
+-            if (types[prev_idx].isdst) {
+-                comp = icalcomponent_new(ICAL_XDAYLIGHT_COMPONENT);
+-            } else {
+-                comp = icalcomponent_new(ICAL_XSTANDARD_COMPONENT);
+-            }
+-            icalprop = icalproperty_new_tzname(types[prev_idx].zname);
+-            icalcomponent_add_property(comp, icalprop);
+-            dtstart = icaltime_from_timet(start, 0);
+-            icalprop = icalproperty_new_dtstart(dtstart);
+-            icalcomponent_add_property(comp, icalprop);
+-            icalprop = icalproperty_new_tzoffsetfrom(types[idx].gmtoff);
+-            icalcomponent_add_property(comp, icalprop);
+-            icalprop = icalproperty_new_tzoffsetto(types[prev_idx].gmtoff);
+-            icalcomponent_add_property(comp, icalprop);
+-            icalcomponent_add_component(tz_comp, comp);
+-        }
+-        /* finally, add a last zone with no end date */
++        // This time zone doesn't transition, insert a single VTIMEZONE component
+         if (types[idx].isdst) {
+             comp = icalcomponent_new(ICAL_XDAYLIGHT_COMPONENT);
+         } else {
+             comp = icalcomponent_new(ICAL_XSTANDARD_COMPONENT);
+         }
++
+         icalprop = icalproperty_new_tzname(types[idx].zname);
+         icalcomponent_add_property(comp, icalprop);
+-        dtstart = icaltime_from_timet(start, 0);
+-        icalprop = icalproperty_new_dtstart(dtstart);
++        icaltime = icaltime_from_timet_with_zone(start, 0, NULL);
++        icalprop = icalproperty_new_dtstart(icaltime);
+         icalcomponent_add_property(comp, icalprop);
+         icalprop = icalproperty_new_tzoffsetfrom(types[prev_idx].gmtoff);
+         icalcomponent_add_property(comp, icalprop);

Added: head/devel/libical/files/patch-src_libical_icaltz-util.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/devel/libical/files/patch-src_libical_icaltz-util.h	Tue Mar 20 02:52:28 2018	(r465060)
@@ -0,0 +1,41 @@
+--- src/libical/icaltz-util.h.orig	2018-03-09 22:29:13 UTC
++++ src/libical/icaltz-util.h
+@@ -4,19 +4,16 @@
+  *
+  * Copyright 2007, Novell, Inc.
+  *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of version 2 of the GNU Lesser General Public
+- * License as published by the Free Software Foundation.
++ * This library is free software; you can redistribute it and/or modify
++ * it under the terms of either:
+  *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU Lesser General Public License for more details.
++ *   The LGPL as published by the Free Software Foundation, version
++ *   2.1, available at: http://www.gnu.org/licenses/lgpl-2.1.html
+  *
+- * You should have received a copy of the GNU Lesser General Public
+- * License along with this library; if not, write to the
+- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
++ * Or:
++ *
++ *   The Mozilla Public License Version 2.0. You may obtain a copy of
++ *   the License at http://www.mozilla.org/MPL/
+  */
+ 
+ #ifndef ICALTZUTIL_H
+@@ -35,10 +32,4 @@ LIBICAL_ICAL_EXPORT const char *icaltzut
+ 
+ LIBICAL_ICAL_EXPORT icalcomponent *icaltzutil_fetch_timezone(const char *location);
+ 
+-/* set @p on to 0 if inter-operable vtimezones are desired; else exact timezones are in-effect */
+-LIBICAL_ICAL_EXPORT void icaltzutil_set_exact_vtimezones_support(int on);
+-
+-/* return 1 if exact vtimezones are in-effect; else inter-operable vtimezones are in-effect */
+-LIBICAL_ICAL_EXPORT int icaltzutil_get_exact_vtimezones_support(void);
+-
+ #endif

Added: head/devel/libical/files/patch-src_test_timezones.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/devel/libical/files/patch-src_test_timezones.c	Tue Mar 20 02:52:28 2018	(r465060)
@@ -0,0 +1,82 @@
+--- src/test/timezones.c.orig	2018-03-09 22:35:51 UTC
++++ src/test/timezones.c
+@@ -1,15 +1,16 @@
+ /*
+ ======================================================================
+ 
+-  The contents of this file are subject to the Mozilla Public License
+-  Version 1.0 (the "License"); you may not use this file except in
+-  compliance with the License. You may obtain a copy of the License at
+-  http://www.mozilla.org/MPL/
++ This library is free software; you can redistribute it and/or modify
++ it under the terms of either:
+ 
+-  Software distributed under the License is distributed on an "AS IS"
+-  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+-  the License for the specific language governing rights and
+-  limitations under the License.
++    The LGPL as published by the Free Software Foundation, version
++    2.1, available at: http://www.gnu.org/licenses/lgpl-2.1.html
++
++ Or:
++
++    The Mozilla Public License Version 2.0. You may obtain a copy of
++    the License at http://www.mozilla.org/MPL/
+ 
+ ======================================================================*/
+ 
+@@ -56,6 +57,9 @@ int main()
+     for (i = 0; i < timezones->num_elements; i++) {
+         zone = (icaltimezone *)icalarray_element_at(timezones, i);
+         zone_location = (char *)icaltimezone_get_location(zone);
++        zonedef_printed = 0;
++        if (!zone_location)
++            continue;
+ 
+         /*
+          * select this location for glibc: needs support for TZ=<location>
+@@ -66,7 +70,7 @@ int main()
+ #else
+         new_tz[0] = '\0';
+         strncat(new_tz, "TZ=", 255);
+-        strncat(new_tz, zone_location, 255);
++        strncat(new_tz, zone_location, 255 - strlen(new_tz));
+         putenv(new_tz);
+ #endif
+         tzset();
+@@ -106,7 +110,9 @@ int main()
+             if (verbose || curr_failed != failed) {
+                 struct tm utc_tm;
+ 
+-                gmtime_r(&curr_time, &utc_tm);
++                if (!gmtime_r(&curr_time, &utc_tm))
++                    memset(&utc_tm, 0, sizeof(utc_tm));
++
+                 printf(
+                     "%s: day %03d: %s: %04d-%02d-%02d %02d:%02d:%02d UTC = "
+                     "libc %04d-%02d-%02d %02d:%02d:%02d dst %d",
+@@ -131,7 +137,7 @@ int main()
+                 printf("\n");
+                 failed = curr_failed;
+ 
+-                if (!zonedef_printed) {
++                if (failed && !zonedef_printed) {
+                     icalcomponent *comp = icaltimezone_get_component(zone);
+ 
+                     if (comp) {
+@@ -153,14 +159,8 @@ int main()
+         percent_failed = total_failed * 100 / (total_failed + total_okay);
+         printf(" *** Summary: %lu zones tested, %u days failed, %u okay => %u%% failed ***\n",
+                (unsigned long)timezones->num_elements, total_failed, total_okay, percent_failed);
+-
+-        if (!icaltzutil_get_exact_vtimezones_support()) {
+-            if (!percent_failed) {
+-                ret = 0;
+-                printf(" *** Expect some small error rate with inter-operable vtimezones *** \n");
+-            }
+-       }
+     }
+ 
++    icaltimezone_free_builtin_timezones();
+     return ret;
+ }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201803200252.w2K2qShi006793>