$darkmode
Libical API Documentation 4.0 STABLE VERSION Visit the v3.0 documentation
/tmp/B.47ejeh9m/BUILD/libical-4.0.3-build/libical-4.0.3/docs/MigrationGuide_to_4.md
1 # Migrating to version 4
2 
3 A guide to help developers port their code from libical v3.x to libical 4.0.
4 
5 ## CMake options
6 
7 Some CMake option names have been removed or renamed (deprecated) to the LIBICAL namespace.
8 
9 Please change your build scripts to use the new names before the next major release.
10 
11 User-specific:
12 
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 |
28 
29 Developer-specific:
30 
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 |
38 
39 ## Conditional compilation
40 
41 To continue supporting the 3.0 version you can use conditional compilation, like so:
42 
43 ```C
44  #if ICAL_CHECK_VERSION(4,0,0)
45  <...new code for the libical 4.0 version ...>
46  #else
47  <...old code for the libical 3.0 version ...>
48  #endif
49 ```
50 
51 you can handle code that no longer exists in 4.0 with:
52 
53 ```C
54  #if !ICAL_CHECK_VERSION(4,0,0)
55  <...old code for the libical 3.0 version ...>
56  #endif
57 ```
58 
59 ## ICAL_ENABLE_ERRORS_ARE_FATAL
60 
61 The `ICAL_ENABLE_ERRORS_ARE_FATAL` conditional compile macro and accompanying CMake option `ICAL_ENABLE_ERRORS_ARE_FATAL`
62 are removed.
63 
64 To abort whenever an error is encountered use the `icalerror_set_errors_are_fatal()` and `icalerror_get_errors_are_fatal()`
65 functions.
66 
67 ## ICAL_ALLOW_EMPTY_PROPERTIES
68 
69 The `ICAL_ALLOW_EMPTY_PROPERTIES` conditional compile macro and accompanying CMake option `ICAL_ALLOW_EMPTY_PROPERTIES`
70 are removed.
71 
72 To allow empty properties you can use the new runtime functions `icalproperty_set_allow_empty_properties()`
73 and `icalproperty_get_allow_empty_properties()`.
74 
75 ## PVL_USE_MACROS
76 
77 The `PVL_USE_MACROS` conditional compile macro is removed.
78 The pvl unit always compiles the `pvl_data` function.
79 
80 ## ICAL_SETERROR_ISFUNC
81 
82 The `ICAL_SETERROR_ISFUNC` conditional compile macro is removed.
83 The icalerror unit always compiles the `icalerror_set_errno` function.
84 
85 ## ICAL_BOOLEAN_TRUE and ICAL_BOOLEAN_FALSE
86 
87 The `ICAL_BOOLEAN_TRUE` and `ICAL_BOOLEAN_FALSE` macros are removed.
88 The C library is C99 standards compliant and uses bool types.
89 
90 ## C library
91 
92 ### Modified functions
93 
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()`.
97 
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()`
112 
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()`
118 
119 * `icaltimezone_convert_time()` now populates the icaltimetype zone member on conversion;
120  i.e. the timezone information is not lost during a conversion.
121 
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`.
128 
129 * Similarly, the `icaltime_add()` and `icaltime_subtract()` functions are now called
130  `icalduration_extend()` and `icalduration_from_times()`. Their functionality has not changed.
131 
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.
134 
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.
137 
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.
140 
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.
143 
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.
147 
148 ### New functions
149 
150 The following functions have been added:
151 
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()`
165 * `icallimit_get()`
166 * `icallimit_set()`
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
196 
197 ### Removed functions
198 
199 * `icalmime_parse()` has been removed. Please use another library if you need a MIME parser.
200 
201 * `icaltime_week_number()` has been removed. (it never properly accounted for the
202  start day of the week in different locales).
203 
204 * `icalrecurrencetype_clear()` has been removed.
205 
206 * `icaltimezone_release_zone_tab()` has been removed.
207  Use `icaltimezone_free_builtin_timezones() instead.
208 
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.
212 
213 * These deprecated functions have been removed:
214  * `caldat()`
215  * `icalcluster_new_clone()`
216  * `icalcomponent_new_clone()`
217  * `icalparameter_new_clone()`
218  * `icalproperty_new_clone()`
219  * `icalvalue_new_clone()`
220  * `juldat()`
221 
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()`
235  * `icalerror_warn()`
236  * `icalerrprintf()`
237  * `icalproperty_new_impl()`
238  * `icalpvl_*()`
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()`
247 
248 ### Removed macros
249 
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
252 names as follows:
253 
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 |
277 
278 ### Added data types
279 
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
284 
285 ### Removed data types
286 
287 * These data structures have been removed (as they were never used):
288  * struct icaltimezonetype
289  * struct icaltimezonephase
290 
291 ### Migrating from 3.0 to 4.0
292 
293 ### const pointers
294 
295 Many function signatures have been changed to use const pointers.
296 
297 ### bool return values
298 
299 A number of function signatures have been changed to use 'bool' rather than 'int' types.
300 
301 This is implemented using the C99 standards compliant <stdbool.h> header.
302 
303 ### Clone functions
304 
305 Replace all `ical*_new_clone()` function calls with `ical*_clone()` .
306 ie, use `icalcomponent_clone()` rather then `icalcomponent_new_clone()`.
307 
308 ### `icalrecurrencetype` now passed by reference
309 
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.
313 
314 Code like this in libical 3.0:
315 
316 ```C
317  struct icalrecurrencetype recur;
318 
319  icalrecurrencetype_clear(&recur);
320 
321  // Work with the object
322 ```
323 
324 changes to this in libical 4.0:
325 
326 ```C
327  struct icalrecurrencetype *recur;
328 
329  // allocate
330  recur = icalrecurrencetype_new();
331  if (recur) {
332 
333  // Work with the object
334 
335  // deallocate
336  icalrecurrencetype_unref(recur);
337  } else {
338  // out of memory error handling
339  }
340 ```
341 
342 ### `icalgeotype` now uses character strings rather than doubles
343 
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.
346 
347 This means that simple assignments in 3.0 must be replaced by string copies.
348 
349 ```C
350  geo.lat = 0.0;
351  geo.lon = 10.0;
352 ```
353 
354 becomes
355 
356 ```C
357  strncpy(geo.lat, "0.0", ICAL_GEO_LEN-1);
358  strncpy(geo.lon, "10.0", ICAL_GEO_LEN-1);
359 ```
360 
361 and
362 
363 ```C
364  double lat = geo.lat;
365  double lon = geo.lon;
366 ```
367 
368 becomes
369 
370 ```C
371  double lat, lon;
372  sscanf(geo.lat, "%lf", &lat);
373  sscanf(geo.lon, "%lf", &lon);
374 ```
375 
376 ## icaltime_adjust
377 
378 The `icaltime_adjust` function no longer adjusts null icaltimetypes.
379 
380 ### Working with `icalvalue` and `icalproperty`
381 
382 Code like this in libical 3.0:
383 
384 ```C
385  icalvalue *recur_value = ...;
386  struct icalrecurrencetype recur = icalvalue_get_recur(recur_value);
387 
388  // Work with the object
389 ```
390 
391 changes to this in libical 4.0:
392 
393 ```C
394  icalvalue *recur_value = ...;
395  struct icalrecurrencetype *recur = icalvalue_get_recur(recur_value);
396 
397  // Work with the object
398  // No need to unref
399 ```
400 
401 ### Multi-valued parameters
402 
403 Support for these multi-valued parameters is added in libical 4.0.
404 
405 * DELEGATED-FROM (RFC 5545)
406 * DELEGATED-TO (RFC 5545)
407 * MEMBER (RFC 5545)
408 * DISPLAY (RFC 7986)
409 * FEATURE (RFC 7986)
410 
411 You can access the 'nth' value for such parameters using the new "_nth" functions.
412 
413 For example, to access the first delegated-to attendee use
414 
415 ```c
416 param = icalproperty_get_first_parameter(prop, ICAL_DELEGATEDTO_PARAMETER);
417 icalparameter_get_delegatedto_nth(param, 0)
418 ```
419 
420 ### Setting the tzid
421 
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/").
425 
426 The new publicly visible function `icaltimezone_tzid_prefix` returns the current tzid prefix string.
427 
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.
431 
432 ## C++ library
433 
434 ### Modified methods
435 
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()`
441 
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()`
447 
448 ### `icalrecurrencetype.by_xxx` static arrays replaced by dynamically allocated ones
449 
450 I.e. memory `short by_hour[ICAL_BY_DAY_SIZE]` etc. are replaced by
451 
452 ```c
453 typedef struct
454 {
455  short *data;
456  short size;
457 } icalrecurrence_by_data;
458 
459 struct icalrecurrencetype {
460  ...
461  icalrecurrence_by_data by[ICAL_BY_NUM_PARTS];
462 }
463 ```
464 
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.
469 
470 ### Migrating `icalrecurrencetype.by_xxx` static arrays usage from 3.0 to 4.0
471 
472 Code like this in libical 3.0:
473 
474 ```C
475  icalrecurrencetype recur;
476  ...
477  recur.by_hour[0] = 12;
478  recur.by_hour[1] = ICAL_RECURRENCE_ARRAY_MAX;
479 ```
480 
481 changes to something like this in libical 4.0:
482 
483 ```C
484  icalrecurrencetype *recur;
485  ...
486  if (!icalrecur_resize_by(&recur->by[ICAL_BY_HOUR], 1)) {
487  // allocation failed
488  // error handling
489  } else {
490  recur.by[ICAL_BY_HOUR].data[0] = 12;
491  }
492 ```
493 
494 ## GLib/Python bindings - changed `ICalGLib.Recurrence.*_by_*` methods
495 
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.
498 
499 `i_cal_bt` and `i_cal_errno_return` are renamed to `i_calerror_backtrace` and
500 `i_cal_errno_return`, respectively.
501 
502 ### Migrating `ICalGLib.Recurrence.*_by_*` methods from 3.0 to 4.0
503 
504 Code like this in libical 3.0:
505 
506 ```python
507  recurrence.set_by_second(0,
508  recurrence.get_by_second(0) + 1)
509 ```
510 
511 changes to something like this in libical 4.0:
512 
513 ```python
514  recurrence.set_by(ICalGLib.RecurrenceByRule.BY_SECOND, 0,
515  recurrence.get_by(ICalGLib.RecurrenceByRule.BY_SECOND, 0) + 1)
516 ```