$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/UsingLibical.md
1 # Using Libical
2 
3 > Author: Eric Busboom <eric@civicknowledge.com>
4 >
5 > Date: January 2001
6 
7 ## 1 Introduction
8 
9 Libical is an Open Source implementation of the iCalendar protocols
10 and protocol data units. The iCalendar specification describes how
11 calendar clients can communicate with calendar servers so users can
12 store their calendar data and arrange meetings with other users.
13 
14 Libical implements multiple [RFC calendar standards](rfcs.md).
15 
16 This documentation assumes that you are familiar with the iCalendar
17 standards [RFC5545][] and [RFC5546][]. These specifications are available
18 at the [IETF Tools][] website:
19 
20 [IETF Tools]: https://tools.ietf.org/
21 [RFC5545]: https://tools.ietf.org/html/rfc5545
22 [RFC5546]: https://tools.ietf.org/html/rfc5546
23 
24 ### 1.1 The libical project
25 
26 This code is under active development. If you would like to contribute
27 to the project, visit <https://libical.github.io/libical/>.
28 
29 ### 1.2 License
30 
31 The code and datafiles in this distribution are licensed under the
32 Mozilla Public License version 2.0. See <https://www.mozilla.org/MPL>
33 for a copy of the license. Alternately, you may use libical under
34 the terms of the GNU Lesser General Public License, version 2.1.
35 See <https://www.gnu.org/licenses/lgpl-2.1.html> for a copy of the LGPL.
36 
37 This dual license ensures that the library can be incorporated into
38 both proprietary code and GPL'd programs, and will benefit from improvements
39 made by programmers in both realms. We (the libical developers) will only
40 accept changes to this library if they are similarly dual-licensed.
41 
42 ### 1.3 Example Code
43 
44 A lot of the documentation for this library is in the form of example
45 code. These examples are in the `examples/` directory of the distribution.
46 Also look in `src/test/` for additional annotated examples.
47 
48 ## 2 Building the Library
49 
50 Libical uses CMake to generate makefiles. It should build with no adjustments on Linux,
51 MacOS and Windows using `gcc`, `clang` and Microsoft Visual. Please report build problems
52 to the [Libical issue tracker](https://github.com/libical/libical/issues).
53 
54 For a more complete guide to building the library, see the
55 [Building Libical](INSTALL.md) instructions.
56 
57 ## 3 Structure
58 
59 The iCalendar data model is based on four types of objects: *components*,
60 *properties*, *values* and *parameters*.
61 
62 Properties are the fundamental unit of information in iCalendar, and they
63 work a bit like a hash entry, with a constant key and a variable value.
64 Properties may also have modifiers, called parameters. In the iCal
65 content line
66 
67 ```ical
68 ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com
69 ```
70 
71 The property name is `ORGANIZER`, the value of the property is `mrbig@host.com`
72 and the `ROLE` parameter specifies that Mr Big is the chair of the
73 meetings associated with this property.
74 
75 Components are groups of properties that represent the core objects
76 of a calendar system, such as events or timezones. Components are
77 delimited by `BEGIN` and `END` tags.
78 
79 When a component is sent across a network, if it is un-encrypted, it
80 will look something like:
81 
82 ```ical
83 BEGIN:VCALENDAR
84 METHOD:REQUEST
85 PRODID: -//hacksw/handcal//NONSGML v1.0//EN
86 BEGIN:VEVENT
87 DTSTAMP:19980309T231000Z
88 UID:guid-1.host1.com
89 ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com
90 ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:
91  MAILTO:employee-A@host.com
92 DESCRIPTION:Project XYZ Review Meeting
93 CATEGORIES:MEETING
94 CLASS:PUBLIC
95 CREATED:19980309T130000Z
96 SUMMARY:XYZ Project Review
97 DTSTART;TZID=US-Eastern:19980312T083000
98 DTEND;TZID=US-Eastern:19980312T093000
99 LOCATION:1CP Conference Room 4350
100 END:VEVENT
101 END:VCALENDAR
102 ```
103 
104 Note that components can be nested; this example has both a VCALENDAR
105 and a VEVENT component, one nested inside the other.
106 
107 ### 3.1 Core iCal classes
108 
109 Libical is an object-based, data-oriented library. Nearly all of the
110 routines in the library are associated with an opaque data types and
111 perform some operation on that data type. Although the library does
112 not actually have classes, we will use those terms since the behavior
113 of these associations of data and routines is very similar to a class.
114 
115 #### 3.1.1 Properties
116 
117 Properties are represented with the `icalproperty` class and its many
118 "derived" classes with one "derived" class per property type in [RFC5545][].
119 Again, there is no actual inheritance relations, but there are clusters
120 of routines that make this term useful. A property is a container
121 for a single value and a set of parameters.
122 
123 #### 3.1.2 Components
124 
125 In libical, components are represented with the `icalcomponent` class.
126 `icalcomponent` is a container for a set of other components and properties.
127 
128 #### 3.1.3 Values
129 
130 Values are represented in a similar way to properties; a base class
131 and many "derived " classes. A value is essentially an abstract handle
132 on a single fundamental type, a structure or a union.
133 
134 #### 3.1.4 Parameters
135 
136 Parameters are represented in a similar way to properties, except that
137 they contain only one value.
138 
139 ### 3.2 Other elements of libical
140 
141 In addition to the core iCal classes, libical has many other types,
142 structures, and classes that aid in creating and using iCal components.
143 
144 #### 3.2.1 Enumerations and types
145 
146 Libical is strongly typed, so every component, property, parameter,
147 and value type has an enumeration, and some have an associated structure
148 or union.
149 
150 #### 3.2.2 The parser
151 
152 The libical parser offers a variety of ways to convert [RFC5545][] text
153 into a libical internal component structure. The parser can parse
154 blocks of text as a string, or it can parse line-by-line.
155 
156 #### 3.2.3 Error objects
157 
158 Libical has a substantial error reporting system for both programming
159 errors and component usage errors.
160 
161 #### 3.2.4 Memory Management
162 
163 Since many of libical's interfaces return strings, the library has its
164 own memory management system to eliminate the need to free every string
165 returned from the library. See [Memory Management](#memory).
166 
167 #### 3.2.5 Storage classes
168 
169 The library also offers several classes to store components to files,
170 memory or databases.
171 
172 ## 4 Differences From RFCs
173 
174 Libical has been designed to follow the standards as closely as possible,
175 so that the key objects in the standards are also key objects in the
176 library. However, there are a few areas where the specifications are
177 (arguably) irregular, and following them exactly would result in an
178 unfriendly interface. These deviations make libical easier to use
179 by maintaining a self-similar interface.
180 
181 ### 4.1 Pseudo Components
182 
183 Libical defines components for groups of properties that look and act
184 like components, but are not defined as components in the specification.
185 `XDAYLIGHT` and `XSTANDARD` are notable examples. These pseudo components
186 group properties within the `VTIMEZONE` components. For instance, the
187 timezone properties associated with daylight savings time starts with
188 `BEGIN:DAYLIGHT` and ends with `END:DAYLIGHT`, just like other components,
189 but is not defined as a component in [RFC5545][] (see [section 3.6.5][RFC5545 3.6.5])
190 In libical, this grouping is represented by the `XDAYLIGHT` component.
191 Standard iCal components all start with the letter "V," while pseudo
192 components start with "X."
193 
194 There are also pseudo components that are conceptually derived classes
195 of `VALARM`. [RFC5546][] defines what properties may be included in each
196 component, and for `VALARM`, the set of properties it may have depends
197 on the value of the `ACTION` property.
198 
199 For instance, if a `VALARM` component has an `ACTION` property with the
200 value of `AUDIO`, the component must also have an `ATTACH` property.
201 However, if the `ACTION` value is `DISPLAY`, the component must have
202 a `DESCRIPTION` property.
203 
204 To handle these various, complex restrictions, libical has pseudo components
205 for each type of alarm: `XAUDIOALARM`, `XDISPLAYALARM`, `XEMAILALARM` and
206 `XPROCEDUREALARM`.
207 
208 [RFC5545 3.6.5]: <https://tools.ietf.org/html/rfc5545#section-3.6.5>
209 
210 ### 4.2 Combined Values
211 
212 Many values can take more than one type. `TRIGGER`, for instance, can
213 have a value type of with `DURATION` or of `DATE-TIME`. These multiple
214 types make it difficult to create routines to return the value associated
215 with a property.
216 
217 It is natural to have interfaces that would return the value of a property,
218 but it is cumbersome for a single routine to return multiple types.
219 So, in libical, properties that can have multiple types are given
220 a single type that is the union of their RFC5545 types. For instance,
221 in libical, the value of the `TRIGGER` property resolves to struct
222 `icaltriggertype`. This type is a union of a `DURATION` and a `DATE-TIME`.
223 
224 ### 4.3 Multi-Valued Properties
225 
226 Some properties, such as `CATEGORIES` have only one value type, but each
227 `CATEGORIES` property can have multiple value instances. This also results
228 in a cumbersome interface -- `CATEGORIES` accessors would have to return
229 a list while all other accessors returned a single value. In libical,
230 all properties have a single value, and multi-valued properties are
231 broken down into multiple single valued properties during parsing.
232 That is, an input line like,
233 
234 ```ical
235 CATEGORIES: work, home
236 ```
237 
238 becomes in libical's internal representation
239 
240 ```ical
241 CATEGORIES: work
242 CATEGORIES: home
243 ```
244 
245 Oddly, [RFC5545][] allows some multi-valued properties (like `FREEBUSY`)
246 to exist as both a multi-values property and as multiple single
247 value properties, while others (like `CATEGORIES`) can only exist
248 as single multi-valued properties. This makes the internal representation
249 for `CATEGORIES` illegal. However when you convert a component to a
250 string, the library will collect all of the `CATEGORIES` properties
251 into one.
252 
253 ## 5 Using libical
254 
255 ### 5.1 Creating Components
256 
257 There are three ways to create components in Libical:
258 
259 1. creating individual objects and assembling them,
260 2. building entire objects in massive vargs calls,
261 3. parsing a text file containing iCalendar data.
262 
263 #### 5.1.1 Constructor Interfaces
264 
265 Using constructor interfaces, you create each of the objects separately
266 and then assemble them in to components:
267 
268 ```c
269 icalcomponent *event;
270 icalproperty *prop;
271 icalparameter *param;
272 struct icaltimetype atime;
273 
274 // create new VEVENT component
275 event = icalcomponent_new(ICAL_VEVENT_COMPONENT);
276 
277 // add DTSTAMP property to the event
278 prop = icalproperty_new_dtstamp(atime);
279 icalcomponent_add_property(event, prop);
280 
281 // add UID property to the event
282 prop = icalproperty_new_uid("guid-1.example.com");
283 icalcomponent_add_property(event, prop);
284 
285 // add ORGANIZER (with ROLE=CHAIR) to the event
286 prop = icalproperty_new_organizer("mrbig@example.com");
287 param = icalparameter_new_role(ICAL_ROLE_CHAIR);
288 icalproperty_add_parameter(prop, param);
289 icalcomponent_add_property(event, prop);
290 ```
291 
292 Notice that libical uses a semi-object-oriented style of interface.
293 Most things you work with are objects, that are instantiated with
294 a constructor that has "new" in the name. Also note that, other than
295 the object reference, most structure data is passed in to libical
296 routines by value. Libical has some complex but very regular memory
297 handling rules. These are detailed in section [Memory Management](#memory).
298 
299 If any of the constructors fail, they will return 0. If you try to
300 insert 0 into a property or component, or use a zero-valued object
301 reference, libical will either silently ignore the error or will abort
302 with an error message. To abort whenever an error is encountered call
303 `icalerror_set_errors_are_fatal(true)`. (see also `icalerror_get_errors_are_fatal()`)
304 
305 #### 5.1.2 varargs Constructors
306 
307 There is another way to create complex components, which is arguably
308 more elegant, if you are not horrified by varargs. The varargs constructor
309 interface allows you to create intricate components in a single block
310 of code. Here is the previous examples in the vaargs style.
311 
312 ```c
313 icalcomponent *calendar;
314 struct icaltimetype atime;
315 
316 calendar =
317  icalcomponent_vanew(
318  ICAL_VCALENDAR_COMPONENT,
319  icalproperty_new_version("2.0"),
320  icalproperty_new_prodid(
321  "-//RDU Software//NONSGML HandCal//EN"),
322  icalcomponent_vanew(
323  ICAL_VEVENT_COMPONENT,
324  icalproperty_new_dtstamp(atime),
325  icalproperty_new_uid("guid-1.host1.com"),
326  icalproperty_vanew_organizer(
327  "mrbig@host.com",
328  icalparameter_new_role(ICAL_ROLE_CHAIR),
329  (void *)0),
330  icalproperty_vanew_attendee(
331  "employee-A@host.com",
332  icalparameter_new_role(
333  ICAL_ROLE_REQPARTICIPANT),
334  icalparameter_new_rsvp(ICAL_RSVP_TRUE),
335  icalparameter_new_cutype(ICAL_CUTYPE_GROUP),
336  (void *)0),
337  icalproperty_new_location(
338  "1CP Conference Room 4350"),
339  (void *)0),
340  (void *)0);
341 ```
342 
343 This form is similar to the constructor form, except that the constructors
344 have `vanew` instead of `new` in the name. The arguments are similar
345 too, except that the component constructor can have a list of properties,
346 and the property constructor can have a list of parameters.
347 
348 *Be sure to terminate every list with a `NULL` (or a *`(void 0)`*, or your code
349 will crash, if you are lucky*. The reason you can't use 0 itself is that
350 depending on what platform you are on, `sizeof(int) ≠ sizeof(void *)`.
351 
352 #### 5.1.3 Parsing Text Files
353 
354 The final way to create components will probably be the most common;
355 you can create components from [RFC5545][] compliant text. If you have
356 the string in memory, use
357 
358 ```c
359 icalcomponent* icalparser_parse_string(char* str);
360 ```
361 
362 If the string contains only one component, the parser will return the
363 component in libical form. If the string contains multiple components,
364 the multiple components will be returned as the children of an
365 `ICAL_XROOT_COMPONENT` component.
366 
367 Parsing a whole string may seem wasteful if you want to pull a large
368 component off of the network or from a file; you may prefer to parse
369 the component line by line. This is possible too by using:
370 
371 ```c
372 icalparser* icalparser_new();
373 
374 void icalparser_free(
375  icalparser* parser);
376 
377 icalparser_get_line(
378  icalparser *parser,
379  char* (*read_stream)(char *s, size_t size, void *d));
380 
381 icalparser_add_line(
382  icalparser *parser,
383  char *line);
384 
385 icalparser_set_gen_data(
386  icalparser *parser,
387  void *data);
388 ```
389 
390 These routines will construct a parser object to which you can add
391 lines of input and retrieve any components that the parser creates
392 from the input. These routines work by specifying an adaptor routine
393 to get string data from a source. For example:
394 
395 ```c
396 char* read_stream(char *s, size_t size, void *d)
397 {
398  return fgets(s, size, (FILE*)d);
399 }
400 
401 int main(int argc, char *argv[])
402 {
403  char *line;
404  icalcomponent *component;
405  icalparser *parser = icalparser_new();
406 
407  // open file (first command-line argument)
408  FILE* stream = fopen(argv[1], "r");
409 
410  // associate the FILE with the parser so that read_stream
411  // will have access to it
412  icalparser_set_gen_data(parser, stream);
413 
414  do {
415  // read the file, line-by-line, and parse the data
416  line = icalparser_get_line(parser, read_stream);
417  component = icalparser_add_line(parser, line);
418 
419  // if icalparser has finished parsing a component,
420  // it will return it
421  if (component != 0) {
422  // print the parsed component
423  printf("%s", icalcomponent_as_ical_string(component));
424  icalparser_clean(parser);
425 
426  printf("\n---------------\n");
427 
428  icalcomponent_free(component);
429  }
430  } while (line != 0);
431 
432  return 0;
433 }
434 ```
435 
436 The parser object parametrizes the routine used to get input lines
437 with `icalparser_set_gen_data()`and `icalparser_get_line()`. In this
438 example, the routine `read_stream()` will fetch the next line from a
439 stream, with the stream passed in as the `void*` parameter d. The parser
440 calls `read_stream()` from `icalparser_get_line()`, but it also needs
441 to know what stream to use. This is set by the call to `icalparser_set_gen_data()`.
442 By using a different routine for `read_stream()` or passing in different
443 data with `icalparser_set_gen_data()`, you can connect to any data source.
444 
445 Using the same mechanism, other implementations could read from memory
446 buffers, sockets or other interfaces.
447 
448 Since the example code is a very common way to use the parser, there
449 is a convenience routine;
450 
451 ```c
452 icalcomponent* icalparser_parse(
453  icalparser *parser,
454  char* (*line_gen_func)(char *s, size_t size, void *d));
455 ```
456 
457 To use this routine, you still must construct the parser object and
458 pass in a reference to a line reading routine. If the parser can create
459 a single component from the input, it will return a pointer to the
460 newly constructed component. If the parser can construct multiple
461 components from the input, it will return a reference to an `XROOT`
462 component (of type `ICAL_XROOT_COMPONENT`.) This `XROOT` component will
463 hold all of the components constructed from the input as children.
464 
465 ```c
466 char* read_stream(char *s, size_t size, void *d)
467 {
468  return fgets(s, size, (FILE*)d);
469 }
470 
471 int main(int argc, char *argv[])
472 {
473  char* line;
474  icalcomponent *component;
475  icalparser *parser = icalparser_new();
476 
477  // open file (first command-line argument)
478  FILE* stream = fopen(argv[1], "r");
479 
480  // associate the FILE with the parser so that read_stream
481  // will have access to it
482  icalparser_set_gen_data(parser, stream);
483 
484  // parse the opened file
485  component = icalparser_parse(parser, read_stream);
486 
487  if (component != 0) {
488  // print the parsed component
489  printf("%s", icalcomponent_as_ical_string(component));
490  icalcomponent_free(component);
491  }
492 
493  icalparser_free(parser);
494 
495  return 0;
496 }
497 ```
498 
499 ### 5.2 Accessing Components
500 
501 Given a reference to a component, you probably will want to access
502 the properties, parameters and values inside. Libical interfaces let
503 you find sub-component, add and remove sub-components, and do the
504 same three operations on properties.
505 
506 #### 5.2.1 Finding Components
507 
508 To find a sub-component of a component, use:
509 
510 ```c
511 icalcomponent* icalcomponent_get_first_component(
512  icalcomponent* component,
513  icalcomponent_kind kind);
514 ```
515 
516 This routine will return a reference to the first component of the
517 type `kind`. The key kind values, listed in icalenums.h are:
518 
519 - `ICAL_ANY_COMPONENT`
520 - `ICAL_VEVENT_COMPONENT`
521 - `ICAL_VTODO_COMPONENT`
522 - `ICAL_VJOURNAL_COMPONENT`
523 - `ICAL_VCALENDAR_COMPONENT`
524 - `ICAL_VFREEBUSY_COMPONENT`
525 - `ICAL_VALARM_COMPONENT`
526 
527 These are only the most common components; there are many more listed
528 in icalenums.h.
529 
530 As you might guess, if there is more than one subcomponent of the type
531 you have chosen, this routine will return only the first. to get at
532 the others, you need to iterate through the component.
533 
534 #### 5.2.2 Iterating Through Components
535 
536 Iteration requires a second routine to get the next subcomponent after
537 the first:
538 
539 ```c
540 icalcomponent* icalcomponent_get_next_component(
541  icalcomponent* component,
542  icalcomponent_kind kind);
543 ```
544 
545 With the 'first' and 'next' routines, you can create a for loop to
546 iterate through all of a components subcomponents
547 
548 ```c
549 icalcomponent *c;
550 
551 for(c = icalcomponent_get_first_component(comp, ICAL_ANY_COMPONENT);
552  c != 0;
553  c = icalcomponent_get_next_component(comp, ICAL_ANY_COMPONENT))
554 {
555  do_something(c);
556 }
557 ```
558 
559 This code bit will iterate through all of the subcomponents in `comp`
560 but you can select a specific type of component by changing `ICAL_ANY_COMPONENT`
561 to another component type.
562 
563 #### 5.2.3 Using Component Iterators
564 
565 The iteration model in the previous section requires the component
566 to keep the state of the iteration. So, you could not use this model
567 to perform a sorting operations, since you'd need two iterators and
568 there is only space for one. If you ever call `icalcomponent_get_first_component()`
569 when an iteration is in progress, the pointer will be reset to the
570 beginning.
571 
572 To solve this problem, there are also external iterators for components.
573 The routines associated with these external iterators are:
574 
575 ```c
576 icalcompiter icalcomponent_begin_component(
577  icalcomponent* component,
578  icalcomponent_kind kind);
579 
580 icalcompiter icalcomponent_end_component(
581  icalcomponent* component,
582  icalcomponent_kind kind);
583 
584 icalcomponent* icalcompiter_next(
585  icalcompiter* i);
586 
587 icalcomponent* icalcompiter_prior(
588  icalcompiter* i);
589 
590 icalcomponent* icalcompiter_deref(
591  icalcompiter* i);
592 ```
593 
594 The `*_begin_*()` and `*_end_*()` routines return a new iterator that points
595 to the beginning and end of the list of subcomponent for the given
596 component, and the kind argument works like the kind argument for
597 internal iterators.
598 
599 After creating an iterators, use `*_next()` and `*_prior()` to step forward
600 and backward through the list and get the component that the iterator
601 points to, and use `_deref()` to return the component that the iterator
602 points to without moving the iterator. All routines will return 0
603 when they move to point off the end of the list.
604 
605 Here is an example of a loop using these routines:
606 
607 ```c
608 for(i = icalcomponent_begin_component(impl->cluster, ICAL_ANY_COMPONENT);
609  icalcompiter_deref(&i)!= 0;
610  icalcompiter_next(&i))
611 {
612  icalcomponent *this = icalcompiter_deref(&i);
613 }
614 ```
615 
616 #### 5.2.4 Removing Components
617 
618 Removing an element from a list while iterating through the list with
619 the internal iterators can cause problems, since you will probably
620 be removing the element that the internal iterator points to. The
621 `_remove()` routine will keep the iterator valid by moving it to the
622 next component, but in a normal loop, this will result in two advances
623 per iteration, and you will remove only every other component. To
624 avoid the problem, you will need to step the iterator ahead of the
625 element you are going to remove, like this:
626 
627 ```c
628 for(c = icalcomponent_get_first_component(parent_comp, ICAL_ANY_COMPONENT);
629  c != 0;
630  c = next)
631 {
632  next = icalcomponent_get_next_component(parent_comp, ICAL_ANY_COMPONENT);
633  icalcomponent_remove_component(parent_comp,c);
634 }
635 ```
636 
637 Another way to remove components is to rely on the side effect of
638 `icalcomponent_remove_component()`:
639 if component iterator in the parent component is pointing to the child
640 that will be removed, it will move the iterator to the component after
641 the child. The following code will exploit this behavior:
642 
643 ```c
644 icalcomponent_get_first_component(parent_comp,ICAL_VEVENT_COMPONENT);
645 
646 while((c=icalcomponent_get_current_component(c)) != 0){
647  if(icalcomponent_isa(c) == ICAL_VEVENT_COMPONENT){
648  icalcomponent_remove_component(parent_comp,inner);
649  } else {
650  icalcomponent_get_next_component(parent_comp,ICAL_VEVENT_COMPONENT);
651  }
652 }
653 ```
654 
655 #### 5.2.5 Working with properties and parameters
656 
657 Finding, iterating and removing properties works the same as it does
658 for components, using the property-specific or parameter-specific
659 interfaces:
660 
661 ```c
662 icalproperty* icalcomponent_get_first_property(
663  icalcomponent* component,
664  icalproperty_kind kind);
665 
666 icalproperty* icalcomponent_get_next_property(
667  icalcomponent* component,
668  icalproperty_kind kind);
669 
670 void icalcomponent_add_property(
671  icalcomponent* component,
672  icalproperty* property);
673 
674 void icalcomponent_remove_property(
675  icalcomponent* component,
676  icalproperty* property);
677 ```
678 
679 For parameters:
680 
681 ```c
682 icalparameter* icalproperty_get_first_parameter(
683  icalproperty* prop,
684  icalparameter_kind kind);
685 
686 icalparameter* icalproperty_get_next_parameter(
687  icalproperty* prop,
688  icalparameter_kind kind);
689 
690 void icalproperty_add_parameter(
691  icalproperty* prop,
692  icalparameter* parameter);
693 
694 void icalproperty_remove_parameter_by_kind(
695  icalproperty* prop,
696  icalparameter_kind kind);
697 ```
698 
699 Note that since there should be only one parameter of each type in
700 a property, you will rarely need to use `icalparameter_get_next_parameter()`.
701 
702 #### 5.2.6 Working with values
703 
704 Values are typically part of a property, although they can exist on
705 their own. You can manipulate them either as part of the property
706 or independently.
707 
708 The most common way to work with values to is to manipulate them from
709 the properties that contain them. This involves fewer routine calls
710 and intermediate variables than working with them independently, and
711 it is type-safe.
712 
713 For each property, there are a `_get_()` and a `_set_()` routine that
714 accesses the internal value. For instanace, for the `UID` property, the
715 routines are:
716 
717 ```c
718 void icalproperty_set_uid(
719  icalproperty* prop,
720  const char* v);
721 
722 const char* icalproperty_get_uid(
723  icalproperty* prop);
724 ```
725 
726 For multi-valued properties, like `ATTACH`, the value type is usually
727 a struct or union that holds both possible types.
728 
729 If you want to work with the underlying value object, you can get and
730 set it with:
731 
732 ```c
733 icalvalue* icalproperty_get_value(
734  icalproperty* prop);
735 
736 void icalproperty_set_value(
737  icalproperty* prop,
738  icalvalue* value);
739 ```
740 
741 `icalproperty_get_value()` will return a reference that you can manipulate
742 with other icalvalue routines. Most of the time, you will have to
743 know what the type of the value is. For instance, if you know that
744 the value is a `DATETIME` type, you can manipulate it with:
745 
746 ```c
747 struct icaltimetype icalvalue_get_datetime(
748  icalvalue* value);
749 
750 void icalvalue_set_datetime(
751  icalvalue* value,
752  struct icaltimetype v);
753 ```
754 
755 Some complex value types, such as `ATTACH` and `RECUR`, are passed by reference
756 rather than by value. For example, when using `icalvalue_get_recur()`, you
757 receive a reference to the internal state of the value object. Conversely, when
758 setting these values, the value object retains a reference to the original
759 object instead of creating a copy.
760 
761 **Caution:** Manipulating this referenced object will also modify the owning
762 value object.
763 
764 Be mindful of the memory management for these objects, which is managed through
765 reference counting. For more details, see [Memory Management](#memory).
766 
767 When working with an extension property or value (and `X-PROPERTY` or
768 a property that has the parameter `VALUE=x-name`), the value type is
769 always a string. To get and set the value, use:
770 
771 ```x
772 void icalproperty_set_x(
773  icalproperty* prop,
774  char* v);
775 
776 char* icalproperty_get_x(
777  icalproperty* prop);
778 ```
779 
780 All X properties have the type of `ICAL_X_PROPERTY`, so you will need
781 these routines to get and set the name of the property:
782 
783 ```c
784 char* icalproperty_get_x_name(
785  icalproperty* prop)
786 
787 void icalproperty_set_x_name(
788  icalproperty* prop,
789  char* name);
790 ```
791 
792 #### 5.2.7 Checking Component Validity
793 
794 [RFC5546][] defines rules for what properties must exist in a component
795 to be used for transferring scheduling data. Most of these rules relate
796 to the existence of properties relative to the `METHOD` property, which
797 declares what operation a remote receiver should use to process a
798 component. For instance, if the `METHOD` is `REQUEST` and the component
799 is a `VEVENT`, the sender is probably asking the receiver to join in
800 a meeting. In this case, RFC5546 says that the component must specify
801 a start time (`DTSTART`) and list the receiver as an attendee
802 (`ATTENDEE`).
803 
804 Libical can check these restrictions with the routine:
805 
806 ```c
807 int icalrestriction_check(icalcomponent* comp);
808 ```
809 
810 This routine returns 0 if the component does not pass RFC5546 restrictions,
811 or if the component is malformed. The component you pass in must be
812 a `VCALENDAR`, with one or more children, like the examples in RFC5546.
813 
814 When this routine runs, it will insert new properties into the component
815 to indicate any errors it finds. See section 6.5.3, `X-LIC-ERROR` for
816 more information about these error properties.
817 
818 5.2.8 Converting Components to Text
819 
820 To create an RFC5545 compliant text representation of an object, use
821 one of the `*_as_ical_string()` routines:
822 
823 ```c
824 char* icalcomponent_as_ical_string(icalcomponent* component)
825 
826 char* icalproperty_as_ical_string(icalproperty* property)
827 
828 char* icalparameter_as_ical_string(icalparameter* parameter)
829 
830 char* icalvalue_as_ical_string(icalvalue* value)
831 ```
832 
833 In most cases, you will only use `icalcomponent_as_ical_string()`, since
834 it will cascade and convert all of the parameters, properties and
835 values that are attached to the root component.
836 
837 Remember that the string returned by these routines is owned by the
838 library, and will eventually be re-written. You should copy it if
839 you want to preserve it.
840 
841 ### 5.3 Time
842 
843 #### 5.3.1 Time structure
844 
845 Libical defines its own time structure for storing all dates and times.
846 It would have been nice to reuse the C library's struct `tm`, but that
847 structure does not differentiate between dates and times, and between
848 local time and UTC. The libical structure is:
849 
850 ```c
851 struct icaltimetype {
852  int day;
853  int hour;
854  int is_date; /* 1 -> interpret this as date. */
855  int is_daylight; /* 1 -> time is in daylight savings time. */
856  int minute;
857  int month;
858  int second;
859  int year;
860  const icaltimezone * zone; /* timezone */
861 };
862 ```
863 
864 The `year`, `month`, `day`, `hour`, `minute` and `second` fields hold the
865 broken-out time values. The `is_date` field indicates if the time should be
866 interpreted only as a date. If it is a date, the hour, minute and second fields
867 are assumed to be zero, regardless of their actual values. The `is_daylight`
868 field indicates if the time is in daylight savings time. The `zone` field holds
869 a struct representing a timezone.
870 
871 #### 5.3.2 Creating time structures
872 
873 There are several ways to create a new icaltimetype structure:
874 
875 ```c
876 struct icaltimetype icaltime_from_string(
877  const char* str);
878 
879 struct icaltimetype icaltime_from_timet_with_zone(
880  icaltime_t v,
881  int is_date,
882  icaltimezone* zone);
883 ```
884 
885 `icaltime_from_string()` takes any RFC5545 compliant time string:
886 
887 ```c
888 struct icaltimetype tt = icaltime_from_string("19970101T103000");
889 ```
890 
891 `icaltime_from_timet_with_zone()` takes a `icaltime_t` value, representing seconds past
892 the POSIX epoch, a flag to indicate if the time is a date, and a time zone.
893 Dates have an identical structure to a time, but the time portion (hours,
894 minutes and seconds) is always 00:00:00. Dates act differently in
895 sorting and comparison, and they have a different string representation
896 in [RFC5545][].
897 
898 #### 5.3.3 Time manipulating routines
899 
900 The `null` time value is used to indicate that the data in the structure
901 is not a valid time.
902 
903 ```c
904 struct icaltimetype icaltime_null_time(void);
905 
906 int icaltime_is_null_time(struct icaltimetype t);
907 ```
908 
909 It is sensible for the broken-out time fields to contain values that
910 are not permitted in an ISO compliant time string. For instance, the
911 seconds field can hold values greater than 59, and the hours field
912 can hold values larger than 24. The excessive values will be rolled
913 over into the next larger field when the structure is normalized.
914 
915 ```c
916 struct icaltimetype icaltime_normalize(struct icaltimetype t);
917 ```
918 
919 Normalizing allows you to do arithmetic operations on time values.
920 
921 ```c
922 struct icaltimetype tt = icaltime_from_string("19970101T103000");
923 
924 tt.days +=3
925 tt.second += 70;
926 
927 tt = icaltime_normalize(tt);
928 ```
929 
930 There are several routines to get the day of the week or month, etc,
931 from a time structure.
932 
933 ```c
934 short icaltime_day_of_year(
935  struct icaltimetype t);
936 
937 struct icaltimetype icaltime_from_day_of_year(
938  short doy,
939  short year);
940 
941 short icaltime_day_of_week(
942  struct icaltimetype t);
943 
944 short icaltime_start_doy_week(
945  struct icaltimetype t,
946  int fdow);
947 
948 short icaltime_days_in_month(
949  short month,
950  short year);
951 ```
952 
953 Two routines convert time structures to and from the number of seconds
954 since the POSIX epoch. The `is_date` field indicates whether or not
955 the hour, minute and second fields should be used in the conversion.
956 
957 ```c
958 struct icaltimetype icaltime_from_timet_with_zone(
959  icaltime_t v,
960  int is_date,
961  icaltimezone* zone);
962 
963 icaltime_t icaltime_as_timet(
964  struct icaltimetype);
965 ```
966 
967 The compare routine works exactly like `strcmp()`, but on time structures.
968 
969 ```c
970 int icaltime_compare(
971  struct icaltimetype a,
972  struct icaltimetype b);
973 ```
974 
975 The following routines convert between UTC and a named timezone. The
976 tzid field must be a timezone name from the Olsen database, such as
977 `America/Los_Angeles`.
978 
979 The `utc_offset` routine returns the offset of the named time zone from
980 UTC, in seconds.
981 
982 The `tt` parameter in the following routines indicates the date on which
983 the conversion should be made. The parameter is necessary because
984 timezones have many different rules for when daylight savings time
985 is used, and these rules can change over time. So, for a single timezone
986 one year may have daylight savings time on March 15, but for other
987 years March 15 may be standard time, and some years may have standard
988 time all year.
989 
990 ```c
991 int icaltime_utc_offset(
992  struct icaltimetype tt,
993  char* tzid);
994 
995 int icaltime_local_utc_offset();
996 
997 struct icaltimetype icaltime_as_utc(
998  struct icaltimetype tt,
999  char* tzid);
1000 
1001 struct icaltimetype icaltime_as_zone(
1002  struct icaltimetype tt,
1003  char* tzid);
1004 
1005 struct icaltimetype icaltime_as_local(
1006  struct icaltimetype tt);
1007 ```
1008 
1009 ### 5.4 Storing Objects
1010 
1011 The libical distribution includes a separate library, libicalss, that
1012 allows you to store iCal component data to disk in a variety of ways.
1013 
1014 The file storage routines are organized in an inheritance hierarchy
1015 that is rooted in icalset, with the derived class icalfileset and
1016 icaldirset. Icalfileset stores components to a file, while icaldirset
1017 stores components to multiple files, one per month based on DTSTAMP.
1018 Other storages classes, for storage to a heap or a mysql database
1019 for example, could be added in the future.
1020 
1021 All of the icalset derived classes have the same interface:
1022 
1023 ```c
1024 icaldirset* icaldirset_new(
1025  const char* path);
1026 
1027 void icaldirset_free(
1028  icaldirset* store);
1029 
1030 const char* icaldirset_path(
1031  icaldirset* store);
1032 
1033 void icaldirset_mark(
1034  icaldirset* store);
1035 
1036 icalerrorenum icaldirset_commit(
1037  icaldirset* store);
1038 
1039 icalerrorenum icaldirset_add_component(
1040  icaldirset* store,
1041  icalcomponent* comp);
1042 
1043 icalerrorenum icaldirset_remove_component(
1044  icaldirset* store,
1045  icalcomponent* comp);
1046 
1047 int icaldirset_count_components(
1048  icaldirset* store,
1049  icalcomponent_kind kind);
1050 
1051 icalerrorenum icaldirset_select(
1052  icaldirset* store,
1053  icalcomponent* gauge);
1054 
1055 void icaldirset_clear(
1056  icaldirset* store);
1057 
1058 icalcomponent* icaldirset_fetch(
1059  icaldirset* store,
1060  const char* uid);
1061 
1062 int icaldirset_has_uid(
1063  icaldirset* store,
1064  const char* uid);
1065 
1066 icalcomponent* icaldirset_fetch_match(
1067  icaldirset* set,
1068  icalcomponent *c);
1069 
1070 icalerrorenum icaldirset_modify(
1071  icaldirset* store,
1072  icalcomponent *oldc,
1073  icalcomponent *newc);
1074 
1075 icalcomponent* icaldirset_get_current_component(
1076  icaldirset* store);
1077 
1078 icalcomponent* icaldirset_get_first_component(
1079  icaldirset* store);
1080 
1081 icalcomponent* icaldirset_get_next_component(
1082  icaldirset* store);
1083 ```
1084 
1085 #### 5.4.1 Creating a new set
1086 
1087 You can create a new set from either the base class or the direved
1088 class. From the base class use one of:
1089 
1090 ```c
1091 icalset* icalset_new_file(const char* path);
1092 
1093 icalset* icalset_new_dir(const char* path);
1094 
1095 icalset* icalset_new_heap(void);
1096 
1097 icalset* icalset_new_mysql(const char* path);
1098 ```
1099 
1100 You can also create a new set based on the derived class, For instance,
1101 with icalfileset:
1102 
1103 ```c
1104 icalfileset* icalfileset_new(
1105  const char* path);
1106 
1107 icalfileset* icalfileset_new_open(
1108  const char* path,
1109  int flags,
1110  int mode);
1111 ```
1112 
1113 `icalset_new_file()` is identical to `icalfileset_new()`. Both routines will
1114 open an existing file for reading and writing, or create a new file
1115 if it does not exist. `icalfileset_new_open()` takes the same arguments
1116 as the open() system routine and behaves in the same way.
1117 
1118 The icalset and icalfileset objects are somewhat interchangeable -- you
1119 can use an `icalfileset*` as an argument to any of the icalset routines.
1120 
1121 The following examples will all use icalfileset routines; using the
1122 other icalset derived classes will be similar.
1123 
1124 #### 5.4.2 Adding, Finding and Removing Components
1125 
1126 To add components to a set, use:
1127 
1128 ```c
1129 icalerrorenum icalfileset_add_component(
1130  icalfileset* cluster,
1131  icalcomponent* child);
1132 ```
1133 
1134 The fileset keeps an in-memory copy of the components, and this set
1135 must be written back to the file occasionally. There are two routines
1136 to manage this:
1137 
1138 ```c
1139 void icalfileset_mark(icalfileset* cluster);
1140 
1141 icalerrorenum icalfileset_commit(icalfileset* cluster);
1142 ```
1143 
1144 `icalfileset_mark()` indicates that the in-memory components have changed.
1145 Calling the `_add_component()` routine will call `_mark()` automatically,
1146 but you may need to call it yourself if you have made a change to
1147 an existing component. The `_commit()` routine writes the data base to
1148 disk, but only if it is marked. The `_commit()` routine is called automatically
1149 when the icalfileset is freed.
1150 
1151 To iterate through the components in a set, use:
1152 
1153 ```c
1154 icalcomponent* icalfileset_get_first_component(icalfileset* cluster);
1155 
1156 icalcomponent* icalfileset_get_next_component(icalfileset* cluster);
1157 
1158 icalcomponent* icalfileset_get_current_component (icalfileset* cluster);
1159 ```
1160 
1161 These routines work like the corresponding routines from icalcomponent,
1162 except that their output is filtered through a gauge. A gauge is a
1163 test for the properties within a components; only components that
1164 pass the test are returned. A gauge can be constructed from a MINSQL
1165 string with:
1166 
1167 ```c
1168 icalgauge* icalgauge_new_from_sql(const char* sql);
1169 ```
1170 
1171 Then, you can add the gauge to the set with :
1172 
1173 ```c
1174 icalerrorenum icalfileset_select(
1175  icalfileset* store,
1176  icalgauge* gauge);
1177 ```
1178 
1179 Here is an example that puts all of these routines together:
1180 
1181 ```c
1182 void test_fileset()
1183 {
1184  icalfileset *fs;
1185  icalcomponent *c;
1186  int i;
1187  char *path = "test_fileset.ics";
1188 
1189  icalgauge *g = icalgauge_new_from_sql(
1190  "SELECT * FROM VEVENT WHERE DTSTART > '20000103T120000Z' AND
1191 DTSTART <= '20000106T120000Z'");
1192 
1193  fs = icalfileset_new(path);
1194 
1195  for (i = 0; i!= 10; i++){
1196  c = make_component(i); /* Make a new component where DTSTART has month of i */
1197  icalfileset_add_component(fs,c);
1198  }
1199 
1200  icalfileset_commit(fs); /* Write to disk */
1201  icalfileset_select(fs,g); /* Set the gauge to filter components */
1202 
1203  for (c = icalfileset_get_first_component(fs);
1204  c != 0;
1205  c = icalfileset_get_next_component(fs))
1206  {
1207  struct icaltimetype t = icalcomponent_get_dtstart(c);
1208  printf("%s\n",icaltime_as_ctime(t));
1209 
1210  }
1211 
1212  icalfileset_free(fs);
1213 }
1214 ```
1215 
1216 #### 5.4.3 Other routines
1217 
1218 There are several other routines in the icalset interface, but they
1219 not fully implemented yet.
1220 
1221 #### 5.5 Memory Management
1222 
1223 <a id="memory"></a>
1224 Libical relies heavily on dynamic allocation for both the core objects
1225 and for the strings used to hold values. Some of this memory the library
1226 caller owns and must free, and some of the memory is managed by the
1227 library. Here is a summary of the memory rules.
1228 
1229 1. If the function name has "new" in it (such as `icalcomponent_new()`,
1230  or `icalproperty_new_from_string()`), the caller gets control
1231  of the memory. The caller also gets control over an object that is
1232  cloned via a function that ends with "_clone" (like `icalcomponent_clone()`)
1233 
1234 2. If you got the memory from a routine with "clone" or "new" in it, you
1235  must call the corresponding `*_free()` routine to free the memory,
1236  for example use `icalcomponent_free()` to free objects created with
1237  `icalcomponent_new()` or `icalcomponent_clone()`. The only exception
1238  to this rule are objects that implement reference counting (i.e.
1239  `icalattach` and `icalrecurrencetype`), which are deallocated via
1240  `*_unref()` functions. Learn more in the next section.
1241 
1242 3. If the function name has "add" in it, the caller is transferring
1243  control of the memory to the routine, for example the function
1244  `icalproperty_add_parameter()`
1245 
1246 4. If the function name has "remove" in it, the caller passes in
1247  a pointer to an object and after the call returns, the caller owns
1248  the object. So, before you call `icalcomponent_remove_property(comp, foo)`,
1249  you do not own "foo" and after the call returns, you do.
1250 
1251 5. If the routine returns a string and its name does NOT end in `_r`,
1252  libical owns the memory and will put it on a ring buffer to reclaim
1253  later. For example, `icalcomponent_as_ical_string()`. You better
1254  `strdup()` it if you want to keep it, and you don't have to delete it.
1255 
1256 6. If the routine returns a string and its name *does* end in `_r`, the
1257  caller gets control of the memory and is responsible for freeing it.
1258  For example, `icalcomponent_as_ical_string_r()` does the same thing as
1259  `icalcomponent_as_ical_string()`, except you now have control of the
1260  string buffer it returns.
1261 
1262 #### 5.5.1 Reference Counting
1263 
1264 Some special types are managed using reference counting, in particular:
1265 
1266 - `icalattach`
1267 - `struct icalrecurrencetype`
1268 
1269 Just as any other object they are allocated using any of the `*_new*()` functions, e.g.
1270 
1271 - `icalrecurrencetype_new_from_string()`
1272 - `icalattach_new_from_data()`
1273 
1274 When an object is returned by one of these constructor functions, its reference counter is set to 1.
1275 
1276 The reference counter can be modified using:
1277 
1278 - `*_ref()` – to increase the counter.
1279 - `*_unref()` – to decrease the counter.
1280 
1281 The object is automatically deallocated when the reference counter reaches 0.
1282 No explicit `*_free()` functions exist for these types.
1283 
1284 When such objects are passed to functions as arguments, it is the task of the function being called
1285 to manage the reference counter, not of the caller. If a pointer to an object is returned by a
1286 function other than the constructor functions, it is the task of the calling function rather than
1287 of the returning function to manage the reference counter.
1288 
1289 ### 5.6 Error Handling
1290 
1291 Libical has several error handling mechanisms for the various types
1292 of programming, semantic and syntactic errors you may encounter.
1293 
1294 #### 5.6.1 Return values
1295 
1296 Many library routines signal errors through their return values. All
1297 routines that return a pointer, such as `icalcomponent_new()`, will
1298 return 0 (zero) on a fatal error. Some routines will return a value
1299 of enum `icalerrorenum`.
1300 
1301 5.6.2 `icalerrno`
1302 
1303 Most routines will set the global error value `icalerrno` on errors.
1304 This variable is an enumeration; permissible values can be found in
1305 `libical/icalerror.h`. If the routine returns an enum icalerrorenum,
1306 then the return value will be the same as icalerrno. You can use
1307 `icalerror_strerror()` to get a string that describes the error.
1308 The enumerations are:
1309 
1310 - `ICAL_BADARG_ERROR`: One of the arguments to a routine was bad.
1311  Typically for a null pointer.
1312 
1313 - `ICAL_NEWFAILED_ERROR`: A `new()` or `malloc()` failed.
1314 
1315 - `ICAL_MALFORMEDDATA_ERROR`: An input string was not in the correct format
1316 
1317 - `ICAL_PARSE_ERROR`: The parser failed to parse an incoming component
1318 
1319 - `ICAL_INTERNAL_ERROR`: Largely equivalent to an assert
1320 
1321 - `ICAL_FILE_ERROR`: A file operation failed. Check errno for more detail.
1322 
1323 - `ICAL_ALLOCATION_ERROR`: ?
1324 
1325 - `ICAL_USAGE_ERROR`: ?
1326 
1327 - `ICAL_NO_ERROR`: No error
1328 
1329 - `ICAL_MULTIPLEINCLUSION_ERROR`: ?
1330 
1331 - `ICAL_TIMEDOUT_ERROR`: For CSTP and acquiring locks
1332 
1333 - `ICAL_UNKNOWN_ERROR`: ?
1334 
1335 #### 5.6.3 `X-LIC-ERROR` and `X-LIC-INVALID-COMPONENT`
1336 
1337 The library handles semantic and syntactic errors in components by
1338 inserting errors properties into the components. If the parser cannot
1339 parse incoming text (a syntactic error) or if the `icalrestriction_check()`
1340 routine indicates that the component does not meet the requirements
1341 of RFC5546 (a semantic error) the library will insert properties
1342 of the type `X-LIC-ERROR` to describe the error. Here is an example
1343 of the error property:
1344 
1345 ```ical
1346 X-LIC-ERROR;X-LIC-ERRORTYPE=INVALID_ITIP :Failed iTIP restrictions
1347 for property DTSTART.
1348 
1349 Expected 1 instances of the property and got 0
1350 ```
1351 
1352 This error resulted from a call to `icalrestriction_check()`, which discovered
1353 that the component does not have a `DTSTART` property, as required by
1354 RFC5545.
1355 
1356 There are a few routines to manipulate error properties:
1357 
1358 | Routine | Purpose |
1359 |:--------------------------------------|:-----------------------------------------------------------------------------------------|
1360 | `void icalrestriction_check()` | Check a component against RFC5546 and insert error properties to indicate non compliance |
1361 | `int icalcomponent_count_errors()` | Return the number of error properties in a component |
1362 | `void icalcomponent_strip_errors()` | Remove all error properties in a component |
1363 | `void icalcomponent_convert_errors()` | Convert some error properties into REQUESTS-STATUS properties to indicate the inability |
1364 | | to process the component as an iTIP request |
1365 
1366 The types of errors are listed in icalerror.h. They are:
1367 
1368 - `ICAL_XLICERRORTYPE_COMPONENTPARSEERROR`
1369 - `ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR`
1370 - `ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR`
1371 - `ICAL_XLICERRORTYPE_PROPERTYPARSEERROR`
1372 - `ICAL_XLICERRORTYPE_VALUEPARSEERROR`
1373 - `ICAL_XLICERRORTYPE_UNKVCALPROP`
1374 - `ICAL_XLICERRORTYPE_INVALIDITIP`
1375 
1376 The libical parser will generate the error that end in `PARSEERROR` when
1377 it encounters garbage in the input steam. `ICAL_XLICERRORTYPE_INVALIDITIP`
1378 is inserted by `icalrestriction_check()`, and `ICAL_XLICERRORTYPE_UNKVCALPROP`
1379 is generated by `icalvcal_convert()` when it encounters a vCal property
1380 that it cannot convert or does not know about.
1381 
1382 `icalcomponent_convert_errors()` converts some of the error properties
1383 in a component into `REQUEST-STATUS` properties that indicate a failure.
1384 As of libical version 0.18, this routine only converts `PARSEERROR` errors
1385 and it always generates a 3.x (failure) code. This makes it more
1386 of a good idea than a really useful bit of code.
1387 
1388 #### 5.6.4 `icalerror_errors_are_fatal`
1389 
1390 If `icalerror_get_errors_are_fatal()` returns true, then any error
1391 condition will cause the program to abort. The abort occurs
1392 in `icalerror_set_errno()`, and is done with an assert(0) if NDEBUG
1393 is undefined, and with `icalerror_crash_here()` if NDEBUG is defined.
1394 `icalerror_get_errors_are_fatal()` is false by default; to change
1395 that behavior, call `icalerror_set_errors_are_fatal(true)` beforehand
1396 (eg. at the initialization of your application).
1397 
1398 ### 5.7 Naming Standard
1399 
1400 Structures that you access with the "struct" keyword, such as `struct
1401 icaltimetype` are things that you are allowed to see inside and poke
1402 at.
1403 
1404 Structures that you access though a typedef, such as `icalcomponent`
1405 are things where all of the data is hidden.
1406 
1407 Component names that start with "V" are part of RFC5545 or another
1408 iCal standard. Component names that start with "X" are also part of
1409 the spec, but they are not actually components in the spec. However,
1410 they look and act like components, so they are components in libical.
1411 Names that start with `XLIC` or `X-LIC` are not part of any iCal spec.
1412 They are used internally by libical.
1413 
1414 Enums that identify a component, property, value or parameter end with
1415 `_COMPONENT`, `_PROPERTY`, `_VALUE`, or `_PARAMETER`"
1416 
1417 Enums that identify a parameter value have the name of the parameter
1418 as the second word. For instance: `ICAL_ROLE_REQPARTICIPANT` or
1419 `ICAL_PARTSTAT_ACCEPTED`.
1420 
1421 The enums for the parts of a recurrence rule and request statuses
1422 are irregular.
1423 
1424 ## 6 Hacks and Bugs
1425 
1426 There are a lot of hacks in the library -- bits of code that I am not
1427 proud of and should probably be changed. These are marked with the
1428 comment string "HACK."
1429 
1430 ## 7 Library Reference
1431 
1432 ### 7.1 Manipulating struct icaltimetype
1433 
1434 #### 7.1.1 Struct icaltimetype
1435 
1436 ```c
1437 struct icaltimetype
1438 
1439 {
1440  int year;
1441  int month;
1442  int day;
1443  int hour;
1444  int minute;
1445  int second;
1446  int is_utc;
1447  int is_date;
1448  const char* zone;
1449 };
1450 ```