1 # Migrating to version 4
3 A guide to help developers port their code from libical v3.x to libical 4.0.
7 Some CMake option names have been removed or renamed (deprecated) to the LIBICAL namespace.
9 Please change your build scripts to use the new names before the next major release.
13 | Old Name | New Name |
14 |------------------------------|--------------------------------------|
15 | ICAL_ALLOW_EMPTY_PROPERTIES | removed |
16 | ICAL_BUILD_DOCS | LIBICAL_BUILD_DOCS |
17 | ICAL_ERRORS_ARE_FATAL | removed |
18 | ICAL_GLIB | LIBICAL_GLIB |
19 | ICAL_GLIB_VAPI | LIBICAL_GLIB_VAPI |
20 | ICAL_GLIB_BUILD_DOCS | LIBICAL_GLIB_BUILD_DOCS |
21 | USE_BUILTIN_TZDATA | LIBICAL_ENABLE_BUILTIN_TZDATA |
22 | USE_32BIT_TIME_T | LIBICAL_ENABLE_MSVC_32BIT_TIME_T |
23 | GOBJECT_INTROSPECTION | LIBICAL_GOBJECT_INTROSPECTION |
24 | WITH_CXX_BINDINGS | LIBICAL_CXX_BINDINGS |
25 | ENABLE_LTO_BUILD | CMAKE_INTERPROCEDURAL_OPTIMIZATION |
26 | SHARED_ONLY | removed |
27 | STATIC_ONLY | LIBICAL_STATIC |
31 | Old Name | New Name |
32 |------------------------------|--------------------------------------|
33 | ABI_DUMPER | LIBICAL_DEVMODE_ABI_DUMPER |
34 | ADDRESS_SANITIZER | LIBICAL_DEVMODE_ADDRESS_SANITIZER |
35 | LIBICAL_SYNCMODE_THREADLOCAL | LIBICAL_DEVMODE_SYNCMODE_THREADLOCAL |
36 | THREAD_SANITIZER | LIBICAL_DEVMODE_THREAD_SANITIZER |
37 | UNDEFINED_SANITIZER | LIBICAL_DEVMODE_UNDEFINED_SANITIZER |
39 ## Conditional compilation
41 To continue supporting the 3.0 version you can use conditional compilation, like so:
44 #if ICAL_CHECK_VERSION(4,0,0)
45 <...new code for the libical 4.0 version ...>
47 <...old code for the libical 3.0 version ...>
51 you can handle code that no longer exists in 4.0 with:
54 #if !ICAL_CHECK_VERSION(4,0,0)
55 <...old code for the libical 3.0 version ...>
59 ## ICAL_ENABLE_ERRORS_ARE_FATAL
61 The `ICAL_ENABLE_ERRORS_ARE_FATAL` conditional compile macro and accompanying CMake option `ICAL_ENABLE_ERRORS_ARE_FATAL`
64 To abort whenever an error is encountered use the `icalerror_set_errors_are_fatal()` and `icalerror_get_errors_are_fatal()`
67 ## ICAL_ALLOW_EMPTY_PROPERTIES
69 The `ICAL_ALLOW_EMPTY_PROPERTIES` conditional compile macro and accompanying CMake option `ICAL_ALLOW_EMPTY_PROPERTIES`
72 To allow empty properties you can use the new runtime functions `icalproperty_set_allow_empty_properties()`
73 and `icalproperty_get_allow_empty_properties()`.
77 The `PVL_USE_MACROS` conditional compile macro is removed.
78 The pvl unit always compiles the `pvl_data` function.
80 ## ICAL_SETERROR_ISFUNC
82 The `ICAL_SETERROR_ISFUNC` conditional compile macro is removed.
83 The icalerror unit always compiles the `icalerror_set_errno` function.
85 ## ICAL_BOOLEAN_TRUE and ICAL_BOOLEAN_FALSE
87 The `ICAL_BOOLEAN_TRUE` and `ICAL_BOOLEAN_FALSE` macros are removed.
88 The C library is C99 standards compliant and uses bool types.
92 ### Modified functions
94 * `icalrecurrencetype_from_string()` was replaced by `icalrecurrencetype_new_from_string()`,
95 which returns a `struct icalrecurrencetype *` rather than a `struct icalrecurrencetype`.
96 Free the allocated memory using `icalrecurrencetype_unref()`.
98 * The following functions now take arguments of type `struct icalrecurrencetype *` rather than
99 `struct icalrecurrencetype`:
100 * `icalproperty_get_exrule()`
101 * `icalproperty_get_rrule()`
102 * `icalproperty_new_exrule()`
103 * `icalproperty_new_rrule()`
104 * `icalproperty_set_exrule()`
105 * `icalproperty_set_rrule()`
106 * `icalproperty_vanew_exrule()`
107 * `icalproperty_vanew_rrule()`
108 * `icalrecur_iterator_new()`
109 * `icalvalue_get_recur()`
110 * `icalvalue_new_recur()`
111 * `icalvalue_set_recur()`
113 * The following functions now return a value of type `struct icalrecurrencetype *` rather than
114 `struct icalrecurrencetype`:
115 * `icalproperty_get_exrule()`
116 * `icalproperty_get_rrule()`
117 * `icalvalue_get_recur()`
119 * `icaltimezone_convert_time()` now populates the icaltimetype zone member on conversion;
120 i.e. the timezone information is not lost during a conversion.
122 * To more clearly illustrate their intended purpose, the `icaldurationtype_from_int()` and `icaldurationtype_as_int()`
123 have been renamed to `icaldurationtype_from_seconds()` and `icaldurationtype_as_seconds()`, respectively.
124 The functionality of `icaldurationtype_from_seconds` has not changed. The functionality for
125 `icaldurationtype_as_seconds` has changed, such that a duration with days or weeks fails
126 with a ICAL_MALFORMEDDATA_ERROR and returns 0. To preserve the former logic of
127 `icaldurationtype_as_int`, use he newly introduced `icaldurationtype_as_utc_seconds`.
129 * Similarly, the `icaltime_add()` and `icaltime_subtract()` functions are now called
130 `icalduration_extend()` and `icalduration_from_times()`. Their functionality has not changed.
132 * The `get_zone_directory()` and `set_zone_directory()` functions are have been renamed to
133 `icaltimezone_get_zone_directory()` and `icaltimezone_set_zone_directory()`, respectively.
135 * The `icaltzutil_set_zone_directory()` and `icaltzutil_get_zone_directory()` functions are now called
136 `icaltimezone_set_system_zone_directory()` and `icaltimezone_get_system_zone_directory()` respectively.
138 * In previous versions, the `icalvalue_compare()` function returned 0 if unknown or null value types
139 were encountered; in this version, ICAL_XLICCOMPARETYPE_NONE is returned instead.
141 * In previous versions, the `icalcomponent_get_status()` returned 0 if a problem parsing the status
142 property was detected; in this version, ICAL_STATUS_NONE is returned instead.
144 * The `ical_bt()` and `icalerrno_return()` functions have been renamed to
145 `icalerror_backtrace()` and icalerror_icalerrno()` respectively for the sake
146 of consistent function name-spacing.
150 The following functions have been added:
152 * `ical_get_invalid_rrule_handling_setting()`
153 * `ical_set_invalid_rrule_handling_setting()`
154 * `icalarray_set_element_at()`
155 * `icalcluster_clone()`
156 * `icalcompiter_is_valid()`
157 * `icalcomponent_clone()`
158 * `icalcomponent_get_component_name()`
159 * `icalcomponent_get_component_name_r()`
160 * `icalcomponent_get_iana_name()`
161 * `icalcomponent_get_x_name()`
162 * `icalcomponent_new_iana()`
163 * `icalcomponent_set_iana_name()`
164 * `icalcomponent_set_x_name()`
167 * `icalparameter_clone()`
168 * `icalparameter_decode_value()`
169 * `icalparameter_is_multivalued()`
170 * `icalparameter_kind_value_kind()`
171 * `icalparser_get_ctrl()`
172 * `icalparser_set_ctrl()`
173 * `icalproperty_clone()`
174 * `icalproperty_get_allow_empty_properties()`
175 * `icalproperty_get_iana_name()`
176 * `icalproperty_new_iana()`
177 * `icalproperty_set_allow_empty_properties()`
178 * `icalproperty_set_iana_name()`
179 * `icalpropiter_is_valid()`
180 * `icalrecur_iterator_prev()`
181 * `icalrecur_resize_by()`
182 * `icalrecurrencetype_clone()`
183 * `icalrecurrencetype_clone()`
184 * `icalrecurrencetype_encode_day()`
185 * `icalrecurrencetype_encode_month()`
186 * `icalrecurrencetype_new()`
187 * `icalrecurrencetype_new_from_string()`
188 * `icalrecurrencetype_ref()`
189 * `icalrecurrencetype_ref()`
190 * `icalrecurrencetype_unref()`
191 * `icalrecurrencetype_unref()`
192 * `icaltimezone_set_system_zone_directory()`
193 * `icaltimezone_tzid_prefix()`
194 * `icalvalue_clone()`
195 * and the new functions for the `icalstrarray` and `icalenumarray` data types
197 ### Removed functions
199 * `icalmime_parse()` has been removed. Please use another library if you need a MIME parser.
201 * `icaltime_week_number()` has been removed. (it never properly accounted for the
202 start day of the week in different locales).
204 * `icalrecurrencetype_clear()` has been removed.
206 * `icaltimezone_release_zone_tab()` has been removed.
207 Use `icaltimezone_free_builtin_timezones() instead.
209 * `icalrecurrencetype_rscale_is_supported()` has been removed as
210 RSCALE=GREGORIAN is supported without libicu now.
211 Replace `icalrecurrencetype_rscale_is_supported()` calls with a true condition.
213 * These deprecated functions have been removed:
215 * `icalcluster_new_clone()`
216 * `icalcomponent_new_clone()`
217 * `icalparameter_new_clone()`
218 * `icalproperty_new_clone()`
219 * `icalvalue_new_clone()`
222 * No longer publicly visible functions:
223 * `icalerror_assert()`
224 * `icalerror_check_arg()`
225 * `icalerror_check_arg_re()`
226 * `icalerror_check_arg_rv()`
227 * `icalerror_check_arg_rx()`
228 * `icalerror_check_arg_rz()`
229 * `icalerror_check_component_type()`
230 * `icalerror_check_parameter_type()`
231 * `icalerror_check_property_type()`
232 * `icalerror_check_value_type()`
233 * `icalerror_crash_here()`
234 * `icalerror_stop_here()`
237 * `icalproperty_new_impl()`
239 * `icalrecurrencetype_clear()`
240 * `icaltime_span_contains()`
241 * `icaltime_span_new()`
242 * `icaltime_span_overlaps()`
243 * `icaltimezone_array_append_from_vtimezone()`
244 * `icaltimezone_array_free()`
245 * `icaltimezone_array_new()`
246 * `icaltzutil_fetch_timezone()`
250 These convenience macros were added in version 3 to ease porting from older versions.
251 They have been removed in version 4 and should be replaced with their actual function
254 | Old Macro Name | Actual Function Name |
255 |--------------------------------------|----------------------------------------|
256 | icalenum_action_to_string | icalproperty_action_to_string |
257 | icalenum_class_to_string | icalproperty_class_to_string |
258 | icalenum_component_kind_to_string | icalcomponent_kind_to_string |
259 | icalenum_method_to_string | icalproperty_method_to_string |
260 | icalenum_participanttype_to_string | icalproperty_participanttype_to_string |
261 | icalenum_property_kind_to_string | icalproperty_kind_to_string |
262 | icalenum_property_kind_to_value_kind | icalproperty_kind_to_value_kind |
263 | icalenum_resourcetype_to_string | icalproperty_resourcetype_to_string |
264 | icalenum_status_to_string | icalproperty_status_to_string |
265 | icalenum_string_to_action | icalproperty_string_to_action |
266 | icalenum_string_to_class | icalproperty_string_to_class |
267 | icalenum_string_to_component_kind | icalcomponent_string_to_kind |
268 | icalenum_string_to_method | icalproperty_string_to_method |
269 | icalenum_string_to_participanttype | icalproperty_string_to_participanttype |
270 | icalenum_string_to_property_kind | icalproperty_string_to_kind |
271 | icalenum_string_to_resourcetype | icalproperty_string_to_resourcetype |
272 | icalenum_string_to_status | icalproperty_string_to_status |
273 | icalenum_string_to_transp | icalproperty_string_to_transp |
274 | icalenum_string_to_value_kind | icalvalue_string_to_kind |
275 | icalenum_transp_to_string | icalproperty_transp_to_string |
276 | icalenum_value_kind_to_string | icalvalue_kind_to_string |
280 * These data types have been added:
281 * icalstrarray - for manipulating an array of strings
282 * icalenumarray_element - structure to hold a generic enum value
283 * icalenumarray - for manipulating an array of enum elements
285 ### Removed data types
287 * These data structures have been removed (as they were never used):
288 * struct icaltimezonetype
289 * struct icaltimezonephase
291 ### Migrating from 3.0 to 4.0
295 Many function signatures have been changed to use const pointers.
297 ### bool return values
299 A number of function signatures have been changed to use 'bool' rather than 'int' types.
301 This is implemented using the C99 standards compliant <stdbool.h> header.
305 Replace all `ical*_new_clone()` function calls with `ical*_clone()` .
306 ie, use `icalcomponent_clone()` rather then `icalcomponent_new_clone()`.
308 ### `icalrecurrencetype` now passed by reference
310 The way `struct icalrecurrencetype` is passed between functions has been changed. While it was
311 usually passed by value in 3.0, it is now passed by reference. A reference counting mechanism is
312 applied that takes care of de-allocating an instance as soon as the reference counter goes to 0.
314 Code like this in libical 3.0:
317 struct icalrecurrencetype recur;
319 icalrecurrencetype_clear(&recur);
321 // Work with the object
324 changes to this in libical 4.0:
327 struct icalrecurrencetype *recur;
330 recur = icalrecurrencetype_new();
333 // Work with the object
336 icalrecurrencetype_unref(recur);
338 // out of memory error handling
342 ### `icalgeotype` now uses character strings rather than doubles
344 The members of `struct icalgeotype` for latitude ('lat`) and longitude ('lon`) have been changed
345 to use ICAL_GEO_LEN long character strings rather than the double type.
347 This means that simple assignments in 3.0 must be replaced by string copies.
357 strncpy(geo.lat, "0.0", ICAL_GEO_LEN-1);
358 strncpy(geo.lon, "10.0", ICAL_GEO_LEN-1);
364 double lat = geo.lat;
365 double lon = geo.lon;
372 sscanf(geo.lat, "%lf", &lat);
373 sscanf(geo.lon, "%lf", &lon);
378 The `icaltime_adjust` function no longer adjusts null icaltimetypes.
380 ### Working with `icalvalue` and `icalproperty`
382 Code like this in libical 3.0:
385 icalvalue *recur_value = ...;
386 struct icalrecurrencetype recur = icalvalue_get_recur(recur_value);
388 // Work with the object
391 changes to this in libical 4.0:
394 icalvalue *recur_value = ...;
395 struct icalrecurrencetype *recur = icalvalue_get_recur(recur_value);
397 // Work with the object
401 ### Multi-valued parameters
403 Support for these multi-valued parameters is added in libical 4.0.
405 * DELEGATED-FROM (RFC 5545)
406 * DELEGATED-TO (RFC 5545)
411 You can access the 'nth' value for such parameters using the new "_nth" functions.
413 For example, to access the first delegated-to attendee use
416 param = icalproperty_get_first_parameter(prop, ICAL_DELEGATEDTO_PARAMETER);
417 icalparameter_get_delegatedto_nth(param, 0)
422 The `icaltimezone_set_tzid_prefix` function now allows setting an empty prefix.
423 In older libical versions, calling `icaltimezone_set_tzid_prefix` with an empty tzid prefix
424 would reset to the BUILTIN_TZID_PREFIX value (i.e. ""/freeassociation.sourceforge.net/").
426 The new publicly visible function `icaltimezone_tzid_prefix` returns the current tzid prefix string.
428 Note that the tzid prefix must be globally unique (such as a domain name owned by the developer
429 of the calling application), and begin and end with forward slashes. The tzid string must be
430 fewer than 256 characters long.
436 * The following methods now take arguments of type `struct icalrecurrencetype *` rather than `const
437 struct icalrecurrencetype &`:
438 * `ICalProperty.set_exrule()`
439 * `ICalProperty.set_rrule()`
440 * `ICalValue.set_recur()`
442 * The following methods now returns a value of type `struct icalrecurrencetype *` rather than
443 `struct icalrecurrencetype`:
444 * `ICalProperty.get_exrule()`
445 * `ICalProperty.get_rrule()`
446 * `ICalValue.get_recur()`
448 ### `icalrecurrencetype.by_xxx` static arrays replaced by dynamically allocated ones
450 I.e. memory `short by_hour[ICAL_BY_DAY_SIZE]` etc. are replaced by
457 } icalrecurrence_by_data;
459 struct icalrecurrencetype {
461 icalrecurrence_by_data by[ICAL_BY_NUM_PARTS];
465 Memory is allocated in the required size using the new `icalrecur_resize_by()` function. It is
466 automatically freed together with the containing `icalrecurrencetype`. As the size of the array is
467 stored explicitly, no termination of the array with special value `ICAL_RECURRENCE_ARRAY_MAX` is
468 required anymore. The array is iterated by comparing the iterator to the `size` member value.
470 ### Migrating `icalrecurrencetype.by_xxx` static arrays usage from 3.0 to 4.0
472 Code like this in libical 3.0:
475 icalrecurrencetype recur;
477 recur.by_hour[0] = 12;
478 recur.by_hour[1] = ICAL_RECURRENCE_ARRAY_MAX;
481 changes to something like this in libical 4.0:
484 icalrecurrencetype *recur;
486 if (!icalrecur_resize_by(&recur->by[ICAL_BY_HOUR], 1)) {
490 recur.by[ICAL_BY_HOUR].data[0] = 12;
494 ## GLib/Python bindings - changed `ICalGLib.Recurrence.*_by_*` methods
496 `i_cal_recurrence_*_by_xxx*` methods have been replaced by more generic versions that take the 'by'
497 type (day, month, ...) as a parameter.
499 `i_cal_bt` and `i_cal_errno_return` are renamed to `i_calerror_backtrace` and
500 `i_cal_errno_return`, respectively.
502 ### Migrating `ICalGLib.Recurrence.*_by_*` methods from 3.0 to 4.0
504 Code like this in libical 3.0:
507 recurrence.set_by_second(0,
508 recurrence.get_by_second(0) + 1)
511 changes to something like this in libical 4.0:
514 recurrence.set_by(ICalGLib.RecurrenceByRule.BY_SECOND, 0,
515 recurrence.get_by(ICalGLib.RecurrenceByRule.BY_SECOND, 0) + 1)