diff options
author | JP Rosevear <jpr@ximian.com> | 2001-04-18 01:54:48 +0800 |
---|---|---|
committer | JP Rosevear <jpr@src.gnome.org> | 2001-04-18 01:54:48 +0800 |
commit | e6f1da7f4681def1f8b0472a504dda549f9f4b89 (patch) | |
tree | 20975542002d583663c5c728e9f3cde0bd61573f /libical | |
parent | 3a49d3e43d8e752162e5c4a098e1c0991a7611db (diff) | |
download | gsoc2013-evolution-e6f1da7f4681def1f8b0472a504dda549f9f4b89.tar.gz gsoc2013-evolution-e6f1da7f4681def1f8b0472a504dda549f9f4b89.tar.zst gsoc2013-evolution-e6f1da7f4681def1f8b0472a504dda549f9f4b89.zip |
Finish merge of new libical 0.23a version
2001-04-17 JP Rosevear <jpr@ximian.com>
* Finish merge of new libical 0.23a version
svn path=/trunk/; revision=9420
Diffstat (limited to 'libical')
40 files changed, 3303 insertions, 3116 deletions
diff --git a/libical/ChangeLog b/libical/ChangeLog index 5deefa813c..17e1ad0072 100644 --- a/libical/ChangeLog +++ b/libical/ChangeLog @@ -1,29 +1,140 @@ -2001-02-27 Ettore Perazzoli <ettore@ximian.com> +2001-04-01 Eric Busboom <eric@softwarestudio.org> - * src/libical/Makefile.am (ical.h): Depend on `$(BUILT_SOURCES)', - not `$(COMBINEDHEADERS)'. + * icalcomponent.h Changed meaning of + icalcomponent_new_from_string. It used to create a new component + given the text name of the component type to create. Now it calls + icalparser_parse_string to create a new component from the + complete iCalendar text representation of the component. +2001-03-31 Eric Busboom <eric@softwarestudio.org> + + * icalvalue Changed ACTION properties to take an ACTION value + instead of TEXT. The ACTION value is enumerated. + +2001-03-26 Eric Busboom <eric@softwarestudio.org> + + * icalparameter.h icalparameter_rsvp_* routines now take, return + ICAL_RSVP_TRUE and ICAL_RSVP_FALSE, not 0 and 1 + +2001-03-25 Eric Busboom <eric@softwarestudio.org> + + * icalrecur.c Many changes to get YEARLY rules working and fix + other errors. Recurrences are stil broken, but more types of rue + now work. + +2001-03-16 Eric Busboom <eric@softwarestudio.org> + + * icalparameter.c Changed icalparameter_new_from_string() to + icalparameter_new_from_value_string(). Created new + icalparameter_new_from_string() that takes strings of + form"PARAMNAME=PARAMVALUE" + + * *_XNAME changes all _XNAME enumerations to _X + + * derived props, values, parameters. Seperated out derived + proeprties, parameters and values into their own files. This makes + it easier to auto generate all of the enumerations for values, + parameters and proeprties. + + * icalenum.h Major changes to icalenum. Movel all of the + icalenum_* values to other modules, and changed the names. Look + for #defines in icalenum.h tying the old name to the new + name. Also moved all of the enumerations into other files. + + + +2001-02-26 Eric Busboom <eric@softwarestudio.org> + + * src/libical/icalproperty.c Added + icalproperty_set_parameter_from_string and + icalproperty_set_value_from_string to aid in binding to Python + +2001-02-15 Eric Busboom <eric@softwarestudio.org> + + * design-data/prop-to-value.txt Made a new CSV file, + properties.cvs That collects property-to-value and default value + information + + * src/libical/icalproperty.{c,h}.in Moved auto generated code into + icalderivedproperty.{c,h} and created icalderivedproperty.{c,h}.in + + + +2001-02-14 JP Rosevear <jpr@ximian.com> + + * src/libical/Makefile.am: Sigh, automake is dumber than i thought + +2001-02-12 JP Rosevear <jpr@ximian.com> + + * src/test/Makefile.am: link with the static versions + + * src/python/Makefile.am: use include dir discovered in configure checks + + * src/python/.cvsignore: shush + + * src/libical/icalrestriction.c: remove autogenerated file + + * src/libical/Makefile.am: the generated files are now disted so + look for them in the source dir rather than the build dir + + * src/Makefile.am: Only build the python dir if all the configure + stuff checked out + + * configure.in: Remove shared library disabling and add a python + check and allow for the python bindings to not be built + +2001-02-11 Eric Busboom <eric@softwarestudio.org> + + * src/python/Makefile.am Tweaked makefile to use automake more, + but it stil isn't quie right. + +2001-02-09 JP Rosevear <jpr@ximian.com> + + * Shush cvs + 2001-02-09 JP Rosevear <jpr@ximian.com> - * src/libical/Makefile.am: The built sources shouldn't be cleaned + * src/libical/Makefile.am: Slightly over zealous during the merge + +2001-02-09 JP Rosevear <jpr@ximian.com> + * src/libical/Makefile.am: Correct typo + + * Removal of more auto generated files + +2001-02-09 JP Rosevear <jpr@ximian.com> + + * Removal of various auto generated files + 2001-02-09 JP Rosevear <jpr@ximian.com> * src/libical/icalparameter.c.in (icalparameter_new_from_string): its NEEDS-ACTION rather than NEEDSACTION (icalparameter_as_ical_string): ditto +2001-02-09 Eric Busboom <eric@softwarestudio.org> + + * python Added src/python directory. Inserted SWIG wrapper files, + and a simple interface to Component, Time, Duration, Period and + Store. + + * icallangbind.c More experimental work + + * icalduration.{c,h}, icalperiod.{c,h} Broke out period and + duration types into their own files + 2001-02-06 Christopher James Lahey <clahey@ximian.com> * src/libical/icallangbind.c: Added a missing #include here. * src/libical/icalrecur.c (icalrecur_add_bydayrules): Copy the passed in const vals since we change it. + +2001-02-06 Eric Busboom <eric@softwarestudio.org> -2001-02-05 JP Rosevear <jpr@ximian.com> - - * src/libical/icallangbind.c (icallangbind_get_property): Use the - renamed api call + * icaltime.c Changed icaltime_from_day_of_year to run mktime in + the UTC timezone. This fixed a bug where it would return one day + eariler for some timezones. 2001-02-05 Ettore Perazzoli <ettore@ximian.com> @@ -31,7 +142,7 @@ `icalparameter.h', `icalproperty.h' and `icalrestriction.h' are created in the builddir so they shouldn't be prefixed with `$(top_builddir)/src/libical'. - + 2001-01-26 Eric Busboom <eric@softwarestudio.org> * icalproperty.c.in Improved icalproperty_as_ical_string() to @@ -43,30 +154,21 @@ for combined value type -- non standard values that can have more than on standard value type. These non-standard types now delegate to stadard types. - 2001-01-24 Dan Winship <danw@helixcode.com> * src/libical/icaltime.c: Remove unused "extern long timezone". -2001-01-24 Damon Chaplin <damon@helixcode.com> +2001-01-24 Eric Busboom <eric@softwarestudio.org> - * src/libical/icaltime.c (set_tz): - (unset_tz): rewrote to fix problems with freeing the environment - string after calling putenv() and to fix memory leaks. (We save a - pointer to the last TZ env var we set, so we free it after the next - time we set TZ.) + * icalfileset.c fixed icalfileset_read-from_file so it will handle + lines longer than 80 char properly. 2001-01-23 JP Rosevear <jpr@ximian.com> * configure.in: Don't AC_INIT on an autogenerated file that does not exist beforehand - -2001-01-24 Eric Busboom <eric@softwarestudio.org> - - * icalfileset.c fixed icalfileset_read-from_file so it will handle - lines longer than 80 char properly. - + 2001-01-23 Eric Busboom <eric@softwarestudio.org> * icltime.c Removed all of the _local_ routines and simplified diff --git a/libical/NEWS b/libical/NEWS index c4bc3db38f..16a7924645 100644 --- a/libical/NEWS +++ b/libical/NEWS @@ -1,3 +1,54 @@ +Version 0.23, 26 Mar 01 ( cvs tag libical-0-23 ) +------------------------------------------------ + +**** Incompatibilities with previous versions **** + +icalparameter_new_rsvp +icalparameter_get_rsvp +icalparameter_set_rsvp + + These routines now take and return ICAL_RSVP_TRUE and + ICAL_RSVP_FALSE instead of 0 and 1 + +icalenum_*_to_* + + These routines have been moved to icalproperty, icalparameter + or icalvalue + + + +Python interface: An alpha level python interface is available in +src/python. + +Perl interface: A pre-alpha level interface is available in +src/Net-ICal-Libical + +Code Autogeneration: Converted all of the important files in +design-data/ to .csv files and improved the code that is generated +from them. Now all of the enumerations for property, parameters and +values are generated from thes files, as are the string +representations for the enumerations. You can add a new property or +parameter to the system simply by adding a line to the appropriate +file in design-data/ + +Recurrences: Improved the recurrence code by fixing bugs in MONTHLY +recurrences and completely re-implementing expand_year_days() for +YEARLY recurrences. Hubert V's aided in testing. + +Build system: JP Rosevear made several improvements to the build +system. Now checking out the code from cvs should give to a complete +but minimal distribution, without any of the autognerated files. + +Interface changes: Nearly all of the icalenum routines for converting +between strings and enumerations have been moved out of icalenum into +icalproperty, icalparameter and icalvalue. This means that their names +have changed, although #defines have been added to icalenum.h to map +back to the old names. + +Added src/libical/icllangbind.c that has some functions to make it +easier to bind libical to other languages. + + Version 0.22, 15 Jan 01 ( cvs tag libical-0-22) ---------------------------------------------- diff --git a/libical/THANKS b/libical/THANKS index 5d9e9185fb..a56bca9365 100644 --- a/libical/THANKS +++ b/libical/THANKS @@ -39,10 +39,16 @@ Martin Neimeier <nei@ibn.de> for correcting bugs in icalrecur.c Tom Leitner <tom@radar.tu-graz.ac.at> For several bug fixes in compiling on Tru64 UNIX. -Patrick Lewis <plewis@inetarena.com> for several bug reports. +Patrick Lewis <plewis@inetarena.com> for several bug reports and +contributions to the Python bindings Larry W. Virden <lvirden@cas.org> for several bug reports in compiling on Solaris. Bryan Bartone <bsb@mesasys.com> for code changes based on porting libical to Windows. + +Hubert V <hubertv@bigfoot.com> for checking and analyzing the output +of the recurrence rule system. + +Jonathan Yue <jonathan.yue@cp.net> for icalproperty_get_name() diff --git a/libical/acconfig.h b/libical/acconfig.h index 1d2bfa4060..f4909b0c46 100644 --- a/libical/acconfig.h +++ b/libical/acconfig.h @@ -14,3 +14,7 @@ /* Define if your libc defines a struct tm containing a "tm_gmtoff" member */ #undef HAVE_TM_GMTOFF + +/* Define to 1 if your compile does not like lines like: struct + something foo[]*/ +#undef ICAL_NO_EMPTY_ARRAY_DECL diff --git a/libical/configure.in b/libical/configure.in index 80b35a660e..112ac66ded 100644 --- a/libical/configure.in +++ b/libical/configure.in @@ -1,7 +1,6 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(src) -AM_INIT_AUTOMAKE(libical,0.22c) - +AM_INIT_AUTOMAKE(libical,0.23a) AM_CONFIG_HEADER(config.h) dnl Initialize maintainer mode @@ -25,6 +24,7 @@ AC_CHECK_PROGS(PERL, perl5 perl) AC_DEFINE(ICAL_ERRORS_ARE_FATAL,1) AC_DEFINE(ICAL_SAFESAVES,1) AC_DEFINE(ICAL_UNIX_NEWLINE,1) +dnl AC_DEFINE(ICAL_NO_EMPTY_ARRAY_DECL) dnl Checks for libraries. dnl Replace `main' with a function in -lical: @@ -39,37 +39,52 @@ AC_C_CONST AC_TYPE_SIZE_T AC_STRUCT_TM -AC_CACHE_CHECK(for timezone variable, ac_cv_var_timezone, - AC_TRY_COMPILE([ -#include <time.h> - ], [ - timezone = 1; - ], ac_cv_var_timezone=yes, ac_cv_var_timezone=no)) -if test $ac_cv_var_timezone = yes; then - AC_DEFINE(HAVE_TIMEZONE) -else - AC_CACHE_CHECK(for tm_gmtoff in struct tm, ac_cv_struct_tm_gmtoff, - AC_TRY_COMPILE([ -#include <time.h> - ], [ - struct tm tm; - tm.tm_gmtoff = 1; - ], ac_cv_struct_tm_gmtoff=yes, ac_cv_struct_tm_gmtoff=no -)) - if test $ac_cv_struct_tm_gmtoff = yes; then - AC_DEFINE(HAVE_TM_GMTOFF) - else - AC_ERROR(unable to find a way to determine timezone) - fi -fi - - - dnl Checks for library functions. AC_CHECK_FUNCS(strdup) -dnl Check for perl -AC_CHECK_PROGS(PERL, perl5 perl) +dnl ************************************************** +dnl * Check for Python +dnl ************************************************** +python_val=false +AC_ARG_ENABLE(python-bindings, +[ --enable-python-bindings=[yes/no] Enable python bindings],,enable_python_bindings=yes) +if test "x$enable_python_bindings" = "xyes"; then + python_val=true +else + python_val=false +fi + +if $python_val; then + AC_CHECK_PROG(python_val, python, true, false) +fi +if $python_val; then + AC_CHECK_PROG(python_val, swig, true, false) +fi + +if $python_val; then + PY_PREFIX=`python -c 'import sys ; print sys.prefix'` + PY_EXEC_PREFIX=`python -c 'import sys ; print sys.exec_prefix'` + changequote(<<, >>)dnl + PY_VERSION=`python -c 'import sys ; print sys.version[0:3]'` + changequote([, ])dnl + if test -f $PY_PREFIX/include/python$PY_VERSION/Python.h; then + PY_LIBS="python$PY_VERSION" + PY_LIB_LOC="-L$PY_EXEC_PREFIX/lib/python$PY_VERSION/config" + PY_CFLAGS="-I$PY_PREFIX/include/python$PY_VERSION" + PY_MAKEFILE="$PY_EXEC_PREFIX/lib/python$PY_VERSION/config/Makefile" + PY_LOCALMODLIBS=`sed -n -e 's/^LOCALMODLIBS=\(.*\)/\1/p' $PY_MAKEFILE` + PY_BASEMODLIBS=`sed -n -e 's/^BASEMODLIBS=\(.*\)/\1/p' $PY_MAKEFILE` + PY_OTHER_LIBS=`sed -n -e 's/^LIBS=\(.*\)/\1/p' $PY_MAKEFILE` + PY_EXTRA_LIBS="$PY_LOCALMODLIBS $PY_BASEMODLIBS $PY_OTHER_LIBS" + AC_SUBST(PY_LIBS) + AC_SUBST(PY_LIB_LOC) + AC_SUBST(PY_CFLAGS) + AC_SUBST(PY_EXTRA_LIBS) + else + python_val=false + fi +fi +AM_CONDITIONAL(WITH_PYTHON, $python_val) AC_OUTPUT([ Makefile @@ -80,6 +95,8 @@ src/Makefile src/libical/Makefile src/libical/icalversion.h src/libicalvcal/Makefile +src/python/Makefile +src/test/Makefile test-data/Makefile ]) diff --git a/libical/design-data/Makefile.am b/libical/design-data/Makefile.am index 0548974160..8f27cd6ce0 100644 --- a/libical/design-data/Makefile.am +++ b/libical/design-data/Makefile.am @@ -1,10 +1,6 @@ EXTRA_DIST =\ - components.txt \ - param-c-types.txt \ - params-in-prop.txt \ - prop-to-value.txt \ - property-tokens.txt \ + properties.csv \ + parameters.csv \ restrictions.csv \ status.txt \ - value-c-types.txt \ - value-mem-semantics.txt \ + value-types.csv diff --git a/libical/doc/UsingLibical.lyx b/libical/doc/UsingLibical.lyx index aa299de3c8..cef199bea5 100644 --- a/libical/doc/UsingLibical.lyx +++ b/libical/doc/UsingLibical.lyx @@ -1,8 +1,8 @@ #LyX 1.1 created this file. For more info see http://www.lyx.org/ \lyxformat 2.16 -\textclass linuxdoc +\textclass article \language default -\inputencoding default +\inputencoding latin1 \fontscheme default \graphics default \paperfontsize default @@ -59,7 +59,7 @@ Libical implements RFC2445, RFC2446 and some of RFC2447 and the CAP draft. This documentation assumes that you are familiar with the iCalendar standards RFC2445 and RFC2446. these specifications are online on the CALSCH webpage at: -\layout Verbatim +\layout LyX-Code http://www.imc.org/ietf-calendar/ \layout Subsection @@ -71,16 +71,16 @@ This code is under active development. If you would like to contribute to the project, you can contact me, Eric Busboom, at eric@softwarestudio.org. The project has a webpage at -\layout Verbatim +\layout LyX-Code http://softwarestudio.org/libical/index.html \layout Standard and a mailing list that you can join by sending the following mail: -\layout Verbatim +\layout LyX-Code To: minimalist@softwarestudio.org -\layout Verbatim +\layout LyX-Code Subject: subscribe libical \layout Subsection @@ -128,7 +128,7 @@ src/test \layout Section -Building the Library +Building nas Installing the Library \layout Standard Libical uses autoconf to generate makefiles. @@ -143,6 +143,53 @@ Libical uses autoconf to generate makefiles. For a more complete guide to building the library, see the README file in the distribution. +\layout Standard + + +\begin_inset Quotes eld +\end_inset + +make install +\begin_inset Quotes erd +\end_inset + + will install the libraries and header files for three modules: libical, + libicalss. + and libicalvcal. + If you build shared objects, then these files will be installed: +\layout Itemize + +ical.h +\layout Itemize + +libical.a +\layout Itemize + +libical.so +\layout Itemize + +icalss.h +\layout Itemize + +libicalss.a +\layout Itemize + +libicalss.so +\layout Itemize + +icalvcal.h +\layout Itemize + +libicalvcal.a +\layout Itemize + +libicalvcal.so +\layout Standard + +The header files ical.h and icalss.h are combined header files, generated + by concatenating together all of the header files in src/libical and src/libica +lss respectively. + \layout Section Structure @@ -157,7 +204,7 @@ Properties are the fundamental unit of information in iCal, and they work a bit like a hash entry, with a constant key and a variable value. Properties may also have modifiers, called parameters. In the iCal content line -\layout Verbatim +\layout LyX-Code ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com \layout Standard @@ -215,61 +262,61 @@ END \added_space_bottom 0.3cm When a component is sent across a network, if it is un-encrypted, it will look something like: -\layout Verbatim +\layout LyX-Code BEGIN:VCALENDAR -\layout Verbatim +\layout LyX-Code METHOD:REQUEST -\layout Verbatim +\layout LyX-Code PRODID: -//hacksw/handcal//NONSGML v1.0//EN -\layout Verbatim +\layout LyX-Code BEGIN:VEVENT -\layout Verbatim +\layout LyX-Code DTSTAMP:19980309T231000Z -\layout Verbatim +\layout LyX-Code UID:guid-1.host1.com -\layout Verbatim +\layout LyX-Code ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com -\layout Verbatim +\layout LyX-Code ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP: -\layout Verbatim +\layout LyX-Code MAILTO:employee-A@host.com -\layout Verbatim +\layout LyX-Code DESCRIPTION:Project XYZ Review Meeting -\layout Verbatim +\layout LyX-Code CATEGORIES:MEETING -\layout Verbatim +\layout LyX-Code CLASS:PUBLIC -\layout Verbatim +\layout LyX-Code CREATED:19980309T130000Z -\layout Verbatim +\layout LyX-Code SUMMARY:XYZ Project Review -\layout Verbatim +\layout LyX-Code DTSTART;TZID=US-Eastern:19980312T083000 -\layout Verbatim +\layout LyX-Code DTEND;TZID=US-Eastern:19980312T093000 -\layout Verbatim +\layout LyX-Code LOCATION:1CP Conference Room 4350 -\layout Verbatim +\layout LyX-Code END:VEVENT -\layout Verbatim +\layout LyX-Code END:VCALENDAR \layout Standard @@ -277,21 +324,49 @@ END:VCALENDAR Note that components can be nested; this example has both a VCALENDAR and a VEVENT component, one nested inside the other. +\layout Standard + +The main goal of Libical is to offer a structured, type-safe to create, + access and manipulate components and their properties, values and parameters. + \layout Subsection Core iCal classes \layout Standard Libical is an object-based, data-oriented library. + There are no real-objects, but the way the routines are named and organized + results in the same sort of encapsulations and abstraction that are major + features of Object-Orieted languages. Nearly all of the routines in the library are associated with an opaque data types and perform some operation on that data type. - Although the library does not actually have classes, we will use those - terms since the behavior of these associations of data and routines is - very similar to a class. + For instnace, a Property is declared as: +\layout LyX-Code + +icalproperty *prop; +\layout Standard + +Icalproperty is typedef'd to void, so the only way to manipulate it is through + the accessor routines, all of which have a form similar to: +\layout LyX-Code + +char* icalproperty_as_ical_string(icalproperty* prop); +\layout Standard + +That is, the name of the 'class' is the first word in the routine name, + and the first parameter is a pointer to the 'object.' +\layout Standard + +Although the library does not actually have classes, we will use those terms + since the behavior of these associations of data and routines is very similar + to a class. \layout Subsubsection Properties +\layout LyX-Code + +icalproperty *prop; \layout Standard Properties are represented with the icalproperty class and its many @@ -318,6 +393,9 @@ derived \layout Subsubsection Components +\layout LyX-Code + +icalcomponent *comp; \layout Standard In libical, components are represented with the icalcomponent class. @@ -325,6 +403,9 @@ In libical, components are represented with the icalcomponent class. \layout Subsubsection Values +\layout LyX-Code + +icalvalue *value; \layout Standard Values are represented in a similar way to properties; a base class and @@ -339,10 +420,15 @@ derived classes. A value is essentially a abstract handle on a single fundamental type, a structure or a union. + You probably will never use a value directly, since for most operations + you can get to its data through the property that holds it. \layout Subsubsection Parameters +\layout LyX-Code + +icalparameter *param; \layout Standard Parameters are represetned in a similar way to properties, except that they @@ -360,7 +446,7 @@ In addition to the core iCal classes, libical has many other types, structures, Enumerations and types \layout Standard -Libical is strongly typed, soo every component, property, parameter, and +Libical is strongly typed, so every component, property, parameter, and value type has an enumeration, and some have an associated structure or union. @@ -513,11 +599,7 @@ It is natural to have interfaces that would return the value of a property, So, in libical, properties that can have multiple types are given a single type that is the union of their RFC2445 types. For instance, in libical, the value of the TRIGGER property resolves to - -\noun on -struct icaltriggertype -\noun default -. + struct icaltriggertype. This type is a union of a DURATION and a DATE-TIME. \layout Subsection @@ -532,16 +614,16 @@ S property can have multiple value instances. In libical, all properties have a single value, and multi-valued properties are broken down into multiple single valued properties during parsing. That is, an input line like, -\layout Verbatim +\layout LyX-Code CATEGORIES: work, home \layout Standard becomes in libical's internal representation -\layout Verbatim +\layout LyX-Code CATEGORIES: work -\layout Verbatim +\layout LyX-Code CATEGORIES: home \layout Standard @@ -562,10 +644,20 @@ Using libical Creating Components \layout Standard -There are three ways to create components in Libical: creating individual - objects and assembling them, building entire objects in massive vaargs - calls, and parsing a text file containing iCalendar data. - +There are three ways to create components in Libical: +\layout Itemize + +Create individual components, properties and parameters and assemble them + into structures +\layout Itemize + +Build complete components with nested vaargs calls +\layout Itemize + +Parse bits of text +\layout Itemize + +Parse entire files \layout Subsubsection Constructor Interfaces @@ -573,43 +665,51 @@ Constructor Interfaces Using constructor interfaces, you create each of the objects separately and then assemble them in to components: -\layout Verbatim +\layout LyX-Code icalcomponent *event; -\layout Verbatim +\layout LyX-Code icalproperty *prop; -\layout Verbatim +\layout LyX-Code icalparameter *param; -\layout Verbatim +\layout LyX-Code struct icaltimetype atime; -\layout Verbatim +\layout LyX-Code + +\layout LyX-Code event = icalcomponent_new(ICAL_VEVENT_COMPONENT); -\layout Verbatim +\layout LyX-Code -prop = icalproperty_new_dtstamp(atime) ; -\layout Verbatim +prop = icalproperty_new_dtstamp(atime); +\layout LyX-Code icalcomponent_add_property(event, prop); -\layout Verbatim +\layout LyX-Code + +\layout LyX-Code prop = icalproperty_new_uid(''guid-1.host1.com'') ); -\layout Verbatim +\layout LyX-Code icalcomponent_add_property(event,prop); -\layout Verbatim +\layout LyX-Code + +\layout LyX-Code prop=icalproperty_new_organizer(''mrbig@host.com''); -\layout Verbatim +\layout LyX-Code param = icalparameter_new_role(ICAL_ROLE_CHAIR) -\layout Verbatim +\layout LyX-Code icalproperty_add_parameter(prop, param); -\layout Verbatim +\layout LyX-Code + +\layout LyX-Code icalcomponent_add_property(event,prop); \layout Standard @@ -654,91 +754,91 @@ There is another way to create complex components, which is arguably more in a single block of code. Here is the previous examples in the vaargs style. -\layout Verbatim +\layout LyX-Code calendar = -\layout Verbatim +\layout LyX-Code icalcomponent_vanew( -\layout Verbatim +\layout LyX-Code ICAL_VCALENDAR_COMPONENT, -\layout Verbatim +\layout LyX-Code icalproperty_new_version(''2.0''), -\layout Verbatim +\layout LyX-Code icalproperty_new_prodid( -\layout Verbatim +\layout LyX-Code ''-//RDU Software//NONSGML HandCal//EN''), -\layout Verbatim +\layout LyX-Code icalcomponent_vanew( -\layout Verbatim +\layout LyX-Code ICAL_VEVENT_COMPONENT, -\layout Verbatim +\layout LyX-Code icalproperty_new_dtstamp(atime), -\layout Verbatim +\layout LyX-Code icalproperty_new_uid(''guid-1.host1.com''), -\layout Verbatim +\layout LyX-Code icalproperty_vanew_organizer( -\layout Verbatim +\layout LyX-Code ''mrbig@host.com''), -\layout Verbatim +\layout LyX-Code icalparameter_new_role(ICAL_ROLE_CHAIR), -\layout Verbatim +\layout LyX-Code 0 -\layout Verbatim +\layout LyX-Code ), -\layout Verbatim +\layout LyX-Code icalproperty_vanew_attendee( -\layout Verbatim +\layout LyX-Code ''employee-A@host.com'', -\layout Verbatim +\layout LyX-Code icalparameter_new_role( -\layout Verbatim +\layout LyX-Code ICAL_ROLE_REQPARTICIPANT), -\layout Verbatim +\layout LyX-Code icalparameter_new_rsvp(1), -\layout Verbatim +\layout LyX-Code icalparameter_new_cutype(ICAL_CUTYPE_GROUP), -\layout Verbatim +\layout LyX-Code 0 -\layout Verbatim +\layout LyX-Code ), -\layout Verbatim +\layout LyX-Code icalproperty_new_location( -\layout Verbatim +\layout LyX-Code "1CP Conference Room 4350"), -\layout Verbatim +\layout LyX-Code 0 -\layout Verbatim +\layout LyX-Code ), -\layout Verbatim +\layout LyX-Code 0 -\layout Verbatim +\layout LyX-Code ); \layout Standard @@ -769,41 +869,63 @@ new \layout Subsubsection -Parsing Text Files +Parsing Text +\layout Standard + +Several routines are available for generating objects from text. + For properties, use: +\layout LyX-Code + +icalproperty* p; +\layout LyX-Code + +p = icalproperty_new_from_string("DTSTART:19970101T120000Z +\backslash +n"); +\layout Standard + +For parameters, use: +\layout LyX-Code + +icalparameter *param +\layout LyX-Code + +param = icalparameter_new_from_string("PARTSTAT=ACCEPTED"); \layout Standard The final way to create components will probably be the most common; you can create components from RFC2445 compliant text. If you have the string in memory, use -\layout Verbatim +\layout LyX-Code -icalcomponent* icalparser_parse_string(char* str); +icalcomponent* icalcomponent_new_from_string(char* str); \layout Standard -If the string contains only one component, the parser will return the component +If the string contains only one component, the routine will return the component in libical form. If the string contains multiple components, the multiple components will be returned as the children of an ICAL_XROOT_COMPONENT component. - + This routine is identical to ( and actually uses ) icalparser_parse_string(char +* str). \layout Standard Parsing a whole string may seem wasteful if you want to pull a large component off of the network or from a file; you may prefer to parse the component line by line. This is possible too by using: -\layout Verbatim +\layout LyX-Code icalparser* icalparser_new(); -\layout Verbatim +\layout LyX-Code void icalparser_free(icalparser* parser); -\layout Verbatim +\layout LyX-Code icalparser_get_line(parser,read_stream); -\layout Verbatim +\layout LyX-Code icalparser_add_line(parser,line); -\layout Verbatim +\layout LyX-Code icalparser_set_gen_data(parser,stream) \layout Standard @@ -813,74 +935,74 @@ These routines will construct a parser object to which you can add lines These routines work by specifing an adaptor routine to get string data from a source. For an example: -\layout Verbatim +\layout LyX-Code char* read_stream(char *s, size_t size, void *d) -\layout Verbatim +\layout LyX-Code { -\layout Verbatim +\layout LyX-Code char *c = fgets(s,size, (FILE*)d); -\layout Verbatim +\layout LyX-Code return c; -\layout Verbatim +\layout LyX-Code } -\layout Verbatim +\layout LyX-Code main() { -\layout Verbatim +\layout LyX-Code char* line; -\layout Verbatim +\layout LyX-Code icalcomponent *c; -\layout Verbatim +\layout LyX-Code icalparser *parser = icalparser_new(); -\layout Verbatim +\layout LyX-Code FILE* stream = fopen(argv[1],"r"); -\layout Verbatim +\layout LyX-Code icalparser_set_gen_data(parser,stream); -\layout Verbatim +\layout LyX-Code do{ -\layout Verbatim +\layout LyX-Code line = icalparser_get_line(parser,read_stream); -\layout Verbatim +\layout LyX-Code c = icalparser_add_line(parser,line); -\layout Verbatim +\layout LyX-Code if (c != 0){ -\layout Verbatim +\layout LyX-Code printf("%s",icalcomponent_as_ical_string(c)); -\layout Verbatim +\layout LyX-Code icalparser_claim(parser); -\layout Verbatim +\layout LyX-Code printf(" \backslash n--------------- \backslash n"); -\layout Verbatim +\layout LyX-Code icalcomponent_free(c); -\layout Verbatim +\layout LyX-Code } -\layout Verbatim +\layout LyX-Code } while ( line != 0); -\layout Verbatim +\layout LyX-Code } \layout Standard @@ -908,10 +1030,10 @@ Using the same mechanism, other implementations could read from memory buffers, Since the example code is a very common way to use the parser, there is a convenience routine; -\layout Verbatim +\layout LyX-Code icalcomponent* icalparser_parse(icalparser *parser, -\layout Verbatim +\layout LyX-Code char* (*line_gen_func)(char *s, size_t size, void* d)) \layout Standard @@ -932,7 +1054,7 @@ Accessing Components Given a reference to a component, you probably will want to access the propertie s, parameters and values inside. - Libical interfaces let you find sub-component, add and remove sub-components, + Libical interfaces let you find sub-components, add and remove sub-components, and do the same three operations on properties. \layout Subsubsection @@ -941,38 +1063,38 @@ Finding Components \layout Standard To find a sub-component of a component, use: -\layout Verbatim +\layout LyX-Code icalcomponent* icalcomponent_get_first_component( -\layout Verbatim +\layout LyX-Code icalcomponent* component, -\layout Verbatim +\layout LyX-Code icalcomponent_kind kind); \layout Standard This routine will return a reference to the first component of the type 'kind.' The key kind values, listed in icalenums.h are: -\layout Verbatim +\layout LyX-Code ICAL_ANY_COMPONENT -\layout Verbatim +\layout LyX-Code ICAL_VEVENT_COMPONENT -\layout Verbatim +\layout LyX-Code ICAL_VTODO_COMPONENT -\layout Verbatim +\layout LyX-Code ICAL_VJOURNAL_COMPONENT -\layout Verbatim +\layout LyX-Code ICAL_VCALENDAR_COMPONENT -\layout Verbatim +\layout LyX-Code ICAL_VFREEBUSY_COMPONENT -\layout Verbatim +\layout LyX-Code ICAL_VALARM_COMPONENT \layout Standard @@ -992,35 +1114,35 @@ Iterating Through Components Iteration requires a second routine to get the next subcomponent after the first: -\layout Verbatim +\layout LyX-Code icalcomponent* icalcomponent_get_next_component( -\layout Verbatim +\layout LyX-Code icalcomponent* component, -\layout Verbatim +\layout LyX-Code icalcomponent_kind kind); \layout Standard With the 'first' and 'next' routines, you can create a for loop to iterate through all of a components subcomponents -\layout Verbatim +\layout LyX-Code for(c = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT); -\layout Verbatim +\layout LyX-Code c != 0; -\layout Verbatim +\layout LyX-Code c = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT)) -\layout Verbatim +\layout LyX-Code { -\layout Verbatim +\layout LyX-Code do_something(c); -\layout Verbatim +\layout LyX-Code } \layout Standard @@ -1044,21 +1166,21 @@ The iteration model in the previous section requires the component to keep To solve this problem, there are also external iterators for components. The routines associated with these external iterators are: -\layout Verbatim +\layout LyX-Code icalcompiter icalcomponent_begin_component(icalcomponent* component, icalcompone nt_kind kind); -\layout Verbatim +\layout LyX-Code icalcompiter icalcomponent_end_component(icalcomponent* component, icalcomponent _kind kind); -\layout Verbatim +\layout LyX-Code icalcomponent* icalcompiter_next(icalcompiter* i); -\layout Verbatim +\layout LyX-Code icalcomponent* icalcompiter_prior(icalcompiter* i); -\layout Verbatim +\layout LyX-Code icalcomponent* icalcompiter_deref(icalcompiter* i); \layout Standard @@ -1078,26 +1200,26 @@ After creating an iterators, use _next_() and _prior_() to step forward \layout Standard Here is an example of a loop using these routines: -\layout Verbatim +\layout LyX-Code for( -\layout Verbatim +\layout LyX-Code i = icalcomponent_begin_component(impl->cluster,ICAL_ANY_COMPONENT); -\layout Verbatim +\layout LyX-Code icalcompiter_deref(&i)!= 0; -\layout Verbatim +\layout LyX-Code icalcompiter_next(&i) -\layout Verbatim +\layout LyX-Code ) { -\layout Verbatim +\layout LyX-Code icalcomponent *this = icalcompiter_deref(&i); -\layout Verbatim +\layout LyX-Code } \layout Subsubsection @@ -1113,26 +1235,26 @@ Removing an element from a list while iterating through the list with the per iteration, and you will remove only every other component. To avoid the problem, you will need to step the iterator ahead of the element you are going to remove, like this: -\layout Verbatim +\layout LyX-Code for(c = icalcomponent_get_first_component(parent_comp,ICAL_ANY_COMPONENT); -\layout Verbatim +\layout LyX-Code c != 0; -\layout Verbatim +\layout LyX-Code c = next -\layout Verbatim +\layout LyX-Code { -\layout Verbatim +\layout LyX-Code next = icalcomponent_get_next_component(parent_comp,ICAL_ANY_COMPONENT); -\layout Verbatim +\layout LyX-Code icalcomponent_remove_component(parent_comp,c); -\layout Verbatim +\layout LyX-Code } \layout Standard @@ -1142,29 +1264,29 @@ remove_component: if component iterator in the parent component is pointing to the child that will be removed, it will move the iterator to the component after the child. The following code will exploit this behavior: -\layout Verbatim +\layout LyX-Code icalcomponent_get_first_component(parent_comp,ICAL_VEVENT_COMPONENT); -\layout Verbatim +\layout LyX-Code while((c=icalcomponent_get_current_component(c)) != 0 ){ -\layout Verbatim +\layout LyX-Code if(icalcomponent_isa(c) == ICAL_VEVENT_COMPONENT){ -\layout Verbatim +\layout LyX-Code icalcomponent_remove_component(parent_comp,inner); -\layout Verbatim +\layout LyX-Code } else { -\layout Verbatim +\layout LyX-Code icalcomponent_get_next_component(parent_comp,ICAL_VEVENT_COMPONENT); -\layout Verbatim +\layout LyX-Code } -\layout Verbatim +\layout LyX-Code } \layout Subsubsection @@ -1175,79 +1297,79 @@ Working with properties and parameters Finding, iterating and removing properties works the same as it does for components, using the property-specific or parameter-specific interfaces: -\layout Verbatim +\layout LyX-Code icalproperty* icalcomponent_get_first_property( -\layout Verbatim +\layout LyX-Code icalcomponent* component, -\layout Verbatim +\layout LyX-Code icalproperty_kind kind); -\layout Verbatim +\layout LyX-Code icalproperty* icalcomponent_get_next_property( -\layout Verbatim +\layout LyX-Code icalcomponent* component, -\layout Verbatim +\layout LyX-Code icalproperty_kind kind); -\layout Verbatim +\layout LyX-Code void icalcomponent_add_property( -\layout Verbatim +\layout LyX-Code icalcomponent* component, -\layout Verbatim +\layout LyX-Code icalproperty* property); -\layout Verbatim +\layout LyX-Code void icalcomponent_remove_property( -\layout Verbatim +\layout LyX-Code icalcomponent* component, -\layout Verbatim +\layout LyX-Code icalproperty* property); \layout Standard For parameters: -\layout Verbatim +\layout LyX-Code icalparameter* icalproperty_get_first_parameter( -\layout Verbatim +\layout LyX-Code icalproperty* prop, -\layout Verbatim +\layout LyX-Code icalparameter_kind kind); -\layout Verbatim +\layout LyX-Code icalparameter* icalproperty_get_next_parameter( -\layout Verbatim +\layout LyX-Code icalproperty* prop, -\layout Verbatim +\layout LyX-Code icalparameter_kind kind); -\layout Verbatim +\layout LyX-Code void icalproperty_add_parameter( -\layout Verbatim +\layout LyX-Code icalproperty* prop, -\layout Verbatim +\layout LyX-Code icalparameter* parameter); -\layout Verbatim +\layout LyX-Code void icalproperty_remove_parameter( -\layout Verbatim +\layout LyX-Code icalproperty* prop, -\layout Verbatim +\layout LyX-Code icalparameter_kind kind); \layout Standard @@ -1274,10 +1396,10 @@ The most common way to work with values to is to manipulate them from they For each property, there are a _get_ and a _set_ routine that access the internal value. For instanace, for the UID property, the routines are: -\layout Verbatim +\layout LyX-Code void icalproperty_set_uid(icalproperty* prop, const char* v) -\layout Verbatim +\layout LyX-Code const char* icalproperty_get_uid(icalproperty* prop) \layout Standard @@ -1289,10 +1411,10 @@ For multi-valued properties, like ATTACH, the value type is usually a struct If you want to work with the underlying value object, you can get and set it with: -\layout Verbatim +\layout LyX-Code icalvalue* icalproperty_get_value (icalproperty* prop) -\layout Verbatim +\layout LyX-Code void icalproperty_set_value(icalproperty* prop, icalvalue* value); \layout Standard @@ -1302,10 +1424,10 @@ Icalproperty_get_value() will return a reference that you can manipulate Most of the time, you will have to know what the type of the value is. For instance, if you know that the value is a DATETIME type, you can manipulate it with: -\layout Verbatim +\layout LyX-Code struct icaltimetype icalvalue_get_datetime(icalvalue* value); -\layout Verbatim +\layout LyX-Code void icalvalue_set_datetime(icalvalue* value, struct icaltimetype v); \layout Standard @@ -1313,20 +1435,20 @@ void icalvalue_set_datetime(icalvalue* value, struct icaltimetype v); When working with an extension property or value (and X-PROPERTY or a property that has the parameter VALUE=x-name ) the value type is always a string. To get and set the value, use: -\layout Verbatim +\layout LyX-Code void icalproperty_set_x(icalproperty* prop, char* v); -\layout Verbatim +\layout LyX-Code char* icalproperty_get_x(icalproperty* prop); \layout Standard All X properties have the type of ICAL_X_PROPERTY, so you will need these routines to get and set the name of the property: -\layout Verbatim +\layout LyX-Code char* icalproperty_get_x_name(icalproperty* prop) -\layout Verbatim +\layout LyX-Code void icalproperty_set_x_name(icalproperty* prop, char* name); \layout Subsubsection @@ -1347,7 +1469,7 @@ RFC 2446 defines rules for what properties must exist in a component to \layout Standard Libical can check these restrictions with the routine: -\layout Verbatim +\layout LyX-Code int icalrestriction_check(icalcomponent* comp); \layout Standard @@ -1373,16 +1495,16 @@ Converting Components to Text To create an RFC2445 compliant text representation of an object, use one of the *_as_ical_string() routines: -\layout Verbatim +\layout LyX-Code char* icalcomponent_as_ical_string (icalcomponent* component) -\layout Verbatim +\layout LyX-Code char* icalproperty_as_ical_string (icalproperty* property) -\layout Verbatim +\layout LyX-Code char* icalparameter_as_ical_string (icalparameter* parameter) -\layout Verbatim +\layout LyX-Code char* icalvalue_as_ical_string (icalvalue* value) \layout Standard @@ -1445,31 +1567,31 @@ struct tm, but that structure does not differentiate between dates and times, and between local time and UTC. The libical structure is: -\layout Verbatim +\layout LyX-Code struct icaltimetype { -\layout Verbatim +\layout LyX-Code int year; -\layout Verbatim +\layout LyX-Code int month; -\layout Verbatim +\layout LyX-Code int day; -\layout Verbatim +\layout LyX-Code int hour; -\layout Verbatim +\layout LyX-Code int minute; -\layout Verbatim +\layout LyX-Code int second; -\layout Verbatim +\layout LyX-Code int is_utc; /* 1-> time is in UTC timezone */ -\layout Verbatim +\layout LyX-Code int is_date; /* 1 -> interpret this as date. */ }; @@ -1489,19 +1611,18 @@ Creating time structures \layout Standard There are several ways to create a new icaltimetype structure: -\layout Verbatim +\layout LyX-Code struct icaltimetype icaltime_from_string(const char* str); -\layout Verbatim +\layout LyX-Code struct icaltimetype icaltime_from_timet(time_t v, int is_date); -\layout Verbatim +\layout LyX-Code -struct icaltimetype icaltime_from_int(int v, int is_date, int is_utc); \layout Standard Icaltime_from_string takes any RFC2445 compliant time string: -\layout Verbatim +\layout LyX-Code struct icaltimetype tt = icaltime_from_string("19970101T103000"); \layout Standard @@ -1513,12 +1634,6 @@ Icaltime_from_timet takes a timet value, representing seconds past the POSIX Dates act differently in sorting an comparision, and they have a different string representation in RFC2445. -\layout Standard - -The icaltime_from_int is like icaltime_from_timet, but with an arbitrary - epoch. - This routine was a mistake and is deprecated. - \layout Subsubsection Time manipulating routines @@ -1526,10 +1641,10 @@ Time manipulating routines The null time value is used to indicate that the data in the structure is not a valid time. -\layout Verbatim +\layout LyX-Code struct icaltimetype icaltime_null_time(void); -\layout Verbatim +\layout LyX-Code int icaltime_is_null_time(struct icaltimetype t); \layout Standard @@ -1541,14 +1656,14 @@ It is sensible for the broken-out time fields to contain values that are The excessive values will be rolled over into the next larger field when the structure is normalized. -\layout Verbatim +\layout LyX-Code struct icaltimetype icaltime_normalize(struct icaltimetype t); \layout Standard Normalizing allows you to do arithmetic operations on time values. -\layout Verbatim +\layout LyX-Code struct icaltimetype tt = icaltime_from_string( \begin_inset Quotes eld @@ -1559,38 +1674,38 @@ struct icaltimetype tt = icaltime_from_string( \end_inset ); -\layout Verbatim +\layout LyX-Code tt.days +=3 -\layout Verbatim +\layout LyX-Code tt.second += 70; -\layout Verbatim +\layout LyX-Code tt = icaltime_normalize(tt); \layout Standard There are several routines to get the day of the week or month, etc, from a time structure. -\layout Verbatim +\layout LyX-Code short icaltime_day_of_year(struct icaltimetype t); -\layout Verbatim +\layout LyX-Code struct icaltimetype icaltime_from_day_of_year(short doy, short year); -\layout Verbatim +\layout LyX-Code short icaltime_day_of_week(struct icaltimetype t); -\layout Verbatim +\layout LyX-Code short icaltime_start_doy_of_week(struct icaltimetype t); -\layout Verbatim +\layout LyX-Code short icaltime_week_number(short day_of_month, short month, short year); -\layout Verbatim +\layout LyX-Code struct icaltimetype icaltime_from_week_number(short week_number, short year); -\layout Verbatim +\layout LyX-Code short icaltime_days_in_month(short month,short year); \layout Standard @@ -1599,17 +1714,17 @@ Two routines convert time structures to and from the number of seconds since the POSIX epoch. The is_date field indicates whether or not the hour, minute and second fields should be used in the conversion. -\layout Verbatim +\layout LyX-Code struct icaltimetype icaltime_from_timet(time_t v, int is_date); -\layout Verbatim +\layout LyX-Code time_t icaltime_as_timet(struct icaltimetype); \layout Standard The compare routine works exactly like strcmp, but on time structures. -\layout Verbatim +\layout LyX-Code int icaltime_compare(struct icaltimetype a,struct icaltimetype b); \layout Standard @@ -1641,19 +1756,19 @@ The tt parameter in the following routines indicates the date on which the 15, but for other years March 15 may be standard time, and some years may have standard time all year. -\layout Verbatim +\layout LyX-Code int icaltime_utc_offset(struct icaltimetype tt, char* tzid); -\layout Verbatim +\layout LyX-Code int icaltime_local_utc_offset(); -\layout Verbatim +\layout LyX-Code struct icaltimetype icaltime_as_utc(struct icaltimetype tt,char* tzid); -\layout Verbatim +\layout LyX-Code struct icaltimetype icaltime_as_zone(struct icaltimetype tt,char* tzid); -\layout Verbatim +\layout LyX-Code struct icaltimetype icaltime_as_local(struct icaltimetype tt); \layout Subsection @@ -1678,60 +1793,60 @@ The file storage routines are organized in an inheritance heirarchy that \layout Standard All of the icalset derived classes have the same interface: -\layout Verbatim +\layout LyX-Code -\layout Verbatim +\layout LyX-Code icaldirset* icaldirset_new(const char* path); -\layout Verbatim +\layout LyX-Code void icaldirset_free(icaldirset* store); -\layout Verbatim +\layout LyX-Code const char* icaldirset_path(icaldirset* store); -\layout Verbatim +\layout LyX-Code void icaldirset_mark(icaldirset* store); -\layout Verbatim +\layout LyX-Code icalerrorenum icaldirset_commit(icaldirset* store); -\layout Verbatim +\layout LyX-Code icalerrorenum icaldirset_add_component(icaldirset* store, icalcomponent* comp); -\layout Verbatim +\layout LyX-Code icalerrorenum icaldirset_remove_component(icaldirset* store, icalcomponent* comp); -\layout Verbatim +\layout LyX-Code int icaldirset_count_components(icaldirset* store, icalcomponent_kind kind); -\layout Verbatim +\layout LyX-Code icalerrorenum icaldirset_select(icaldirset* store, icalcomponent* gauge); -\layout Verbatim +\layout LyX-Code void icaldirset_clear(icaldirset* store); -\layout Verbatim +\layout LyX-Code icalcomponent* icaldirset_fetch(icaldirset* store, const char* uid); -\layout Verbatim +\layout LyX-Code int icaldirset_has_uid(icaldirset* store, const char* uid); -\layout Verbatim +\layout LyX-Code icalcomponent* icaldirset_fetch_match(icaldirset* set, icalcomponent *c); -\layout Verbatim +\layout LyX-Code icalerrorenum icaldirset_modify(icaldirset* store, icalcomponent *oldc, icalcomponent *newc); -\layout Verbatim +\layout LyX-Code icalcomponent* icaldirset_get_current_component(icaldirset* store); -\layout Verbatim +\layout LyX-Code icalcomponent* icaldirset_get_first_component(icaldirset* store); -\layout Verbatim +\layout LyX-Code icalcomponent* icaldirset_get_next_component(icaldirset* store); \layout Subsubsection @@ -1741,26 +1856,26 @@ Creating a new set You can create a new set from either the base class or the direved class. From the base class use one of: -\layout Verbatim +\layout LyX-Code icalset* icalset_new_file(const char* path); -\layout Verbatim +\layout LyX-Code icalset* icalset_new_dir(const char* path); -\layout Verbatim +\layout LyX-Code icalset* icalset_new_heap(void); -\layout Verbatim +\layout LyX-Code icalset* icalset_new_mysql(const char* path); \layout Standard You can also create a new set based on the derived class, For instance, with icalfileset: -\layout Verbatim +\layout LyX-Code icalfileset* icalfileset_new(const char* path); -\layout Verbatim +\layout LyX-Code icalfileset* icalfileset_new_open(const char* path, int flags, mode_t mode); \layout Standard @@ -1786,7 +1901,7 @@ Adding, Finding and Removing Components \layout Standard To add components to a set, use: -\layout Verbatim +\layout LyX-Code icalerrorenum icalfileset_add_component(icalfileset* cluster, icalcomponent* child); @@ -1795,10 +1910,10 @@ icalerrorenum icalfileset_add_component(icalfileset* cluster, icalcomponent* The fileset keeps an inmemory copy of the components, and this set must be written back to the file ocassionally. There are two routines to manage this: -\layout Verbatim +\layout LyX-Code void icalfileset_mark(icalfileset* cluster); -\layout Verbatim +\layout LyX-Code icalerrorenum icalfileset_commit(icalfileset* cluster); \layout Standard @@ -1812,13 +1927,13 @@ Icalfileset_mark indicates that the in-memory components have changed. \layout Standard To iterate through the components in a set, use: -\layout Verbatim +\layout LyX-Code icalcomponent* icalfileset_get_first_component(icalfileset* cluster); -\layout Verbatim +\layout LyX-Code icalcomponent* icalfileset_get_next_component(icalfileset* cluster); -\layout Verbatim +\layout LyX-Code icalcomponent* icalfileset_get_current_component (icalfileset* cluster); @@ -1829,160 +1944,160 @@ These routines work like the corresponding routines from icalcomponent, A gauge is a test for the properties within a components; only components that pass the test are returned. A gauge can be constructed from a MINSQL string with: -\layout Verbatim +\layout LyX-Code icalgauge* icalgauge_new_from_sql(char* sql); \layout Standard Then, you can add the gauge to the set with : -\layout Verbatim +\layout LyX-Code icalerrorenum icalfileset_select(icalfileset* store, icalgauge* gauge); \layout Standard Here is an example that puts all of these routines together: -\layout Verbatim +\layout LyX-Code \latex no_latex void test_fileset() -\layout Verbatim +\layout LyX-Code \latex no_latex { -\layout Verbatim +\layout LyX-Code \latex no_latex icalfileset *fs; -\layout Verbatim +\layout LyX-Code \latex no_latex icalcomponent *c; -\layout Verbatim +\layout LyX-Code \latex no_latex int i; -\layout Verbatim +\layout LyX-Code \latex no_latex char *path = "test_fileset.ics"; -\layout Verbatim +\layout LyX-Code \latex no_latex icalgauge *g = icalgauge_new_from_sql( -\layout Verbatim +\layout LyX-Code \latex no_latex "SELECT * FROM VEVENT WHERE DTSTART > '20000103T120000Z' AND DTSTART <= '20000106T120000Z'"); -\layout Verbatim +\layout LyX-Code \latex no_latex -\layout Verbatim +\layout LyX-Code \latex no_latex fs = icalfileset_new(path); -\layout Verbatim +\layout LyX-Code -\layout Verbatim +\layout LyX-Code \latex no_latex for (i = 0; i!= 10; i++){ -\layout Verbatim +\layout LyX-Code \latex no_latex c = make_component(i); \latex default /* Make a new component where DTSTART has month of i */ -\layout Verbatim +\layout LyX-Code \latex no_latex icalfileset_add_component(fs,c); -\layout Verbatim +\layout LyX-Code \latex no_latex } -\layout Verbatim +\layout LyX-Code -\layout Verbatim +\layout LyX-Code \latex no_latex icalfileset_commit(fs); \latex default /* Write to disk */ -\layout Verbatim +\layout LyX-Code -\layout Verbatim +\layout LyX-Code \latex no_latex icalfileset_select(fs,g); \latex default /* Set the gauge to filter components */ -\layout Verbatim +\layout LyX-Code \latex no_latex -\layout Verbatim +\layout LyX-Code \latex no_latex for (c = icalfileset_get_first_component(fs); -\layout Verbatim +\layout LyX-Code \latex no_latex c != 0; -\layout Verbatim +\layout LyX-Code \latex no_latex c = icalfileset_get_next_component(fs)){ -\layout Verbatim +\layout LyX-Code \latex no_latex struct icaltimetype t = icalcomponent_get_dtstart(c); -\layout Verbatim +\layout LyX-Code \latex no_latex -\layout Verbatim +\layout LyX-Code \latex no_latex printf("%s \backslash n",icaltime_as_ctime(t)); -\layout Verbatim +\layout LyX-Code \latex no_latex } -\layout Verbatim +\layout LyX-Code \latex no_latex icalfileset_free(fs); -\layout Verbatim +\layout LyX-Code \latex no_latex @@ -2071,45 +2186,99 @@ lerror.h. be the same as icalerrno. You can use icalerror_strerror() to get a string that describes the error. The enumerations are: -\layout Itemize - -ICAL_BADARG_ERROR -- One of the argument to a routine was bad. - Typically for a null pointer. - -\layout Itemize - -ICAL_NEWFAILED_ERROR -- A new() or malloc() failed -\layout Itemize - -ICAL_MALFORMEDDATA_ERROR -- An input string was not in the correct format -\layout Itemize - -ICAL_PARSE_ERROR -- The parser failed to parse an incomming component -\layout Itemize - -ICAL_INTERNAL_ERROR -- Largely equivalent to an assert -\layout Itemize - -ICAL_FILE_ERROR -- A file operation failed. - Check errno for more detail. -\layout Itemize +\layout Standard +\added_space_top 0.3cm \added_space_bottom 0.3cm \align center \LyXTable +multicol5 +12 2 0 0 -1 -1 -1 -1 +1 1 0 0 +1 0 0 0 +1 0 0 0 +1 0 0 0 +1 0 0 0 +1 0 0 0 +1 0 0 0 +1 0 0 0 +1 0 0 0 +1 0 0 0 +1 0 0 0 +1 1 0 0 +2 1 0 "" "" +2 1 1 "" "" +0 8 1 0 0 0 0 "" "" +0 8 1 0 0 0 0 "" "" +0 2 1 0 0 0 0 "" "" +0 2 1 0 0 0 0 "" "" +0 2 1 0 0 0 0 "" "" +0 2 1 0 0 0 0 "" "" +0 2 1 0 0 0 0 "" "" +0 2 1 0 0 0 0 "" "" +0 2 1 0 0 0 0 "" "" +0 2 1 0 0 0 0 "" "" +0 2 1 0 0 0 0 "" "" +0 2 1 0 0 0 0 "" "" +0 2 1 0 0 0 0 "" "" +0 2 1 0 0 0 0 "" "" +0 2 1 0 0 0 0 "" "" +0 2 1 0 0 0 0 "" "" +0 2 1 0 0 0 0 "" "" +0 2 1 0 0 0 0 "" "" +0 2 1 0 0 0 0 "" "" +0 2 1 0 0 0 0 "" "" +0 2 1 0 0 0 0 "" "" +0 2 1 0 0 0 0 "" "" +0 2 1 0 0 0 0 "" "" +0 2 1 0 0 0 0 "" "" -ICAL_ALLOCATION_ERROR -- ? -\layout Itemize -ICAL_USAGE_ERROR -- ? -\layout Itemize +\newline -ICAL_NO_ERROR -- No error -\layout Itemize +\newline +ICAL_BADARG_ERROR +\newline +One of the argument to a routine was bad. + Typically for a null pointer. +\newline +ICAL_NEWFAILED_ERROR +\newline +A new() or malloc() failed +\newline +ICAL_MALFORMEDDATA_ERROR +\newline +An input string was not in the correct format +\newline +ICAL_PARSE_ERROR +\newline +the parser failed to parse an incomming component +\newline +ICAL_INTERNAL_ERROR +\newline +Largely equivalent to an assert; it indicates a bug in the libical code +\newline +ICAL_FILE_ERROR +\newline +A file operation failed. + Check errno for more detai +\newline +ICAL_ALLOCATION_ERROR +\newline -ICAL_MULTIPLEINCLUSION_ERROR -- ? -\layout Itemize +\newline +ICAL_NO_ERROR +\newline +No error has occured +\newline +ICAL_TIMEDOUT_ERROR +\newline +Failed to acquire a lock on a file, or the CSTP protocol timed out. + +\newline +ICAL_MULTIPLEINCLUSION_ERROR +\newline -ICAL_TIMEDOUT_ERROR -- For CSTP and acquiring locks -\layout Itemize +\newline +ICAL_UNKNOWN_ERROR +\newline -ICAL_UNKNOWN_ERROR -- ? \layout Subsubsection X-LIC-ERROR and X-LIC-INVALID-COMPONENT @@ -2122,12 +2291,12 @@ The library handles semantic and syntactic errors in components by inserting the requirements of RFC2446 ( a semantic error) the library will insert properties of the type X-LIC-ERROR to describe the error. Here is an example of the error property: -\layout Verbatim +\layout LyX-Code X-LIC-ERROR;X-LIC-ERRORTYPE=INVALID_ITIP :Failed iTIP restrictions for property DTSTART. -\layout Verbatim +\layout LyX-Code Expected 1 instances of the property and got 0 \layout Standard @@ -2139,25 +2308,20 @@ This error resulted from a call to icalrestriction_check(), which discovered There are a few routines to manipulate error properties: \layout Standard - -[ The following data is supposed to be in a table. - It looks OK in LyX, but does not format propertly in output. - ] -\layout Standard \LyXTable multicol5 10 2 0 0 -1 -1 -1 -1 1 1 0 0 -1 0 0 0 +0 0 0 0 0 1 1 0 -1 0 0 0 +0 0 0 0 0 1 1 0 -1 1 0 0 +0 1 0 0 0 1 1 0 -1 1 0 0 +0 1 0 0 0 1 1 0 0 1 1 0 -2 1 0 "" "" +2 1 1 "" "" 2 1 1 "3in" "" 0 2 1 1 0 0 0 "" "" 0 8 1 0 0 0 0 "" "" @@ -2224,25 +2388,25 @@ process the component as an iTIP request. The types of errors are listed in icalerror.h. They are: -\layout Verbatim +\layout LyX-Code ICAL_XLICERRORTYPE_COMPONENTPARSEERROR -\layout Verbatim +\layout LyX-Code ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR -\layout Verbatim +\layout LyX-Code ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR -\layout Verbatim +\layout LyX-Code ICAL_XLICERRORTYPE_PROPERTYPARSEERROR -\layout Verbatim +\layout LyX-Code ICAL_XLICERRORTYPE_VALUEPARSEERROR -\layout Verbatim +\layout LyX-Code ICAL_XLICERRORTYPE_UNKVCALPROP -\layout Verbatim +\layout LyX-Code ICAL_XLICERRORTYPE_INVALIDITIP \layout Standard diff --git a/libical/doc/UsingLibical.txt b/libical/doc/UsingLibical.txt index 6dc4958a74..6b203d43d2 100644 --- a/libical/doc/UsingLibical.txt +++ b/libical/doc/UsingLibical.txt @@ -857,10 +857,11 @@ struct icaltimetype { int is_date; /* 1 -> interpret this as date. */ }; -The year, month, day, hour, minute and second fields how the broken-out -time values. The is_utc field distinguishes between times UTC and -a local time zone. The is_date field indicates if the intra-day fields -hold valid data. +The year, month, day, hour, minute and second fields hold the broken-out +time values. The is_utc field distinguishes between times in UTC and +a local time zone. The is_date field indicates if the time should +be interpreted only as a date. If it is a date, the hour, minute and +second fields are assumed to be zero, regardless of their actual vaules. 5.3.2 Creating time structures @@ -878,7 +879,7 @@ struct icaltimetype tt = icaltime_from_string("19970101T103000"); Icaltime_from_timet takes a timet value, representing seconds past the POSIX epoch, and a flag to indicate if the time is a date. Dates -have an identical structure to a time, but they time portion ( hours, +have an identical structure to a time, but the time portion ( hours, minuts and seconds ) is always 00:00:00. Dates act differently in sorting an comparision, and they have a different string representation in RFC2445. @@ -1207,7 +1208,34 @@ Most routines will set the global error value icalerrno on errors. This variable is an enumeration; permissible values can be found in libical/icalerror.h. If the routine returns an enum icalerrorenum, then the return value will be the same as icalerrno. You can use icalerror_strerror() -to get a string that describes the error +to get a string that describes the error. The enumerations are: + +* ICAL_BADARG_ERROR -- One of the argument to a routine was bad. Typically + for a null pointer. + +* ICAL_NEWFAILED_ERROR -- A new() or malloc() failed + +* ICAL_MALFORMEDDATA_ERROR -- An input string was not in the correct + format + +* ICAL_PARSE_ERROR -- The parser failed to parse an incomming component + +* ICAL_INTERNAL_ERROR -- Largely equivalent to an assert + +* ICAL_FILE_ERROR -- A file operation failed. Check errno for more + detail. + +* ICAL_ALLOCATION_ERROR -- ? + +* ICAL_USAGE_ERROR -- ? + +* ICAL_NO_ERROR -- No error + +* ICAL_MULTIPLEINCLUSION_ERROR -- ? + +* ICAL_TIMEDOUT_ERROR -- For CSTP and acquiring locks + +* ICAL_UNKNOWN_ERROR -- ? 5.6.3 X-LIC-ERROR and X-LIC-INVALID-COMPONENT @@ -1284,6 +1312,16 @@ As of libical version0.18, this routine only convert *PARSEERROR errors and it always generates a 3.x ( failure ) code. This makes it more of a good idea than a really useful bit of code. +5.6.4 ICAL_ERRORS_ARE_FATAL and icalerror_errors_are_fatal + +If the global variable icalerror_errors_are_fatal is set to 1, then +any error condition will cause the program to abort. The abort occurs +in icalerror_set_errno(), and is done with an assert(0) if NDEBUG +is undefined, and with icalerror_crash_here if NDEBUG is defined. +The default value of icalerror_errors_are_fatal is 1 when ICAL_ERRORS_ARE_FATAL +is defined, and 0 otherwise. Since ICAL_ERRORS_ARE_FATAL is defined +by default, icalerror_errors_are_fatal is also defined by default. + 5.7 Naming Standard Structures that you access with the "struct" keyword, such as "struct @@ -1314,3 +1352,33 @@ are irregular. There are a lot of hacks in the library -- bits of code that I am not proud of and should probably be changed. These are marked with the comment string "HACK." + +7 Library Reference + +7.1 Manipulating struct icaltimetype + +7.1.1 Struct icaltimetype + +struct icaltimetype + +{ + + int year; + + int month; + + int day; + + int hour; + + int minute; + + int second; + + int is_utc; + + int is_date; + + const char* zone; + +}; diff --git a/libical/install-sh b/libical/install-sh index 0ff4b6a08e..e9de23842d 100755 --- a/libical/install-sh +++ b/libical/install-sh @@ -1,14 +1,27 @@ #!/bin/sh - # # install - install a program, script, or datafile -# This comes from X11R5; it is not part of GNU. +# This comes from X11R5 (mit/util/scripts/install.sh). # -# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ +# Copyright 1991 by the Massachusetts Institute of Technology # -# This script is compatible with the BSD install script, but was written -# from scratch. +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. # +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. # set DOITPROG to echo to test this script @@ -26,9 +39,12 @@ chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" +transformbasename="" +transform_arg="" instcmd="$mvprog" -chmodcmd="" +chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" @@ -36,6 +52,7 @@ rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" +dir_arg="" while [ x"$1" != x ]; do case $1 in @@ -43,6 +60,10 @@ while [ x"$1" != x ]; do shift continue;; + -d) dir_arg=true + shift + continue;; + -m) chmodcmd="$chmodprog $2" shift shift @@ -62,10 +83,20 @@ while [ x"$1" != x ]; do shift continue;; + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + *) if [ x"$src" = x ] then src=$1 else + # this colon is to work around a 386BSD /bin/sh bug + : dst=$1 fi shift @@ -75,45 +106,146 @@ done if [ x"$src" = x ] then - echo "install: no input file specified" - exit 1 -fi - -if [ x"$dst" = x ] -then - echo "install: no destination specified" + echo "install: no input file specified" exit 1 +else + true fi +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic -if [ -d $dst ] -then - dst="$dst"/`basename $src` + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done fi +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + # Make a temp file name in the proper directory. -dstdir=`dirname $dst` -dsttmp=$dstdir/#inst.$$# + dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name -$doit $instcmd $src $dsttmp + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits -if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi -if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi -if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi -if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. -$doit $rmcmd $dst -$doit $mvcmd $dsttmp $dst + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && exit 0 diff --git a/libical/scripts/Makefile.am b/libical/scripts/Makefile.am index fd1b053cb6..c61eaefdce 100644 --- a/libical/scripts/Makefile.am +++ b/libical/scripts/Makefile.am @@ -5,4 +5,5 @@ mkderivedproperties.pl \ mkderivedvalues.pl \ mkparameterrestrictions.pl \ mkrestrictionrecords.pl \ -mkrestrictiontable.pl +mkrestrictiontable.pl \ +readvaluesfile.pl diff --git a/libical/scripts/mkderivedparameters.pl b/libical/scripts/mkderivedparameters.pl index 5715220ea3..5772065ec4 100755 --- a/libical/scripts/mkderivedparameters.pl +++ b/libical/scripts/mkderivedparameters.pl @@ -1,12 +1,14 @@ #!/usr/local/bin/perl +require "readvaluesfile.pl"; + use Getopt::Std; getopts('chspi:'); %no_xname = (RELATED=>1,RANGE=>1,RSVP=>1,XLICERRORTYPE=>1,XLICCOMPARETYPE=>1); -# Usually, open param-c-types.txt -open(F,"$ARGV[0]") || die "Can't open C parameter types file $ARGV[0]:$!"; +%params = read_parameters_file($ARGV[0]); + # Write the file inline by copying everything before a demarcation # line, and putting the generated data after the demarcation @@ -34,122 +36,174 @@ if ($opt_i) { } +# Write parameter string map +if ($opt_c){ +} -if (($opt_c or $opt_h) and !$opt_i) { +# Write parameter enumerations and datatypes -print <<EOM; -/* -*- Mode: C -*- - ====================================================================== - FILE: icalderivedparameters.{c,h} - CREATOR: eric 09 May 1999 - - \044Id: mkderivedparameters.pl,v 1.1 1999/05/14 07:04:31 eric Exp eric \044 - \044Locker: eric \044 +if($opt_h){ + print "typedef enum icalparameter_kind {\n ICAL_ANY_PARAMETER = 0,\n"; + foreach $param (sort keys %params) { - (C) COPYRIGHT 1999 Eric Busboom - http://www.softwarestudio.org + next if !$param; + + next if $param eq 'NO' or $param eq 'ANY'; - 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/ - - 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. - + my $uc = join("",map {uc($_);} split(/-/,$param)); - ======================================================================*/ + my @enums = @{$params{$param}->{'enums'}}; + + print " ICAL_${uc}_PARAMETER, \n"; + + } + print " ICAL_NO_PARAMETER\n} icalparameter_kind;\n\n"; -/* - * THIS FILE IS MACHINE GENERATED DO NOT EDIT - */ + # Now create enumerations for parameter values + $idx = 20000; + + print "#define ICALPARAMETER_FIRST_ENUM $idx\n\n"; + + foreach $param (sort keys %params) { + + next if !$param; + + next if $param eq 'NO' or $prop eq 'ANY'; + my $type = $params{$param}->{"C"}; + my $ucv = join("",map {uc(lc($_));} split(/-/,$param)); + my @enums = @{$params{$param}->{'enums'}}; -EOM + if(@enums){ -} + print "typedef enum $type {\n"; + my $first = 1; -if ($opt_p and !$opt_i){ + unshift(@enums,"X"); -print <<EOM; -# -*- Mode: Perl -*- -# ====================================================================== -# \044Id:\044 -# -# (C) COPYRIGHT 1999 Eric Busboom -# http://www.softwarestudio.org -# -# 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/ -# -# 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 original author is Eric Busboom -# The original code is derivedparams.h -# -# ======================================================================*/ + push(@enums,"NONE"); -EOM + foreach $e (@enums) { + if (!$first){ + print ",\n"; + } else { + $first = 0; + } + + my $uce = join("",map {uc(lc($_));} split(/-/,$e)); + + print " ICAL_${ucv}_${uce} = $idx"; + + $idx++; + } + $c_type =~ s/enum //; + + print "\n} $type;\n\n"; + } + } + + print "#define ICALPARAMETER_LAST_ENUM $idx\n\n"; } +if ($opt_c){ -while(<F>){ + # Create the icalparameter_value to icalvalue_kind conversion table + print "struct icalparameter_value_kind_map value_kind_map[] = {\n"; - chop; - my ($param,$type) = split(/\s{2,}/,$_); + foreach $enum (@{$params{'VALUE'}->{'enums'}}){ + next if $enum eq 'NO' or $enum eq 'ERROR'; + $uc = join("",map {uc(lc($_));} split(/-/,$enum)); + print " {ICAL_VALUE_${uc},ICAL_${uc}_VALUE},\n"; + } + print " {ICAL_VALUE_X,ICAL_X_VALUE},\n"; + print " {ICAL_VALUE_NONE,ICAL_NO_VALUE}\n};\n\n"; + + #Create the parameter Name map + print "static struct icalparameter_kind_map parameter_map[] = { \n"; + + foreach $param (sort keys %params) { + + next if !$param; + + next if $param eq 'NO' or $prop eq 'ANY'; + + my $lc = join("",map {lc($_);} split(/-/,$param)); + my $uc = join("",map {uc(lc($_));} split(/-/,$param)); + + + print " {ICAL_${uc}_PARAMETER,\"$param\"},\n"; + + } + + print " { ICAL_NO_PARAMETER, \"\"}\n};\n\n"; + + # Create the parameter value map + + print "static struct icalparameter_map icalparameter_map[] = {\n"; + print "{ICAL_ANY_PARAMETER,0,\"\"},\n"; + + foreach $param (sort keys %params) { + + next if !$param; + + next if $param eq 'NO' or $prop eq 'ANY'; + + my $type = $params{$param}->{"C"}; + my $uc = join("",map {uc(lc($_));} split(/-/,$param)); + my @enums = @{$params{$param}->{'enums'}}; + + if(@enums){ + + foreach $e (@enums){ + my $uce = join("",map {uc(lc($_));} split(/-/,$e)); + + print " {ICAL_${uc}_PARAMETER,ICAL_${uc}_${uce},\"$e\"},\n"; + } + + } + } + + print " {ICAL_NO_PARAMETER,0,\"\"}};\n\n"; + +} + +foreach $param (keys %params){ + + my $type = $params{$param}->{'C'}; + my $ucf = join("",map {ucfirst(lc($_));} split(/-/,$param)); my $lc = lc($ucf); my $uc = uc($lc); - - my $lctype = lc($type); - - + my $charorenum; my $set_code; my $pointer_check; - my $new_pointer_check; - my $new_pointer_check_v; + my $pointer_check_v; my $xrange; - if ($type=~/char/){ - $new_pointer_check = "icalerror_check_arg_rz( (v!=0),\"v\");"; - $new_pointer_check_v = "icalerror_check_arg_rv( (v!=0),\"v\");"; - } - - if ($type=~/char/ ) { - $charorenum = " icalerror_check_arg_rz( (param!=0), \"param\");\n return ((struct icalparameter_impl*)param)->string;"; + $charorenum = " icalerror_check_arg_rz( (param!=0), \"param\");\n return ($type)((struct icalparameter_impl*)param)->string;"; - $pointer_check = "icalerror_check_arg_rz( (v!=0),\"v\");"; + $set_code = "((struct icalparameter_impl*)param)->string = icalmemory_strdup(v);"; - $set_code = "((struct icalparameter_impl*)param)->string = strdup(v);" + $pointer_check = "icalerror_check_arg_rz( (v!=0),\"v\");"; + $pointer_check_v = "icalerror_check_arg_rv( (v!=0),\"v\");"; } else { - $xrange =" if ( ((struct icalparameter_impl*)param)->string != 0){\n return ICAL_${uc}_XNAME;\n }\n" if !exists $no_xname{$uc}; - - $charorenum=<<EOM; - icalerror_check_arg( (param!=0), \"param\"); -$xrange - return ((struct icalparameter_impl*)param)->data.v_${lc}; -EOM + $xrange =" if ( ((struct icalparameter_impl*)param)->string != 0){\n return ICAL_${uc}_X;\n }\n" if !exists $no_xname{$uc}; + + $charorenum= "icalerror_check_arg( (param!=0), \"param\");\n$xrange\nreturn ($type)((struct icalparameter_impl*)param)->data;"; - $pointer_check = "icalerror_check_arg( (v!=0),\"v\");"; + $pointer_check = "icalerror_check_arg_rz(v >= ICAL_${uc}_X,\"v\");\n icalerror_check_arg_rz(v < ICAL_${uc}_NONE,\"v\");"; - $set_code = "((struct icalparameter_impl*)param)->data.v_${lc} = v;"; + $pointer_check_v = "icalerror_check_arg_rv(v >= ICAL_${uc}_X,\"v\");\n icalerror_check_arg_rv(v < ICAL_${uc}_NONE,\"v\");"; - $print_code = "switch (impl->data.v_${lc}) {\ncase ICAL_${uc}_: {\n}\ncase ICAL_${uc}_XNAME: /* Fall Through */\n}\n"; + $set_code = "((struct icalparameter_impl*)param)->data = (int)v;"; } @@ -163,7 +217,7 @@ icalparameter* icalparameter_new_${lc}($type v) { struct icalparameter_impl *impl; icalerror_clear_errno(); - $new_pointer_check + $pointer_check impl = icalparameter_new_impl(ICAL_${uc}_PARAMETER); if (impl == 0) { return 0; @@ -186,7 +240,7 @@ $charorenum void icalparameter_set_${lc}(icalparameter* param, ${type} v) { - $new_pointer_check_v + $pointer_check_v icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -205,20 +259,9 @@ void icalparameter_set_${lc}(icalparameter* value, ${type} v); EOM -} elsif ($opt_s) { - -next if $type =~ /char/; - -print<<EOM; -case ICAL_${uc}_PARAMETER: -{ - $print_code -} -EOM - } - if ($opt_p) { +if ($opt_p) { print <<EOM; @@ -273,5 +316,6 @@ if ($opt_h){ print <<EOM; #endif /*ICALPARAMETER_H*/ + EOM } diff --git a/libical/scripts/mkderivedproperties.pl b/libical/scripts/mkderivedproperties.pl index 9778c30a77..4e011e112e 100755 --- a/libical/scripts/mkderivedproperties.pl +++ b/libical/scripts/mkderivedproperties.pl @@ -1,44 +1,16 @@ #!/usr/local/bin/perl -use Getopt::Std; -getopts('chsypmi:'); - -# ARG 0 is prop-to-value -open(PV,"$ARGV[0]") || die "Can't open prop to value file $ARGV[0]:$!"; - - -while (<PV>){ - - chop; - my @v = split(/\s+/,$_); - - my $prop = shift @v; - my $value = shift @v; - my $comment = join(" ",@v); - - $propmap{$prop} = $value; -} +require "readvaluesfile.pl"; -close PV; - -# ARG 1 is value-c-types.txt -open(F,"$ARGV[1]") || die "Can't open C parameter types file $ARGV[1 ]:$!"; - -while (<F>){ - - chop; - my @v = split(/\t+/,$_); - - my $value = shift @v; - my $mode = shift @v; - my $type = shift @v; - my $comment = join(" ",@v); +use Getopt::Std; +getopts('chspmi:'); - $valuemap{$value} = $type; +# ARG 0 is properties.csv +%propmap = read_properties_file($ARGV[0]); -} +# ARG 1 is value-types.txt +%valuemap = read_values_file($ARGV[1]); -close F; # Write the file inline by copying everything before a demarcation # line, and putting the generated data after the demarcation @@ -57,78 +29,128 @@ if ($opt_i) { } - if($opt_p){ - print "# Everything below this line is machine generated. Do not edit. \n"; - } else { print "/* Everything below this line is machine generated. Do not edit. */\n"; - } + } - -if ( ($opt_h or $opt_s) and !$opt_i ){ +sub fudge_data { + my $prop = shift; + + my $value = $propmap{$prop}->{'lic_value'}; + + if (!$value){ + die "Can't find value for property \"$prop\"\n"; + } + my $ucf = join("",map {ucfirst(lc($_));} split(/-/,$prop)); + my $lc = lc($ucf); + my $uc = uc($lc); + + my $ucfvalue = join("",map {ucfirst(lc($_));} split(/-/,$value)); + my $lcvalue = lc($ucfvalue); + my $ucvalue = uc($lcvalue); -print <<EOM; -/* -*- Mode: C -*- - ====================================================================== - FILE: icalderivedproperties.{c,h} - CREATOR: eric 09 May 1999 + my $type = $valuemap{$value}->{C}->[1]; + + return ($uc,$lc,$lcvalue,$ucvalue,$type); + +} + +# Create the property map data +if($opt_c){ + + print "static struct icalproperty_map property_map[] = {\n"; - \044Id:\044 + foreach $prop (sort keys %propmap) { + + next if !$prop; + + next if $prop eq 'NO'; + + my ($uc,$lc,$lcvalue,$ucvalue,$type) = fudge_data($prop); + + print "{ICAL_${uc}_PROPERTY,\"$prop\",ICAL_${ucvalue}_VALUE},\n"; - (C) COPYRIGHT 1999 Eric Busboom - http://www.softwarestudio.org + } + + $prop = "NO"; + + my ($uc,$lc,$lcvalue,$ucvalue,$type) = fudge_data($prop); + + print "{ICAL_${uc}_PROPERTY,\"\",ICAL_NO_VALUE}};\n\n"; - 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/ - - 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. - - ======================================================================*/ + print "static struct icalproperty_enum_map enum_map[] = {\n"; -/* - * THIS FILE IS MACHINE GENERATED. DO NOT EDIT - */ + $idx = 10000; + foreach $value (sort keys %valuemap) { + + next if !$value; + next if $value eq 'NO' or $prop eq 'ANY'; -EOM + my $ucv = join("",map {uc(lc($_));} split(/-/,$value)); + my @enums = @{$valuemap{$value}->{'enums'}}; -} + if(@enums){ + my ($c_autogen,$c_type) = @{$valuemap{$value}->{'C'}}; + + unshift(@enums,"X"); + push(@enums,"NONE"); -if ($opt_p and !$opt_i){ + foreach $e (@enums) { -print <<EOM; + my $uce = join("",map {uc(lc($_));} split(/-/,$e)); + + if($e ne "X" and $e ne "NONE"){ + $str = $e; + } else { + $str = ""; + } + + print " {ICAL_${ucv}_PROPERTY,ICAL_${ucv}_${uce},\"$str\" }, /*$idx*/\n"; + + $idx++; + } + + } + } + print " {ICAL_NO_PROPERTY,0,\"\"}\n};\n\n"; -EOM } -foreach $prop (keys %propmap) { - next if !$prop; +if($opt_h){ - my $value = $propmap{$prop}; + # Create the property enumerations list + print "typedef enum icalproperty_kind {\n ICAL_ANY_PROPERTY = 0,\n"; + foreach $prop (sort keys %propmap) { + + next if !$prop; + + next if $prop eq 'NO' or $prop eq 'ANY'; + + my ($uc,$lc,$lcvalue,$ucvalue,$type) = fudge_data($prop); + + print " ICAL_${uc}_PROPERTY, \n"; + + } + print " ICAL_NO_PROPERTY\n} icalproperty_kind;\n\n"; - if (!$value){ - die "Can't find value for property \"$prop\"\n"; - } - my $ucf = join("",map {ucfirst(lc($_));} split(/-/,$prop)); - my $lc = lc($ucf); - my $uc = uc($lc); +} - my $ucfvalue = join("",map {ucfirst(lc($_));} split(/-/,$value)); - my $lcvalue = lc($ucfvalue); - my $ucvalue = uc($lcvalue); - my $type = $valuemap{$value}; +foreach $prop (sort keys %propmap) { + + next if !$prop; + + next if $prop eq 'NO' or $prop eq 'ANY'; + + my ($uc,$lc,$lcvalue,$ucvalue,$type) = fudge_data($prop); + my $pointer_check; if ($type =~ /\*/){ @@ -142,150 +164,54 @@ foreach $prop (keys %propmap) { if($opt_c) { # Generate C source print<<EOM; - /* $prop */ - -icalproperty* icalproperty_new_${lc}($type v) -{ - struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_${uc}_PROPERTY); - $pointer_check - +icalproperty* icalproperty_new_${lc}($type v) { + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_${uc}_PROPERTY); $pointer_check icalproperty_set_${lc}((icalproperty*)impl,v); - return (icalproperty*)impl; } - -icalproperty* icalproperty_vanew_${lc}($type v, ...) -{ +icalproperty* icalproperty_vanew_${lc}($type v, ...){ va_list args; - struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_${uc}_PROPERTY); - $pointer_check - + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_${uc}_PROPERTY); $pointer_check icalproperty_set_${lc}((icalproperty*)impl,v); - va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); - return (icalproperty*)impl; } - -void icalproperty_set_${lc}(icalproperty* prop, $type v) -{ +void icalproperty_set_${lc}(icalproperty* prop, $type v){ icalvalue *value; - $set_pointer_check icalerror_check_arg_rv( (prop!=0),"prop"); - value = icalvalue_new_${lcvalue}(v); - icalproperty_set_value(prop,value); - } - -$type icalproperty_get_${lc}(icalproperty* prop) -{ +$type icalproperty_get_${lc}(icalproperty* prop){ icalvalue *value; icalerror_check_arg( (prop!=0),"prop"); - value = icalproperty_get_value(prop); - return icalvalue_get_${lcvalue}(value); } EOM } elsif ($opt_h) { # Generate C Header file - print<<EOM; - -/* $prop */ -icalproperty* icalproperty_new_${lc}($type v); -icalproperty* icalproperty_vanew_${lc}($type v, ...); -void icalproperty_set_${lc}(icalproperty* prop, $type v); -$type icalproperty_get_${lc}(icalproperty* prop); -EOM + print "\ +/* $prop */\ +icalproperty* icalproperty_new_${lc}($type v);\ +icalproperty* icalproperty_vanew_${lc}($type v, ...);\ +void icalproperty_set_${lc}(icalproperty* prop, $type v);\ +$type icalproperty_get_${lc}(icalproperty* prop);"; -} elsif ($opt_s) { # Generate case in a switch statement - -print <<EOM; -case ICAL_${uc}_PROPERTY: -EOM - - -} elsif ($opt_p) { # Generate perl code - -print <<EOM; - -package Net::ICal::Property::${ucf}; -use Net::ICal::Property; -\@ISA=qw(Net::ICal::Property); -sub new -{ - my \$package = shift; - - my \$p = Net::ICal::icalproperty_new(\$Net::ICal::ICAL_${uc}_PROPERTY); - my \$self = Net::ICal::Property::new_from_ref(\$p); - - \$self->_add_elements(\\\@_); - - return bless \$self, \$package; -} - -sub set_value -{ - my \$self = shift; - my \$v = shift; - - my \$impl = \$self->_impl(); - +} - if ( ref \$v && Net::ICal::icalvalue_isa_value(\$v->_impl())){ - Net::ICal::icalproperty_set_value(\$impl,\$v->_impl); - } else { - my \$value = Net::ICal::icalvalue_new_from_string(\$Net::ICal::ICAL_${ucvalue}_VALUE,\$v); - die if !\$impl; - Net::ICal::icalproperty_set_value(\$impl,\$value) unless !\$value; - } - -} - -sub get_value -{ - my \$self = shift; - my \$impl = \$self->_impl(); - - if (defined \$impl){ - my \$value = Net::ICal::icalproperty_get_value(\$impl); - return "" if !\$value; - return Net::ICal::icalvalue_as_ical_string(\$value); - } else { - return ""; - } -} - -EOM - -} elsif ($opt_m) { # Generate a map - -print "\'${uc}\' => \'Net::ICal::Property::${ucf},\'\n"; - -} } # This brace terminates the main loop -# Add things to the end of the output. - -if ($opt_p) -{ - print "1;\n"; -} - if ($opt_h){ -print <<EOM; -#endif /*ICALPROPERTY_H*/ -EOM +print "\n\n#endif /*ICALPROPERTY_H*/\n" } diff --git a/libical/scripts/mkderivedvalues.pl b/libical/scripts/mkderivedvalues.pl index 10dac3a75f..e7ede34ae7 100755 --- a/libical/scripts/mkderivedvalues.pl +++ b/libical/scripts/mkderivedvalues.pl @@ -1,109 +1,35 @@ #!/usr/bin/perl +use lib '.'; -use Getopt::Std; -getopts('chspi:'); +require 'readvaluesfile.pl'; -#Options -# c -> generate c code file -# h-> generate header file -# s -> generate switch statement +use Getopt::Std; +getopts('chi:'); -# Open with value-c-types.txt + #Options + # c -> generate c code file + # h-> generate header file + # Open with value-types.txt -open(F,"$ARGV[0]") || die "Can't open values data file $ARGV[0]:$!"; +my %h = read_values_file($ARGV[0]); -# Write the file inline by copying everything before a demarcation -# line, and putting the generated data after the demarcation + # Write the file inline by copying everything before a demarcation + # line, and putting the generated data after the demarcation if ($opt_i) { - + open(IN,$opt_i) || die "Can't open input file $opt_i"; - + while(<IN>){ - - if (/Do not edit/){ - last; - } - print; - } - - if($opt_p){ - print "# Everything below this line is machine generated. Do not edit. \n"; - } else { - print "/* Everything below this line is machine generated. Do not edit. */\n"; - } - } -if (($opt_c || $opt_h) and !$opt_i) { -print <<EOM; -/* -*- Mode: C -*- - ====================================================================== - FILE: icalderivedvalues.{c,h} - CREATOR: eric 09 May 1999 - - \044Id:\044 - - (C) COPYRIGHT 1999 Eric Busboom - http://www.softwarestudio.org - - 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/ - - 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. - - ======================================================================*/ - -/* - * THIS FILE IS MACHINE GENERATED DO NOT EDIT - */ - - - -EOM -} - -if ($opt_p and !$opt_i){ - -print <<EOM; -# -*- Mode: Perl -*- -# ====================================================================== -# \044Id:\044 -# -# (C) COPYRIGHT 1999 Eric Busboom -# http://www.softwarestudio.org -# -# 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/ -# -# 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 original author is Eric Busboom -# The original code is derivedvalues.h -# -# ======================================================================*/ - -EOM - -} - -# Map type names to the value in the icalvalue_impl data union */ + # Map type names to the value in the icalvalue_impl data union */ %union_map = ( BOOLEAN => 'int', @@ -118,199 +44,180 @@ EOM URI=>'string', UTCOFFSET=>'int', QUERY=>'string', - BINARY=>'string' + BINARY=>'string', + X=>'string' ); -while(<F>) -{ - - chop; - my @v = split(/\t+/,$_); - - my $value = shift @v; - my $mode = shift @v; - my $type = shift @v; - my $comment = join(" ",@v); - - my $ucf = join("",map {ucfirst(lc($_));} split(/-/,$value)); - - my $lc = lc($ucf); - my $uc = uc($lc); - my $pointer_check = "icalerror_check_arg_rz( (v!=0),\"v\");\n" if $type =~ /\*/; - my $pointer_check_rv = "icalerror_check_arg_rv( (v!=0),\"v\");\n" if $type =~ /\*/; +if($opt_h){ - my $assign; + # First print out the value enumerations + $idx = 5000; + print "typedef enum icalvalue_kind {\n"; + print " ICAL_ANY_VALUE=$idx,\n"; - if ($type =~ /char/){ - $assign = "strdup(v);\n\n if (impl->data.v_string == 0){\n errno = ENOMEM;\n }\n"; - } else { - $assign = "v;"; + foreach $value (keys %h) { + + $idx++; + my $ucv = join("",map {uc(lc($_));} split(/-/,$value)); + + next if $value eq "NO"; + + print " ICAL_${ucv}_VALUE=$idx,\n"; } - - my $union_data; - if (exists $union_map{$uc} ){ - $union_data=$union_map{$uc}; - } else { - $union_data = $lc; - } - - if ($opt_c && $mode eq "autogen") { -print <<EOM; - -icalvalue* -icalvalue_new_${lc} ($type v) -{ - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_${uc}_VALUE); - - $pointer_check - icalvalue_set_${lc}((icalvalue*)impl,v); - - return (icalvalue*)impl; -} - -void -icalvalue_set_${lc}(icalvalue* value, $type v) -{ - struct icalvalue_impl* impl; - - icalerror_check_arg_rv( (value!=0),"value"); - $pointer_check_rv - icalerror_check_value_type(value, ICAL_${uc}_VALUE); - - impl = (struct icalvalue_impl*)value; -EOM - -if( ${union_data} eq 'string'){ -print" if(impl->data.v_${union_data}!=0) {free((void*)impl->data.v_${union_data});}\n"; -} - -print <<EOM; - - impl->data.v_${union_data} = $assign -} - -$type -icalvalue_get_${lc}(icalvalue* value) -{ - icalerror_check_arg( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_${uc}_VALUE); + $idx++; + print " ICAL_NO_VALUE=$idx\n} icalvalue_kind ;\n\n"; - return ((struct icalvalue_impl*)value)->data.v_${union_data}; -} + # Now create enumerations for property values + $idx = 10000; + + print "#define ICALPROPERTY_FIRST_ENUM $idx\n\n"; + + foreach $value (sort keys %h) { + + next if !$value; + + next if $value eq 'NO' or $prop eq 'ANY'; -EOM + my $ucv = join("",map {uc(lc($_));} split(/-/,$value)); + my @enums = @{$h{$value}->{'enums'}}; -} elsif($opt_h && $mode eq "autogen") { + if(@enums){ - print <<EOM; -/* $value $comment */ -icalvalue* icalvalue_new_${lc}($type v); -$type icalvalue_get_${lc}(icalvalue* value); -void icalvalue_set_${lc}(icalvalue* value, ${type} v); + my ($c_autogen,$c_type) = @{$h{$value}->{'C'}}; + print "typedef $c_type {\n"; + my $first = 1; -EOM + unshift(@enums,"X"); -} elsif ($opt_s) { + push(@enums,"NONE"); -if ( $ud{$union_data}++ == 0) { + foreach $e (@enums) { + if (!$first){ + print ",\n"; + } else { + $first = 0; + } + + my $uce = join("",map {uc(lc($_));} split(/-/,$e)); + + print " ICAL_${ucv}_${uce} = $idx"; + + $idx++; + } -print<<EOM; -const char* icalvalue_${union_data}_as_ical_string(icalvalue* value) { + $c_type =~ s/enum //; - $type data; - char temp[1024]; - char *str; - icalerror_check_airg( (value!=0),"value"); - data = ((struct icalvalue_impl*)value)->data.v_${union_data} + print "\n} $c_type;\n\n"; + } + } - str = icalmemory_strdup(temp); + print "#define ICALPROPERTY_LAST_ENUM $idx\n\n"; - return str; } -EOM - -} -} elsif ($opt_p) { # Generate perl code -print <<EOM; +if($opt_c){ -package Net::ICal::Value::${ucf}; -use Net::ICal::Value; -\@ISA=qw(Net::ICal::Value); -sub new -{ - my \$self = []; - my \$package = shift; - my \$value = shift; + # print out the value to string map - bless \$self, \$package; + print "static struct icalvalue_kind_map value_map[]={\n"; - my \$p; + foreach $value (keys %h) { - if (\$value){ - \$p = Net::ICal::icalvalue_new_from_string(\$Net::ICal::ICAL_${uc}_VALUE,\$value); - } else { - \$p = Net::ICal::icalvalue_new(\$Net::ICal::ICAL_${uc}_VALUE); - } + $idx++; + my $ucv = join("",map {uc(lc($_));} split(/-/,$value)); + + next if $value eq "NO"; + + print " {ICAL_${ucv}_VALUE,\"$value\"},\n"; + } - \$self->[0] = \$p; + + print " {ICAL_NO_VALUE,\"\"}\n};"; - return \$self; } -sub set -{ - my \$self = shift; - my \$v = shift; - my \$impl = \$self->_impl(); - - if (\$v) { - my \$new_value = Net::ICal::icalvalue_new_from_string(\$Net::ICal::ICAL_${uc}_VALUE,\$v); - if (\$new_value){ - Net::ICal::icalvalue_free(\$self->[0]); - \$self->[0] = \$new_value; - } - - } - -} +foreach $value (keys %h) { -sub get -{ - my \$self = shift; - my \$impl = \$self->[0]; + my $autogen = $h{$value}->{C}->[0]; + my $type = $h{$value}->{C}->[1]; - if (defined \$impl){ - - return Net::ICal::icalvalue_as_ical_string(\$impl); + my $ucf = join("",map {ucfirst(lc($_));} split(/-/,$value)); + + my $lc = lc($ucf); + my $uc = uc($lc); + + my $pointer_check = "icalerror_check_arg_rz( (v!=0),\"v\");\n" if $type =~ /\*/; + my $pointer_check_rv = "icalerror_check_arg_rv( (v!=0),\"v\");\n" if $type =~ /\*/; + + my $assign; + + if ($type =~ /char/){ + $assign = "icalmemory_strdup(v);\n\n if (impl->data.v_string == 0){\n errno = ENOMEM;\n }\n"; + } else { + $assign = "v;"; + } + + my $union_data; + + if(@{$h{$value}->{'enums'}}){ + $union_data = 'enum'; - } -} + } elsif (exists $union_map{$uc} ){ + $union_data=$union_map{$uc}; + } else { + $union_data = $lc; + } + + if ($opt_c && $autogen) { + + print "\n\n\ +icalvalue* icalvalue_new_${lc} ($type v){\ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_${uc}_VALUE);\ + $pointer_check\ + icalvalue_set_${lc}((icalvalue*)impl,v);\ + return (icalvalue*)impl;\ +}\ +void icalvalue_set_${lc}(icalvalue* value, $type v) {\ + struct icalvalue_impl* impl; \ + icalerror_check_arg_rv( (value!=0),\"value\");\ + $pointer_check_rv\ + icalerror_check_value_type(value, ICAL_${uc}_VALUE);\ + impl = (struct icalvalue_impl*)value;\n"; + + if( $union_data eq 'string') { + + print " if(impl->data.v_${union_data}!=0) {free((void*)impl->data.v_${union_data});}\n"; + } + -EOM -} + print "\n impl->data.v_$union_data = $assign \n }\n"; + print "$type\ icalvalue_get_${lc}(icalvalue* value)\ {\n\ + icalerror_check_arg( (value!=0),\"value\");\ + icalerror_check_value_type(value, ICAL_${uc}_VALUE);\ + return ((struct icalvalue_impl*)value)->data.v_${union_data};\n}\n"; + + } elsif($opt_h && $autogen) { + + print "\n /* $value */ \ +icalvalue* icalvalue_new_${lc}($type v); \ +$type icalvalue_get_${lc}(icalvalue* value); \ +void icalvalue_set_${lc}(icalvalue* value, ${type} v);\n\n"; -} + } -if ($opt_p) -{ - print "1;\n"; } - - + + if ($opt_h){ - -print <<EOM; -#endif /*ICALVALUE_H*/ -EOM -} - - -__END__ - + print "#endif /*ICALVALUE_H*/\n"; + } + + + __END__ + diff --git a/libical/src/Makefile.am b/libical/src/Makefile.am index bff5609c92..108581258d 100644 --- a/libical/src/Makefile.am +++ b/libical/src/Makefile.am @@ -1,4 +1,7 @@ -SUBDIRS = libical libicalvcal +if WITH_PYTHON +PYTHON_DIR = python +else +PYTHON_DIR = +endif -# disabled libicalss and test until they build -#SUBDIRS = libical libicalss libicalvcal test +SUBDIRS = libical libicalss libicalvcal $(PYTHON_DIR) test diff --git a/libical/src/libical/Makefile.am b/libical/src/libical/Makefile.am index 186e705060..e66f805201 100644 --- a/libical/src/libical/Makefile.am +++ b/libical/src/libical/Makefile.am @@ -1,3 +1,28 @@ +#====================================================================== +# FILE: Makefile.am +# CREATOR: eric +# +# $Id: Makefile.am,v 1.27 2001/04/17 17:54:44 jpr Exp $ +# +# +# (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of either: +# +# The LGPL as published by the Free Software Foundation, version +# 2.1, available at: http://www.fsf.org/copyleft/lesser.html +# +# Or: +# +# The Mozilla Public License Version 1.0. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# The original code is icalcomponent.c +# +#====================================================================== + + DESIGNDATA = $(top_srcdir)/design-data ICALSCRIPTS = $(top_srcdir)/scripts @@ -20,6 +45,8 @@ INCLUDES = \ libical_la_LDFLAGS = -version-info 0:0:0 libical_la_SOURCES = \ + icalattendee.h \ + icalattendee.c \ icalcomponent.c \ icalcomponent.h \ icalenums.c \ @@ -33,8 +60,13 @@ libical_la_SOURCES = \ icalmime.h \ icalparameter.c \ icalparameter.h \ + icalparameterimpl.h \ + icalderivedparameter.c \ + icalderivedparameter.h \ icalparser.c \ icalparser.h \ + icalderivedproperty.c \ + icalderivedproperty.h \ icalproperty.c \ icalproperty.h \ icalrecur.c \ @@ -43,10 +75,17 @@ libical_la_SOURCES = \ icalrestriction.h \ icaltime.c \ icaltime.h \ + icalduration.h \ + icalduration.c \ + icalperiod.h \ + icalperiod.c \ icaltypes.c \ icaltypes.h \ icalvalue.c \ icalvalue.h \ + icalvalueimpl.h \ + icalderivedvalue.c \ + icalderivedvalue.h \ icalyacc.h \ icalyacc.y \ pvl.c \ @@ -66,31 +105,37 @@ libicalinclude_HEADERS = ical.h COMBINEDHEADERS = \ $(top_builddir)/src/libical/icalversion.h \ $(top_srcdir)/src/libical/icaltime.h \ + $(top_srcdir)/src/libical/icalduration.h \ + $(top_srcdir)/src/libical/icalperiod.h \ $(top_srcdir)/src/libical/icalenums.h \ $(top_srcdir)/src/libical/icaltypes.h \ $(top_srcdir)/src/libical/icalrecur.h \ - icalvalue.h \ - icalparameter.h \ - icalproperty.h \ + $(top_builddir)/src/libical/icalderivedvalue.h \ + $(top_builddir)/src/libical/icalderivedparameter.h\ + $(top_srcdir)/src/libical/icalvalue.h \ + $(top_srcdir)/src/libical/icalparameter.h \ + $(top_builddir)/src/libical/icalderivedproperty.h\ + $(top_srcdir)/src/libical/icalproperty.h \ + $(top_srcdir)/src/libical/icalattendee.h \ $(top_srcdir)/src/libical/pvl.h \ $(top_srcdir)/src/libical/icalcomponent.h \ $(top_srcdir)/src/libical/icalparser.h \ $(top_srcdir)/src/libical/icalmemory.h \ $(top_srcdir)/src/libical/icalerror.h \ - icalrestriction.h \ + $(top_srcdir)/src/libical/icalrestriction.h \ $(top_srcdir)/src/libical/sspm.h \ $(top_srcdir)/src/libical/icalmime.h \ - $(top_srcdir)/src/libical/icallangbind.h + $(top_srcdir)/src/libical/icallangbind.h BUILT_SOURCES = \ ical.h \ - icalparameter.c \ - icalparameter.h \ - icalproperty.c \ - icalproperty.h \ + icalderivedparameter.c \ + icalderivedparameter.h \ + icalderivedproperty.c \ + icalderivedproperty.h \ icalrestriction.c \ - icalvalue.c \ - icalvalue.h + icalderivedvalue.c \ + icalderivedvalue.h ical.h: $(BUILT_SOURCES) cat $(COMBINEDHEADERS) \ @@ -104,37 +149,35 @@ icallexer.c : icalyacc.h PARAMETERDEPS = \ $(ICALSCRIPTS)/mkderivedparameters.pl \ - $(DESIGNDATA)/param-c-types.txt \ - icalparameter.c.in \ - icalparameter.h.in + $(DESIGNDATA)/parameters.csv \ + icalderivedparameter.c.in \ + icalderivedparameter.h.in -icalparameter.h: $(PARAMETERDEPS) - $(PERL) $(ICALSCRIPTS)/mkderivedparameters.pl -i $(srcdir)/icalparameter.h.in -h $(DESIGNDATA)/param-c-types.txt > icalparameter.newh \ - && mv icalparameter.newh icalparameter.h +icalderivedparameter.h: $(PARAMETERDEPS) + $(PERL) -I $(ICALSCRIPTS) $(ICALSCRIPTS)/mkderivedparameters.pl -i $(srcdir)/icalderivedparameter.h.in -h $(DESIGNDATA)/parameters.csv > icalderivedparameter.h -icalparameter.c: $(PARAMETERDEPS) icalparameter.h - $(PERL) $(ICALSCRIPTS)/mkderivedparameters.pl -i $(srcdir)/icalparameter.c.in -c $(DESIGNDATA)/param-c-types.txt > icalparameter.newc \ - && mv icalparameter.newc icalparameter.c +icalderivedparameter.c: $(PARAMETERDEPS) icalparameter.h + $(PERL) -I $(ICALSCRIPTS) $(ICALSCRIPTS)/mkderivedparameters.pl -i $(srcdir)/icalderivedparameter.c.in -c $(DESIGNDATA)/parameters.csv > icalderivedparameter.c # properties PROPERTYDEPS = \ $(ICALSCRIPTS)/mkderivedproperties.pl \ - $(DESIGNDATA)/prop-to-value.txt \ - $(DESIGNDATA)/value-c-types.txt \ - icalproperty.c.in \ - icalproperty.h.in + $(DESIGNDATA)/properties.csv \ + $(DESIGNDATA)/value-types.csv \ + icalderivedproperty.c.in \ + icalderivedproperty.h.in -icalproperty.h: $(PROPERTYDEPS) - $(PERL) $(ICALSCRIPTS)/mkderivedproperties.pl -i $(srcdir)/icalproperty.h.in -h \ - $(DESIGNDATA)/prop-to-value.txt \ - ${DESIGNDATA}/value-c-types.txt > icalproperty.h +icalderivedproperty.h: $(PROPERTYDEPS) + $(PERL) -I$(ICALSCRIPTS) $(ICALSCRIPTS)/mkderivedproperties.pl \ + -i $(srcdir)/icalderivedproperty.h.in -h $(DESIGNDATA)/properties.csv\ + ${DESIGNDATA}/value-types.csv > icalderivedproperty.h -icalproperty.c: $(PROPERTYDEPS) icalproperty.h - $(PERL) $(ICALSCRIPTS)/mkderivedproperties.pl -i $(srcdir)/icalproperty.c.in -c \ - $(DESIGNDATA)/prop-to-value.txt \ - ${DESIGNDATA}/value-c-types.txt > icalproperty.c +icalderivedproperty.c: $(PROPERTYDEPS) icalproperty.h + $(PERL) -I$(ICALSCRIPTS) $(ICALSCRIPTS)/mkderivedproperties.pl \ + -i $(srcdir)/icalderivedproperty.c.in -c $(DESIGNDATA)/properties.csv \ + ${DESIGNDATA}/value-types.csv > icalderivedproperty.c # restrictions @@ -151,33 +194,37 @@ icalrestriction.c: $(RESTRICTIONDEPS) VALUEDEPS = \ $(ICALSCRIPTS)/mkderivedvalues.pl \ - $(DESIGNDATA)/value-c-types.txt \ - icalvalue.c.in \ - icalvalue.h.in + $(DESIGNDATA)/value-types.csv \ + icalderivedvalue.c.in \ + icalderivedvalue.h.in -icalvalue.h: $(VALUEDEPS) - $(PERL) $(ICALSCRIPTS)/mkderivedvalues.pl -i $(srcdir)/icalvalue.h.in -h \ - $(DESIGNDATA)/value-c-types.txt > icalvalue.h +icalderivedvalue.h: $(VALUEDEPS) + $(PERL) -I$(ICALSCRIPTS) $(ICALSCRIPTS)/mkderivedvalues.pl \ + -i $(srcdir)/icalderivedvalue.h.in -h $(DESIGNDATA)/value-types.csv > icalderivedvalue.h -icalvalue.c: $(VALUEDEPS) icalvalue.h - $(PERL) $(ICALSCRIPTS)/mkderivedvalues.pl -i $(srcdir)/icalvalue.c.in -c \ - $(DESIGNDATA)/value-c-types.txt > icalvalue.c +icalderivedvalue.c: $(VALUEDEPS) icalderivedvalue.h + $(PERL) -I$(ICALSCRIPTS) $(ICALSCRIPTS)/mkderivedvalues.pl \ + -i $(srcdir)/icalderivedvalue.c.in -c $(DESIGNDATA)/value-types.csv > icalderivedvalue.c # housekeeping CONFIG_CLEAN_FILES = y.output +CLEANFILES += $(BUILT_SOURCES) + +dist-hook: + cd $(distdir); rm -f $(BUILT_SOURCES) + EXTRA_DIST = \ - icalparameter.c.in \ - icalparameter.h.in \ - icalproperty.c.in \ - icalproperty.h.in \ + icalderivedparameter.c.in \ + icalderivedparameter.h.in \ + icalderivedproperty.c.in \ + icalderivedproperty.h.in \ icalrestriction.c.in \ - icalvalue.c.in \ - icalvalue.h.in \ + icalderivedvalue.c.in \ + icalderivedvalue.h.in \ icalversion.h.in \ - $(BUILT_SOURCES) \ icallexer.c \ icalyacc.c diff --git a/libical/src/libical/icalcomponent.c b/libical/src/libical/icalcomponent.c index 3ac0ee0663..c28c972007 100644 --- a/libical/src/libical/icalcomponent.c +++ b/libical/src/libical/icalcomponent.c @@ -33,6 +33,9 @@ #include "icalmemory.h" #include "icalenums.h" #include "icaltime.h" +#include "icalduration.h" +#include "icalperiod.h" +#include "icalparser.h" #include <stdlib.h> /* for malloc */ #include <stdarg.h> /* for va_list, etc */ @@ -135,17 +138,7 @@ icalcomponent_vanew (icalcomponent_kind kind, ...) icalcomponent* icalcomponent_new_from_string(char* str) { - icalcomponent_kind kind; - - icalerror_check_arg_rz( (str!=0), "str"); - - kind = icalenum_string_to_component_kind(str); - - if (kind == ICAL_NO_COMPONENT){ - return 0; - } - - return icalcomponent_new(kind); + return icalparser_parse_string(str); } icalcomponent* icalcomponent_new_clone(icalcomponent* component) @@ -156,7 +149,7 @@ icalcomponent* icalcomponent_new_clone(icalcomponent* component) icalcomponent *c; pvl_elem itr; - icalerror_check_arg_rv( (component!=0), "component"); + icalerror_check_arg_rz( (component!=0), "component"); new = icalcomponent_new_impl(old->kind); @@ -996,6 +989,78 @@ void icalcomponent_set_parent(icalcomponent* component, icalcomponent* parent) icalcompiter icalcompiter_null = {ICAL_NO_COMPONENT,0}; + +struct icalcomponent_kind_map { + icalcomponent_kind kind; + char name[20]; +}; + + + +static struct icalcomponent_kind_map component_map[] = +{ + { ICAL_VEVENT_COMPONENT, "VEVENT" }, + { ICAL_VTODO_COMPONENT, "VTODO" }, + { ICAL_VJOURNAL_COMPONENT, "VJOURNAL" }, + { ICAL_VCALENDAR_COMPONENT, "VCALENDAR" }, + { ICAL_VFREEBUSY_COMPONENT, "VFREEBUSY" }, + { ICAL_VTIMEZONE_COMPONENT, "VTIMEZONE" }, + { ICAL_VALARM_COMPONENT, "VALARM" }, + { ICAL_XSTANDARD_COMPONENT, "STANDARD" }, /*These are part of RFC2445 */ + { ICAL_XDAYLIGHT_COMPONENT, "DAYLIGHT" }, /*but are not really components*/ + { ICAL_X_COMPONENT, "X" }, + { ICAL_VSCHEDULE_COMPONENT, "SCHEDULE" }, + + /* CAP components */ + { ICAL_VQUERY_COMPONENT, "VQUERY" }, + { ICAL_VCAR_COMPONENT, "VCAR" }, + { ICAL_VCOMMAND_COMPONENT, "VCOMMAND" }, + + /* libical private components */ + { ICAL_XLICINVALID_COMPONENT, "X-LIC-UNKNOWN" }, + { ICAL_XLICMIMEPART_COMPONENT, "X-LIC-MIME-PART" }, + { ICAL_ANY_COMPONENT, "ANY" }, + { ICAL_XROOT_COMPONENT, "XROOT" }, + + /* End of list */ + { ICAL_NO_COMPONENT, "" }, +}; + + + +const char* icalcomponent_kind_to_string(icalcomponent_kind kind) +{ + int i; + + for (i=0; component_map[i].kind != ICAL_NO_COMPONENT; i++) { + if (component_map[i].kind == kind) { + return component_map[i].name; + } + } + + return 0; + +} + +icalcomponent_kind icalcomponent_string_to_kind(const char* string) +{ + int i; + + if (string ==0 ) { + return ICAL_NO_COMPONENT; + } + + for (i=0; component_map[i].kind != ICAL_NO_COMPONENT; i++) { + if (strcmp(component_map[i].name, string) == 0) { + return component_map[i].kind; + } + } + + return ICAL_NO_COMPONENT; +} + + + icalcompiter icalcomponent_begin_component(icalcomponent* component,icalcomponent_kind kind) { @@ -1374,9 +1439,6 @@ const char* icalcomponent_get_summary(icalcomponent* comp) void icalcomponent_set_comment(icalcomponent* comp, const char* v); const char* icalcomponent_get_comment(icalcomponent* comp); -void icalcomponent_set_organizer(icalcomponent* comp, const char* v); -const char* icalcomponent_get_organizer(icalcomponent* comp); - void icalcomponent_set_uid(icalcomponent* comp, const char* v); const char* icalcomponent_get_uid(icalcomponent* comp); @@ -1403,6 +1465,10 @@ icalcomponent* icalcomponent_new_vjournal() { return icalcomponent_new(ICAL_VJOURNAL_COMPONENT); } +icalcomponent* icalcomponent_new_valarm() +{ + return icalcomponent_new(ICAL_VALARM_COMPONENT); +} icalcomponent* icalcomponent_new_vfreebusy() { return icalcomponent_new(ICAL_VFREEBUSY_COMPONENT); diff --git a/libical/src/libical/icalcomponent.h b/libical/src/libical/icalcomponent.h index 61f4bf0dbf..6046bbee1e 100644 --- a/libical/src/libical/icalcomponent.h +++ b/libical/src/libical/icalcomponent.h @@ -27,6 +27,7 @@ #include "icalproperty.h" #include "icalvalue.h" #include "icalenums.h" /* defines icalcomponent_kind */ +#include "icalattendee.h" #include "pvl.h" typedef void icalcomponent; @@ -75,11 +76,6 @@ icalproperty* icalcomponent_get_first_property(icalcomponent* component, icalproperty* icalcomponent_get_next_property(icalcomponent* component, icalproperty_kind kind); -/* Return a null-terminated array of icalproperties*/ - -icalproperty** icalcomponent_get_properties(icalcomponent* component, - icalproperty_kind kind); - /* * Working with components @@ -104,16 +100,8 @@ int icalcomponent_count_components(icalcomponent* component, /* Iteration Routines. There are two forms of iterators, internal and external. The internal ones came first, and are almost completely sufficient, but they fail badly when you want to construct a loop that -removes components from the container. +removes components from the container.*/ -The internal iterators are deprecated. */ - -/* Using external iterators */ -icalcompiter icalcomponent_begin_component(icalcomponent* component, - icalcomponent_kind kind); - -icalcompiter icalcomponent_end_component(icalcomponent* component, - icalcomponent_kind kind); /* Iterate through components */ icalcomponent* icalcomponent_get_current_component (icalcomponent* component); @@ -123,6 +111,15 @@ icalcomponent* icalcomponent_get_first_component(icalcomponent* component, icalcomponent* icalcomponent_get_next_component(icalcomponent* component, icalcomponent_kind kind); +/* Using external iterators */ +icalcompiter icalcomponent_begin_component(icalcomponent* component, + icalcomponent_kind kind); +icalcompiter icalcomponent_end_component(icalcomponent* component, + icalcomponent_kind kind); +icalcomponent* icalcompiter_next(icalcompiter* i); +icalcomponent* icalcompiter_prior(icalcompiter* i); +icalcomponent* icalcompiter_deref(icalcompiter* i); + @@ -136,14 +133,17 @@ void icalcomponent_strip_errors(icalcomponent* component); /* Convert some X-LIC-ERROR properties into RETURN-STATUS properties*/ void icalcomponent_convert_errors(icalcomponent* component); -/* Internal operations. You don't see these... */ +/* Internal operations. They are private, and you should not be using them. */ icalcomponent* icalcomponent_get_parent(icalcomponent* component); void icalcomponent_set_parent(icalcomponent* component, icalcomponent* parent); -/* External component iterator */ -icalcomponent* icalcompiter_next(icalcompiter* i); -icalcomponent* icalcompiter_prior(icalcompiter* i); -icalcomponent* icalcompiter_deref(icalcompiter* i); + +/* Kind conversion routiens */ + +icalcomponent_kind icalcomponent_string_to_kind(const char* string); + +const char* icalcomponent_kind_to_string(icalcomponent_kind kind); + /************* Derived class methods. **************************** @@ -194,9 +194,6 @@ const char* icalcomponent_get_summary(icalcomponent* comp); void icalcomponent_set_comment(icalcomponent* comp, const char* v); const char* icalcomponent_get_comment(icalcomponent* comp); -void icalcomponent_set_organizer(icalcomponent* comp, const char* v); -const char* icalcomponent_get_organizer(icalcomponent* comp); - void icalcomponent_set_uid(icalcomponent* comp, const char* v); const char* icalcomponent_get_uid(icalcomponent* comp); @@ -204,12 +201,32 @@ void icalcomponent_set_recurrenceid(icalcomponent* comp, struct icaltimetype v); struct icaltimetype icalcomponent_get_recurrenceid(icalcomponent* comp); + +void icalcomponent_set_organizer(icalcomponent* comp, + struct icalorganizertype org); + struct icalorganizertype icalcomponent_get_organizer(icalcomponent* comp); + + +void icalcomponent_add_attendee(icalcomponent *comp, + struct icalattendeetype attendee); + +int icalcomponent_remove_attendee(icalcomponent *comp, char* cuid); + +/* Get the Nth attendee. Out of range indices return an attendee + with cuid == 0 */ +struct icalattendeetype icalcomponent_get_attendee(icalcomponent *comp, + int index); + + + + /*************** Type Specific routines ***************/ icalcomponent* icalcomponent_new_vcalendar(); icalcomponent* icalcomponent_new_vevent(); icalcomponent* icalcomponent_new_vtodo(); icalcomponent* icalcomponent_new_vjournal(); +icalcomponent* icalcomponent_new_valarm(); icalcomponent* icalcomponent_new_vfreebusy(); icalcomponent* icalcomponent_new_vtimezone(); icalcomponent* icalcomponent_new_xstandard(); diff --git a/libical/src/libical/icalenums.c b/libical/src/libical/icalenums.c index 78ca5d7ebe..6751933c3e 100644 --- a/libical/src/libical/icalenums.c +++ b/libical/src/libical/icalenums.c @@ -35,408 +35,6 @@ #include <string.h> /* For strncmp */ #include <assert.h> -struct icalproperty_kind_map { - icalproperty_kind kind; - const char *name; -}; - -static struct icalproperty_kind_map property_map[] = -{ - { ICAL_ANY_PROPERTY, "ANY"}, - { ICAL_ACTION_PROPERTY, "ACTION"}, - { ICAL_ATTACH_PROPERTY, "ATTACH"}, - { ICAL_ATTENDEE_PROPERTY, "ATTENDEE"}, - { ICAL_CALSCALE_PROPERTY, "CALSCALE"}, - { ICAL_CATEGORIES_PROPERTY, "CATEGORIES"}, - { ICAL_CLASS_PROPERTY, "CLASS"}, - { ICAL_COMMENT_PROPERTY, "COMMENT"}, - { ICAL_COMPLETED_PROPERTY, "COMPLETED"}, - { ICAL_CONTACT_PROPERTY, "CONTACT"}, - { ICAL_CREATED_PROPERTY, "CREATED"}, - { ICAL_DESCRIPTION_PROPERTY, "DESCRIPTION"}, - { ICAL_DTEND_PROPERTY, "DTEND"}, - { ICAL_DTSTAMP_PROPERTY, "DTSTAMP"}, - { ICAL_DTSTART_PROPERTY, "DTSTART"}, - { ICAL_DUE_PROPERTY, "DUE"}, - { ICAL_DURATION_PROPERTY, "DURATION"}, - { ICAL_EXDATE_PROPERTY, "EXDATE"}, - { ICAL_EXRULE_PROPERTY, "EXRULE"}, - { ICAL_FREEBUSY_PROPERTY, "FREEBUSY"}, - { ICAL_GEO_PROPERTY, "GEO"}, - { ICAL_LASTMODIFIED_PROPERTY, "LAST-MODIFIED"}, - { ICAL_LOCATION_PROPERTY, "LOCATION"}, - { ICAL_METHOD_PROPERTY, "METHOD"}, - { ICAL_ORGANIZER_PROPERTY, "ORGANIZER"}, - { ICAL_PERCENTCOMPLETE_PROPERTY, "PERCENT-COMPLETE"}, - { ICAL_PRIORITY_PROPERTY, "PRIORITY"}, - { ICAL_PRODID_PROPERTY, "PRODID"}, - { ICAL_RDATE_PROPERTY, "RDATE"}, - { ICAL_RECURRENCEID_PROPERTY, "RECURRENCE-ID"}, - { ICAL_RELATEDTO_PROPERTY, "RELATED-TO"}, - { ICAL_REPEAT_PROPERTY, "REPEAT"}, - { ICAL_REQUESTSTATUS_PROPERTY, "REQUEST-STATUS"}, - { ICAL_RESOURCES_PROPERTY, "RESOURCES"}, - { ICAL_RRULE_PROPERTY, "RRULE"}, - { ICAL_SEQUENCE_PROPERTY, "SEQUENCE"}, - { ICAL_STATUS_PROPERTY, "STATUS"}, - { ICAL_SUMMARY_PROPERTY, "SUMMARY"}, - { ICAL_TRANSP_PROPERTY, "TRANSP"}, - { ICAL_TRIGGER_PROPERTY, "TRIGGER"}, - { ICAL_TZID_PROPERTY, "TZID"}, - { ICAL_TZNAME_PROPERTY, "TZNAME"}, - { ICAL_TZOFFSETFROM_PROPERTY, "TZOFFSETFROM"}, - { ICAL_TZOFFSETTO_PROPERTY, "TZOFFSETTO"}, - { ICAL_TZURL_PROPERTY, "TZURL"}, - { ICAL_UID_PROPERTY, "UID"}, - { ICAL_URL_PROPERTY, "URL"}, - { ICAL_VERSION_PROPERTY, "VERSION"}, - { ICAL_X_PROPERTY,"X_PROPERTY"}, - - /* CAP Object Properties */ - - { ICAL_SCOPE_PROPERTY, "SCOPE"}, - { ICAL_MAXRESULTS_PROPERTY, "MAXRESULTS"}, - { ICAL_MAXRESULTSSIZE_PROPERTY, "MAXRESULTSSIZE"}, - { ICAL_QUERY_PROPERTY, "QUERY" }, - { ICAL_QUERYNAME_PROPERTY, "QUERYNAME" }, - { ICAL_TARGET_PROPERTY, "TARGET"}, - - /* libical private properties */ - { ICAL_XLICERROR_PROPERTY,"X-LIC-ERROR"}, - { ICAL_XLICMIMECONTENTTYPE_PROPERTY,"X-LIC-MIME-CONTENT-TYPE"}, - { ICAL_XLICMIMEENCODING_PROPERTY,"X-LIC-MIME-ENCODING"}, - { ICAL_XLICMIMEOPTINFO_PROPERTY,"X-LIC-MIME-OPT-INFO"}, - { ICAL_XLICMIMECHARSET_PROPERTY,"X-LIC-MIME-CHARSET"}, - { ICAL_XLICCLUSTERCOUNT_PROPERTY,"X-LIC-CLUSTERCOUNT"}, - - /* End of the list */ - { ICAL_NO_PROPERTY, ""} -}; - - -const char* icalenum_property_kind_to_string(icalproperty_kind kind) -{ - int i; - - for (i=0; property_map[i].kind != ICAL_NO_PROPERTY; i++) { - if (property_map[i].kind == kind) { - return property_map[i].name; - } - } - - return 0; - -} - -icalproperty_kind icalenum_string_to_property_kind(const char* string) -{ - int i; - - if (string ==0 ) { - return ICAL_NO_PROPERTY; - } - - - for (i=0; property_map[i].kind != ICAL_NO_PROPERTY; i++) { - if (strcmp(property_map[i].name, string) == 0) { - return property_map[i].kind; - } - } - - if(strncmp(string,"X-",2)==0){ - return ICAL_X_PROPERTY; - } - - - return ICAL_NO_PROPERTY; -} - - - - -struct icalparameter_kind_map { - icalparameter_kind kind; - char name[20]; -}; - -static struct icalparameter_kind_map parameter_map[] = -{ - { ICAL_ALTREP_PARAMETER, "ALTREP"}, - { ICAL_CN_PARAMETER, "CN"}, - { ICAL_CUTYPE_PARAMETER, "CUTYPE"}, - { ICAL_DELEGATEDFROM_PARAMETER, "DELEGATED-FROM"}, - { ICAL_DELEGATEDTO_PARAMETER, "DELEGATED-TO"}, - { ICAL_DIR_PARAMETER, "DIR"}, - { ICAL_ENCODING_PARAMETER, "ENCODING"}, - { ICAL_FBTYPE_PARAMETER, "FBTYPE"}, - { ICAL_FMTTYPE_PARAMETER, "FMTTYPE"}, - { ICAL_LANGUAGE_PARAMETER, "LANGUAGE"}, - { ICAL_MEMBER_PARAMETER, "MEMBER"}, - { ICAL_PARTSTAT_PARAMETER, "PARTSTAT"}, - { ICAL_RANGE_PARAMETER, "RANGE"}, - { ICAL_RELATED_PARAMETER, "RELATED"}, - { ICAL_RELTYPE_PARAMETER, "RELTYPE"}, - { ICAL_ROLE_PARAMETER, "ROLE"}, - { ICAL_RSVP_PARAMETER, "RSVP"}, - { ICAL_SENTBY_PARAMETER, "SENT-BY"}, - { ICAL_TZID_PARAMETER, "TZID"}, - { ICAL_VALUE_PARAMETER, "VALUE"}, - { ICAL_X_PARAMETER, "X"}, - - /* CAP parameters */ - - /* libical private parameters */ - { ICAL_XLICERRORTYPE_PARAMETER, "X-LIC-ERRORTYPE"}, - { ICAL_XLICCOMPARETYPE_PARAMETER, "X-LIC-COMPARETYPE"}, - - /* End of list */ - { ICAL_NO_PARAMETER, ""} -}; - -const char* icalenum_parameter_kind_to_string(icalparameter_kind kind) -{ - int i; - - for (i=0; parameter_map[i].kind != ICAL_NO_PARAMETER; i++) { - if (parameter_map[i].kind == kind) { - return parameter_map[i].name; - } - } - - return 0; - -} - -icalparameter_kind icalenum_string_to_parameter_kind(const char* string) -{ - int i; - - if (string ==0 ) { - return ICAL_NO_PARAMETER; - } - - for (i=0; parameter_map[i].kind != ICAL_NO_PARAMETER; i++) { - if (strcmp(parameter_map[i].name, string) == 0) { - return parameter_map[i].kind; - } - } - - if(strncmp(string,"X-",2)==0){ - return ICAL_X_PARAMETER; - } - - return ICAL_NO_PARAMETER; -} - -struct icalvalue_kind_map { - icalvalue_kind kind; - char name[20]; -}; - -static struct icalvalue_kind_map value_map[] = -{ - { ICAL_BINARY_VALUE, "BINARY"}, - { ICAL_BOOLEAN_VALUE, "BOOLEAN"}, - { ICAL_CALADDRESS_VALUE, "CAL-ADDRESS"}, - { ICAL_DATE_VALUE, "DATE"}, - { ICAL_DATETIME_VALUE, "DATE-TIME"}, - { ICAL_DURATION_VALUE, "DURATION"}, - { ICAL_FLOAT_VALUE, "FLOAT"}, - { ICAL_INTEGER_VALUE, "INTEGER"}, - { ICAL_PERIOD_VALUE, "PERIOD"}, - { ICAL_RECUR_VALUE, "RECUR"}, - { ICAL_TEXT_VALUE, "TEXT"}, - { ICAL_TIME_VALUE, "TIME"}, - { ICAL_URI_VALUE, "URI"}, - { ICAL_UTCOFFSET_VALUE, "UTC-OFFSET"}, - { ICAL_METHOD_VALUE, "METHOD"}, /* Not an RFC2445 type */ - { ICAL_STATUS_VALUE, "STATUS"}, /* Not an RFC2445 type */ - { ICAL_GEO_VALUE, "FLOAT"}, /* Not an RFC2445 type */ - { ICAL_ATTACH_VALUE, "ATTACH"}, /* Not an RFC2445 type */ - { ICAL_DATETIMEDATE_VALUE, "DATETIMEDATE"}, /* Not an RFC2445 type */ - { ICAL_DATETIMEPERIOD_VALUE, "DATETIMEPERIOD"}, /* Not an RFC2445 type */ - { ICAL_TRIGGER_VALUE, "TRIGGER"}, /* Not an RFC2445 type */ - { ICAL_QUERY_VALUE, "QUERY"}, - { ICAL_NO_VALUE, ""}, -}; - -const char* icalenum_value_kind_to_string(icalvalue_kind kind) -{ - int i; - - for (i=0; value_map[i].kind != ICAL_NO_VALUE; i++) { - if (value_map[i].kind == kind) { - return value_map[i].name; - } - } - - return 0; - -} - -icalvalue_kind icalenum_value_kind_by_prop(icalproperty_kind kind) -{ - fprintf(stderr,"icalenum_value_kind_by_prop is not implemented\n"); - assert(0) ; - kind = ICAL_NO_VALUE; - return ICAL_NO_VALUE; -} - - -struct icalcomponent_kind_map { - icalcomponent_kind kind; - char name[20]; -}; - - - -static struct icalcomponent_kind_map component_map[] = -{ - { ICAL_VEVENT_COMPONENT, "VEVENT" }, - { ICAL_VTODO_COMPONENT, "VTODO" }, - { ICAL_VJOURNAL_COMPONENT, "VJOURNAL" }, - { ICAL_VCALENDAR_COMPONENT, "VCALENDAR" }, - { ICAL_VFREEBUSY_COMPONENT, "VFREEBUSY" }, - { ICAL_VTIMEZONE_COMPONENT, "VTIMEZONE" }, - { ICAL_VALARM_COMPONENT, "VALARM" }, - { ICAL_XSTANDARD_COMPONENT, "STANDARD" }, /*These are part of RFC2445 */ - { ICAL_XDAYLIGHT_COMPONENT, "DAYLIGHT" }, /*but are not really components*/ - { ICAL_X_COMPONENT, "X" }, - { ICAL_VSCHEDULE_COMPONENT, "SCHEDULE" }, - - /* CAP components */ - { ICAL_VQUERY_COMPONENT, "VQUERY" }, - { ICAL_VCAR_COMPONENT, "VCAR" }, - { ICAL_VCOMMAND_COMPONENT, "VCOMMAND" }, - - /* libical private components */ - { ICAL_XLICINVALID_COMPONENT, "X-LIC-UNKNOWN" }, - { ICAL_XLICMIMEPART_COMPONENT, "X-LIC-MIME-PART" }, - { ICAL_ANY_COMPONENT, "ANY" }, - { ICAL_XROOT_COMPONENT, "XROOT" }, - - /* End of list */ - { ICAL_NO_COMPONENT, "" }, -}; - -const char* icalenum_component_kind_to_string(icalcomponent_kind kind) -{ - int i; - - for (i=0; component_map[i].kind != ICAL_NO_COMPONENT; i++) { - if (component_map[i].kind == kind) { - return component_map[i].name; - } - } - - return 0; - -} - -icalcomponent_kind icalenum_string_to_component_kind(const char* string) -{ - int i; - - if (string ==0 ) { - return ICAL_NO_COMPONENT; - } - - for (i=0; component_map[i].kind != ICAL_NO_COMPONENT; i++) { - if (strcmp(component_map[i].name, string) == 0) { - return component_map[i].kind; - } - } - - return ICAL_NO_COMPONENT; -} - -struct icalproperty_kind_value_map { - icalproperty_kind prop; - icalvalue_kind value; -}; - -static struct icalproperty_kind_value_map propval_map[] = -{ - { ICAL_CALSCALE_PROPERTY, ICAL_TEXT_VALUE }, - { ICAL_METHOD_PROPERTY, ICAL_METHOD_VALUE }, - { ICAL_PRODID_PROPERTY, ICAL_TEXT_VALUE }, - { ICAL_VERSION_PROPERTY, ICAL_TEXT_VALUE }, - { ICAL_CATEGORIES_PROPERTY, ICAL_TEXT_VALUE }, - { ICAL_CLASS_PROPERTY, ICAL_TEXT_VALUE }, - { ICAL_COMMENT_PROPERTY, ICAL_TEXT_VALUE }, - { ICAL_DESCRIPTION_PROPERTY, ICAL_TEXT_VALUE }, - { ICAL_LOCATION_PROPERTY, ICAL_TEXT_VALUE }, - { ICAL_PERCENTCOMPLETE_PROPERTY, ICAL_INTEGER_VALUE }, - { ICAL_PRIORITY_PROPERTY, ICAL_INTEGER_VALUE }, - { ICAL_RESOURCES_PROPERTY, ICAL_TEXT_VALUE }, - { ICAL_STATUS_PROPERTY, ICAL_STATUS_VALUE }, - { ICAL_SUMMARY_PROPERTY, ICAL_TEXT_VALUE }, - { ICAL_COMPLETED_PROPERTY, ICAL_DATETIME_VALUE }, - { ICAL_FREEBUSY_PROPERTY, ICAL_PERIOD_VALUE }, - { ICAL_TRANSP_PROPERTY, ICAL_TEXT_VALUE }, - { ICAL_TZNAME_PROPERTY, ICAL_TEXT_VALUE }, - { ICAL_TZOFFSETFROM_PROPERTY, ICAL_UTCOFFSET_VALUE }, - { ICAL_TZOFFSETTO_PROPERTY, ICAL_UTCOFFSET_VALUE }, - { ICAL_TZURL_PROPERTY, ICAL_URI_VALUE }, - { ICAL_TZID_PROPERTY, ICAL_TEXT_VALUE }, - { ICAL_ATTENDEE_PROPERTY, ICAL_CALADDRESS_VALUE }, - { ICAL_CONTACT_PROPERTY, ICAL_TEXT_VALUE }, - { ICAL_ORGANIZER_PROPERTY, ICAL_CALADDRESS_VALUE }, - { ICAL_RELATEDTO_PROPERTY, ICAL_TEXT_VALUE }, - { ICAL_URL_PROPERTY, ICAL_URI_VALUE }, - { ICAL_UID_PROPERTY, ICAL_TEXT_VALUE }, - { ICAL_EXRULE_PROPERTY, ICAL_RECUR_VALUE }, - { ICAL_RRULE_PROPERTY, ICAL_RECUR_VALUE }, - { ICAL_ACTION_PROPERTY, ICAL_TEXT_VALUE }, - { ICAL_REPEAT_PROPERTY, ICAL_INTEGER_VALUE }, - { ICAL_CREATED_PROPERTY, ICAL_DATETIME_VALUE }, - { ICAL_DTSTAMP_PROPERTY, ICAL_DATETIME_VALUE }, - { ICAL_LASTMODIFIED_PROPERTY, ICAL_DATETIME_VALUE }, - { ICAL_SEQUENCE_PROPERTY, ICAL_INTEGER_VALUE }, - { ICAL_X_PROPERTY, ICAL_TEXT_VALUE }, - { ICAL_REQUESTSTATUS_PROPERTY, ICAL_STRING_VALUE }, - { ICAL_ATTACH_PROPERTY, ICAL_URI_VALUE }, - { ICAL_GEO_PROPERTY, ICAL_GEO_VALUE }, - { ICAL_DTEND_PROPERTY, ICAL_DATETIME_VALUE }, - { ICAL_DUE_PROPERTY, ICAL_DATETIME_VALUE }, - { ICAL_DTSTART_PROPERTY, ICAL_DATETIME_VALUE }, - { ICAL_RECURRENCEID_PROPERTY, ICAL_DATETIME_VALUE }, - { ICAL_EXDATE_PROPERTY, ICAL_DATETIME_VALUE }, - { ICAL_RDATE_PROPERTY, ICAL_DATETIME_VALUE }, - { ICAL_TRIGGER_PROPERTY, ICAL_DURATION_VALUE }, - { ICAL_DURATION_PROPERTY, ICAL_DURATION_VALUE }, - - /* CAP properties */ - { ICAL_SCOPE_PROPERTY, ICAL_TEXT_VALUE }, - { ICAL_MAXRESULTS_PROPERTY, ICAL_INTEGER_VALUE}, - { ICAL_MAXRESULTSSIZE_PROPERTY, ICAL_INTEGER_VALUE}, - { ICAL_QUERY_PROPERTY, ICAL_QUERY_VALUE }, - { ICAL_QUERYNAME_PROPERTY, ICAL_TEXT_VALUE }, - { ICAL_TARGET_PROPERTY, ICAL_CALADDRESS_VALUE }, - - - /* libical private properties */ - { ICAL_XLICERROR_PROPERTY,ICAL_TEXT_VALUE}, - { ICAL_XLICCLUSTERCOUNT_PROPERTY,ICAL_INTEGER_VALUE}, - - - /* End of list */ - { ICAL_NO_PROPERTY, ICAL_NO_PROPERTY} -}; - - -icalvalue_kind icalenum_property_kind_to_value_kind(icalproperty_kind kind) -{ - int i; - - for (i=0; propval_map[i].value != ICAL_NO_VALUE; i++) { - if ( propval_map[i].prop == kind ) { - return propval_map[i].value; - } - } - - return ICAL_NO_VALUE; -} struct { @@ -535,97 +133,3 @@ icalrequeststatus icalenum_num_to_reqstat(short major, short minor) -struct {icalproperty_method method; const char* str;} method_map[] = { - {ICAL_METHOD_PUBLISH,"PUBLISH"}, - {ICAL_METHOD_REQUEST,"REQUEST"}, - {ICAL_METHOD_REPLY,"REPLY"}, - {ICAL_METHOD_ADD,"ADD"}, - {ICAL_METHOD_CANCEL,"CANCEL"}, - {ICAL_METHOD_REFRESH,"REFRESH"}, - {ICAL_METHOD_COUNTER,"COUNTER"}, - {ICAL_METHOD_DECLINECOUNTER,"DECLINECOUNTER"}, - /* CAP Methods */ - {ICAL_METHOD_CREATE,"CREATE"}, - {ICAL_METHOD_READ,"READ"}, - {ICAL_METHOD_RESPONSE,"RESPONSE"}, - {ICAL_METHOD_MOVE,"MOVE"}, - {ICAL_METHOD_MODIFY,"MODIFY"}, - {ICAL_METHOD_GENERATEUID,"GENERATEUID"}, - {ICAL_METHOD_DELETE,"DELETE"}, - {ICAL_METHOD_NONE,"NONE"} -}; - - -const char* icalenum_method_to_string(icalproperty_method method) -{ - int i; - - for (i=0; method_map[i].method != ICAL_METHOD_NONE; i++) { - if ( method_map[i].method == method) { - return method_map[i].str; - } - } - - return method_map[i].str; /* should be ICAL_METHOD_NONE */ -} - -icalproperty_method icalenum_string_to_method(const char* str) -{ - int i; - - while(*str == ' '){ - str++; - } - - - for (i=0; method_map[i].method != ICAL_METHOD_NONE; i++) { - if ( strcmp(method_map[i].str, str) == 0) { - return method_map[i].method; - } - } - - return ICAL_METHOD_NONE; -} - - -struct {icalproperty_status status; const char* str;} status_map[] = { - {ICAL_STATUS_TENTATIVE,"TENTATIVE"}, - {ICAL_STATUS_CONFIRMED,"CONFIRMED"}, - {ICAL_STATUS_NEEDSACTION,"NEEDS-ACTION"}, - {ICAL_STATUS_COMPLETED,"COMPLETED"}, - {ICAL_STATUS_INPROCESS,"IN-PROCESS"}, - {ICAL_STATUS_DRAFT,"DRAFT"}, - {ICAL_STATUS_FINAL,"FINAL"}, - {ICAL_STATUS_NONE,"NONE"} -}; - -const char* icalenum_status_to_string(icalproperty_status status) -{ - int i; - - for (i=0; status_map[i].status != ICAL_STATUS_NONE; i++) { - if ( status_map[i].status == status) { - return status_map[i].str; - } - } - - return status_map[i].str; /* should be ICAL_STATUS_NONE */ -} - -icalproperty_status icalenum_string_to_status(const char* str) -{ - int i; - - while(*str == ' '){ - str++; - } - - - for (i=0; status_map[i].status != ICAL_STATUS_NONE; i++) { - if ( strcmp(status_map[i].str, str) == 0) { - return status_map[i].status; - } - } - - return ICAL_STATUS_NONE; -} diff --git a/libical/src/libical/icalenums.h b/libical/src/libical/icalenums.h index d11547efad..21031dd20e 100644 --- a/libical/src/libical/icalenums.h +++ b/libical/src/libical/icalenums.h @@ -63,311 +63,6 @@ typedef enum icalcomponent_kind { } icalcomponent_kind; -/*********************************************************************** - * Property Enumerations -**********************************************************************/ - -typedef enum icalproperty_kind { - ICAL_ANY_PROPERTY = 0, /* This must be the first enum, for iteration */ - ICAL_CALSCALE_PROPERTY, - ICAL_METHOD_PROPERTY, - ICAL_PRODID_PROPERTY, - ICAL_VERSION_PROPERTY, - ICAL_ATTACH_PROPERTY, - ICAL_CATEGORIES_PROPERTY, - ICAL_CLASS_PROPERTY, - ICAL_COMMENT_PROPERTY, - ICAL_DESCRIPTION_PROPERTY, - ICAL_GEO_PROPERTY, - ICAL_LOCATION_PROPERTY, - ICAL_PERCENTCOMPLETE_PROPERTY, - ICAL_PRIORITY_PROPERTY, - ICAL_RESOURCES_PROPERTY, - ICAL_STATUS_PROPERTY, - ICAL_SUMMARY_PROPERTY, - ICAL_COMPLETED_PROPERTY, - ICAL_DTEND_PROPERTY, - ICAL_DUE_PROPERTY, - ICAL_DTSTART_PROPERTY, - ICAL_DURATION_PROPERTY, - ICAL_FREEBUSY_PROPERTY, - ICAL_TRANSP_PROPERTY, - ICAL_TZID_PROPERTY, - ICAL_TZNAME_PROPERTY, - ICAL_TZOFFSETFROM_PROPERTY, - ICAL_TZOFFSETTO_PROPERTY, - ICAL_TZURL_PROPERTY, - ICAL_ATTENDEE_PROPERTY, - ICAL_CONTACT_PROPERTY, - ICAL_ORGANIZER_PROPERTY, - ICAL_RECURRENCEID_PROPERTY, - ICAL_RELATEDTO_PROPERTY, - ICAL_URL_PROPERTY, - ICAL_UID_PROPERTY, - ICAL_EXDATE_PROPERTY, - ICAL_EXRULE_PROPERTY, - ICAL_RDATE_PROPERTY, - ICAL_RRULE_PROPERTY, - ICAL_ACTION_PROPERTY, - ICAL_REPEAT_PROPERTY, - ICAL_TRIGGER_PROPERTY, - ICAL_CREATED_PROPERTY, - ICAL_DTSTAMP_PROPERTY, - ICAL_LASTMODIFIED_PROPERTY, - ICAL_SEQUENCE_PROPERTY, - ICAL_REQUESTSTATUS_PROPERTY, - ICAL_X_PROPERTY, - - /* CAP Properties */ - ICAL_SCOPE_PROPERTY, - ICAL_MAXRESULTS_PROPERTY, - ICAL_MAXRESULTSSIZE_PROPERTY, - ICAL_QUERY_PROPERTY, - ICAL_QUERYNAME_PROPERTY, - ICAL_TARGET_PROPERTY, - - /* libical private properties */ - ICAL_XLICERROR_PROPERTY, - ICAL_XLICCLUSTERCOUNT_PROPERTY, - ICAL_XLICMIMECONTENTTYPE_PROPERTY, - ICAL_XLICMIMEENCODING_PROPERTY, - ICAL_XLICMIMECID_PROPERTY, - ICAL_XLICMIMEFILENAME_PROPERTY, - ICAL_XLICMIMECHARSET_PROPERTY, - ICAL_XLICMIMEOPTINFO_PROPERTY, - - ICAL_NO_PROPERTY /* This must be the last enum, for iteration */ - -} icalproperty_kind; - -/*********************************************************************** - * Enumerations for the values of properties - ***********************************************************************/ - -typedef enum icalproperty_method { - ICAL_METHOD_PUBLISH, - ICAL_METHOD_REQUEST, - ICAL_METHOD_REPLY, - ICAL_METHOD_ADD, - ICAL_METHOD_CANCEL, - ICAL_METHOD_REFRESH, - ICAL_METHOD_COUNTER, - ICAL_METHOD_DECLINECOUNTER, - /* CAP Methods */ - ICAL_METHOD_CREATE, - ICAL_METHOD_READ, - ICAL_METHOD_RESPONSE, - ICAL_METHOD_MOVE, - ICAL_METHOD_MODIFY, - ICAL_METHOD_GENERATEUID, - ICAL_METHOD_DELETE, - ICAL_METHOD_NONE -} icalproperty_method ; - -typedef enum icalproperty_transp { - ICAL_TRANSP_OPAQUE, - ICAL_TRANS_TRANSPARENT -} icalproperty_trans; - -typedef enum icalproperty_calscale { - ICAL_CALSCALE_GREGORIAN -} icalproperty_calscale ; - - -typedef enum icalproperty_class { - ICAL_CLASS_PUBLIC, - ICAL_CLASS_PRIVATE, - ICAL_CLASS_CONFIDENTIAL, - ICAL_CLASS_XNAME -} icalproperty_class; - - -typedef enum icalproperty_status { - ICAL_STATUS_NONE, - ICAL_STATUS_TENTATIVE, - ICAL_STATUS_CONFIRMED, - ICAL_STATUS_CANCELLED, /* CANCELED? SIC from RFC*/ - ICAL_STATUS_NEEDSACTION, - ICAL_STATUS_COMPLETED, - ICAL_STATUS_INPROCESS, - ICAL_STATUS_DRAFT, - ICAL_STATUS_FINAL -} icalproperty_status; - -typedef enum icalproperty_action { - ICAL_ACTION_AUDIO, - ICAL_ACTION_DISPLAY, - ICAL_ACTION_EMAIL, - ICAL_ACTION_PROCEDURE, - ICAL_ACTION_XNAME -} icalproperty_action; - -/*********************************************************************** - * Value enumerations -**********************************************************************/ - -typedef enum icalvalue_kind { - ICAL_NO_VALUE, - ICAL_ATTACH_VALUE, /* Non-Standard*/ - ICAL_BINARY_VALUE, - ICAL_BOOLEAN_VALUE, - ICAL_CALADDRESS_VALUE, - ICAL_DATE_VALUE, - ICAL_DATETIME_VALUE, - ICAL_DATETIMEDATE_VALUE, /* Non-Standard */ - ICAL_DATETIMEPERIOD_VALUE, /* Non-Standard */ - ICAL_DURATION_VALUE, - ICAL_FLOAT_VALUE, - ICAL_GEO_VALUE, /* Non-Standard */ - ICAL_INTEGER_VALUE, - ICAL_METHOD_VALUE, /* Non-Standard */ - ICAL_STATUS_VALUE, /* Non-Standard */ - ICAL_PERIOD_VALUE, - ICAL_RECUR_VALUE, - ICAL_STRING_VALUE, /* Non-Standard */ - ICAL_TEXT_VALUE, - ICAL_TIME_VALUE, - ICAL_TRIGGER_VALUE, /* Non-Standard */ - ICAL_URI_VALUE, - ICAL_UTCOFFSET_VALUE, - ICAL_QUERY_VALUE, - ICAL_XNAME_VALUE -} icalvalue_kind; - - -/*********************************************************************** - * Parameter Enumerations - **********************************************************************/ - - -typedef enum icalparameter_kind { - ICAL_NO_PARAMETER, - ICAL_ANY_PARAMETER, - ICAL_ALTREP_PARAMETER, /* DQUOTE uri DQUOTE */ - ICAL_CN_PARAMETER, /* text */ - ICAL_CUTYPE_PARAMETER, /*INDIVIDUAL, GROUP, RESOURCE,ROOM,UNKNOWN, x-name*/ - ICAL_DELEGATEDFROM_PARAMETER, /* *("," DQUOTE cal-address DQUOTE) */ - ICAL_DELEGATEDTO_PARAMETER, /* *("," DQUOTE cal-address DQUOTE) */ - ICAL_DIR_PARAMETER, /* DQUOTE uri DQUOTE */ - ICAL_ENCODING_PARAMETER, /* *BIT, BASE64, x-name */ - ICAL_FMTTYPE_PARAMETER, /* registered MINE content type */ - ICAL_FBTYPE_PARAMETER, /* FREE, BUSY, BUSY-UNAVAILABLE, BUSY-TENTATIVE,x-name */ - ICAL_LANGUAGE_PARAMETER, /* text from RFC 1766 */ - ICAL_MEMBER_PARAMETER, /* DQUOTE cal-address DQUOTE */ - ICAL_PARTSTAT_PARAMETER, /* NEEDS-ACTION, ACCEPTED, DECLINED, TENTATIVE, DELEGATED, x-name */ - ICAL_RANGE_PARAMETER, /* THISANDPRIOR, THISANDFUTURE */ - ICAL_RELATED_PARAMETER, /* START, END */ - ICAL_RELTYPE_PARAMETER, /* PARENT, CHILD, SIBLING,x-name */ - ICAL_ROLE_PARAMETER, /* CHAIR, REQ_PARTICIPANT, OPT_PARTICIPANT, NON_PARTICIPANT, x-name */ - ICAL_RSVP_PARAMETER, /* TRUE. FALSE */ - ICAL_SENTBY_PARAMETER, /* DQUOTE uri DQUOTE */ - ICAL_TZID_PARAMETER, /* [tzidprefix] paramtext CRLF */ - ICAL_VALUE_PARAMETER, /* BINARY, BOOLEAN, CAL_ADDRESS, DATE, DATE-TIME, DURATION, FLOAT, INTEGER, PERIOD, RECUR, TEXT, TIME, UTC_OFFSET, x-name */ - ICAL_XLICERRORTYPE_PARAMETER, /*ICAL_XLICERROR_PARSE_ERROR,ICAL_XLICERROR_INVALID_ITIP*/ - ICAL_XLICCOMPARETYPE_PARAMETER, /**/ - ICAL_X_PARAMETER /* text */ -} icalparameter_kind; - -typedef enum icalparameter_cutype { - ICAL_CUTYPE_INDIVIDUAL, - ICAL_CUTYPE_GROUP, - ICAL_CUTYPE_RESOURCE, - ICAL_CUTYPE_ROOM, - ICAL_CUTYPE_UNKNOWN, - ICAL_CUTYPE_XNAME -} icalparameter_cutype; - - -typedef enum icalparameter_encoding { - ICAL_ENCODING_8BIT, - ICAL_ENCODING_BASE64, - ICAL_ENCODING_XNAME -} icalparameter_encoding; - -typedef enum icalparameter_fbtype { - ICAL_FBTYPE_FREE, - ICAL_FBTYPE_BUSY, - ICAL_FBTYPE_BUSYUNAVAILABLE, - ICAL_FBTYPE_BUSYTENTATIVE, - ICAL_FBTYPE_XNAME -} icalparameter_fbtype; - -typedef enum icalparameter_partstat { - ICAL_PARTSTAT_NEEDSACTION, - ICAL_PARTSTAT_ACCEPTED, - ICAL_PARTSTAT_DECLINED, - ICAL_PARTSTAT_TENTATIVE, - ICAL_PARTSTAT_DELEGATED, - ICAL_PARTSTAT_COMPLETED, - ICAL_PARTSTAT_INPROCESS, - ICAL_PARTSTAT_XNAME, - ICAL_PARTSTAT_NONE -} icalparameter_partstat; - -typedef enum icalparameter_range { - ICAL_RANGE_THISANDPRIOR, - ICAL_RANGE_THISANDFUTURE -} icalparameter_range; - -typedef enum icalparameter_related { - ICAL_RELATED_START, - ICAL_RELATED_END -} icalparameter_related; - -typedef enum icalparameter_reltype { - ICAL_RELTYPE_PARENT, - ICAL_RELTYPE_CHILD, - ICAL_RELTYPE_SIBLING, - ICAL_RELTYPE_XNAME -} icalparameter_reltype; - -typedef enum icalparameter_role { - ICAL_ROLE_CHAIR, - ICAL_ROLE_REQPARTICIPANT, - ICAL_ROLE_OPTPARTICIPANT, - ICAL_ROLE_NONPARTICIPANT, - ICAL_ROLE_XNAME -} icalparameter_role; - -typedef enum icalparameter_xlicerrortype { - ICAL_XLICERRORTYPE_COMPONENTPARSEERROR, - ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR, - ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR, - ICAL_XLICERRORTYPE_PROPERTYPARSEERROR, - ICAL_XLICERRORTYPE_VALUEPARSEERROR, - ICAL_XLICERRORTYPE_UNKVCALPROP, - ICAL_XLICERRORTYPE_INVALIDITIP, - ICAL_XLICERRORTYPE_MIMEPARSEERROR -} icalparameter_xlicerrortype; - -typedef enum icalparameter_xliccomparetype { - ICAL_XLICCOMPARETYPE_EQUAL=0, - ICAL_XLICCOMPARETYPE_LESS=-1, - ICAL_XLICCOMPARETYPE_LESSEQUAL=2, - ICAL_XLICCOMPARETYPE_GREATER=1, - ICAL_XLICCOMPARETYPE_GREATEREQUAL=3, - ICAL_XLICCOMPARETYPE_NOTEQUAL=4, - ICAL_XLICCOMPARETYPE_REGEX=5 -} icalparameter_xliccomparetype; - -typedef enum icalparameter_value { - ICAL_VALUE_XNAME = ICAL_XNAME_VALUE, - ICAL_VALUE_BINARY = ICAL_BINARY_VALUE, - ICAL_VALUE_BOOLEAN = ICAL_BOOLEAN_VALUE, - ICAL_VALUE_CALADDRESS = ICAL_CALADDRESS_VALUE, - ICAL_VALUE_DATE = ICAL_DATE_VALUE, - ICAL_VALUE_DATETIME = ICAL_DATETIME_VALUE, - ICAL_VALUE_DURATION = ICAL_DURATION_VALUE, - ICAL_VALUE_FLOAT = ICAL_FLOAT_VALUE, - ICAL_VALUE_INTEGER = ICAL_INTEGER_VALUE, - ICAL_VALUE_PERIOD = ICAL_PERIOD_VALUE, - ICAL_VALUE_RECUR = ICAL_RECUR_VALUE, - ICAL_VALUE_TEXT = ICAL_TEXT_VALUE, - ICAL_VALUE_TIME = ICAL_TIME_VALUE, - ICAL_VALUE_UTCOFFSET = ICAL_UTCOFFSET_VALUE, - ICAL_VALUE_URI = ICAL_URI_VALUE, - ICAL_VALUE_ERROR = ICAL_NO_VALUE -} icalparameter_value; /*********************************************************************** @@ -420,27 +115,43 @@ icalrequeststatus icalenum_num_to_reqstat(short major, short minor); * Conversion functions **********************************************************************/ -const char* icalenum_property_kind_to_string(icalproperty_kind kind); -icalproperty_kind icalenum_string_to_property_kind(const char* string); -const char* icalenum_value_kind_to_string(icalvalue_kind kind); -icalvalue_kind icalenum_value_kind_by_prop(icalproperty_kind kind); +/* Thse routines used to be in icalenums.c, but were moved into the + icalproperty, icalparameter, icalvalue, or icalcomponent modules. */ -const char* icalenum_parameter_kind_to_string(icalparameter_kind kind); -icalparameter_kind icalenum_string_to_parameter_kind(const char* string); +/* const char* icalproperty_kind_to_string(icalproperty_kind kind);*/ +#define icalenum_property_kind_to_string(x) icalproperty_kind_to_string(x) -const char* icalenum_component_kind_to_string(icalcomponent_kind kind); -icalcomponent_kind icalenum_string_to_component_kind(const char* string); +/*icalproperty_kind icalproperty_string_to_kind(const char* string)*/ +#define icalenum_string_to_property_kind(x) icalproperty_string_to_kind(x) -icalvalue_kind icalenum_property_kind_to_value_kind(icalproperty_kind kind); +/*icalvalue_kind icalproperty_kind_to_value_kind(icalproperty_kind kind);*/ +#define icalenum_property_kind_to_value_kind(x) icalproperty_kind_to_value_kind(x) -const char* icalenum_method_to_string(icalproperty_method); -icalproperty_method icalenum_string_to_method(const char* string); +/*const char* icalenum_method_to_string(icalproperty_method);*/ +#define icalenum_method_to_string(x) icalproperty_method_to_string(x) -const char* icalenum_status_to_string(icalproperty_status); -icalproperty_status icalenum_string_to_status(const char* string); +/*icalproperty_method icalenum_string_to_method(const char* string);*/ +#define icalenum_string_to_method(x) icalproperty_string_to_method(x) -#endif /* !ICALENUMS_H */ +/*const char* icalenum_status_to_string(icalproperty_status);*/ +#define icalenum_status_to_string(x) icalproperty_status_to_string(x) + +/*icalproperty_status icalenum_string_to_status(const char* string);*/ +#define icalenum_string_to_status(x) icalproperty_string_to_status(x) +/*icalvalue_kind icalenum_string_to_value_kind(const char* str);*/ +#define icalenum_string_to_value_kind(x) icalvalue_string_to_kind(x) +/*const char* icalenum_value_kind_to_string(icalvalue_kind kind);*/ +#define icalenum_value_kind_to_string(x) icalvalue_kind_to_string(x) + +/*const char* icalenum_component_kind_to_string(icalcomponent_kind kind);*/ +#define icalenum_component_kind_to_string(x) icalcomponent_kind_to_string(x) + +/*icalcomponent_kind icalenum_string_to_component_kind(const char* string);*/ +#define icalenum_string_to_component_kind(x) icalcomponent_string_to_kind(x) + + +#endif /* !ICALENUMS_H */ diff --git a/libical/src/libical/icalerror.c b/libical/src/libical/icalerror.c index 13c39dadbc..05191defb9 100644 --- a/libical/src/libical/icalerror.c +++ b/libical/src/libical/icalerror.c @@ -59,7 +59,7 @@ int icalerror_errors_are_fatal = 1; int icalerror_errors_are_fatal = 0; #endif -struct icalerror_state { +struct icalerror_state { icalerrorenum error; icalerrorstate state; }; @@ -72,15 +72,82 @@ struct icalerror_state error_state_map[] = { ICAL_PARSE_ERROR,ICAL_ERROR_DEFAULT}, { ICAL_INTERNAL_ERROR,ICAL_ERROR_DEFAULT}, { ICAL_FILE_ERROR,ICAL_ERROR_DEFAULT}, - { ICAL_ALLOCATION_ERROR,ICAL_ERROR_DEFAULT}, { ICAL_USAGE_ERROR,ICAL_ERROR_DEFAULT}, - { ICAL_MULTIPLEINCLUSION_ERROR,ICAL_ERROR_DEFAULT}, - { ICAL_TIMEDOUT_ERROR,ICAL_ERROR_DEFAULT}, + { ICAL_UNIMPLEMENTED_ERROR,ICAL_ERROR_DEFAULT}, { ICAL_UNKNOWN_ERROR,ICAL_ERROR_DEFAULT}, { ICAL_NO_ERROR,ICAL_ERROR_DEFAULT} }; +struct icalerror_string_map { + const char* str; + icalerrorenum error; + char name[160]; +}; + +static struct icalerror_string_map string_map[] = +{ + {"BADARG",ICAL_BADARG_ERROR,"BADARG: Bad argument to function"}, + { "NEWFAILED",ICAL_NEWFAILED_ERROR,"NEWFAILED: Failed to create a new object via a *_new() routine"}, + {"MALFORMEDDATA",ICAL_MALFORMEDDATA_ERROR,"MALFORMEDDATA: An input string was not correctly formed or a component has missing or extra properties"}, + { "PARSE",ICAL_PARSE_ERROR,"PARSE: Failed to parse a part of an iCal component"}, + {"INTERNAL",ICAL_INTERNAL_ERROR,"INTERNAL: Random internal error. This indicates an error in the library code, not an error in use"}, + { "FILE",ICAL_FILE_ERROR,"FILE: An operation on a file failed. Check errno for more detail."}, + { "USAGE",ICAL_USAGE_ERROR,"USAGE: Failed to propertyl sequence calls to a set of interfaces"}, + { "UNIMPLEMENTED",ICAL_UNIMPLEMENTED_ERROR,"UNIMPLEMENTED: This feature has not been implemented"}, + { "NO",ICAL_NO_ERROR,"NO: No error"}, + {"UNKNOWN",ICAL_UNKNOWN_ERROR,"UNKNOWN: Unknown error type -- icalerror_strerror() was probably given bad input"} +}; + + +icalerrorenum icalerror_error_from_string(const char* str){ + + icalerrorenum e; + int i = 0; + + for( i = 0; string_map[i].error != ICAL_NO_ERROR; i++){ + if (strcmp(string_map[i].str,str) == 0){ + e = string_map[i].error; + } + } + + return e; +} + +icalerrorstate icalerror_supress(const char* error){ + + icalerrorenum e = icalerror_error_from_string(error); + icalerrorstate es; + + if (e == ICAL_NO_ERROR){ + return ICAL_ERROR_UNKNOWN; + } + + + es = icalerror_get_error_state(e); + icalerror_set_error_state(e,ICAL_ERROR_NONFATAL); + + return es; +} + +char* icalerror_perror() +{ + return icalerror_strerror(icalerrno); +} + +void icalerror_restore(const char* error, icalerrorstate es){ + + + icalerrorenum e = icalerror_error_from_string(error); + + if (e != ICAL_NO_ERROR){ + icalerror_set_error_state(e,es); + } + +} + + + void icalerror_set_error_state( icalerrorenum error, icalerrorstate state) { @@ -107,46 +174,6 @@ icalerrorstate icalerror_get_error_state( icalerrorenum error) } -void icalerror_set_errno(icalerrorenum e) { - - icalerrorstate es; - - icalerrno = e; - es = icalerror_get_error_state(e); - - icalerror_stop_here(); - - if( (es == ICAL_ERROR_FATAL) || - (es == ICAL_ERROR_DEFAULT && icalerror_errors_are_fatal == 1)){ - - fprintf(stderr,"libical: icalerrno_set_error: %s\n",icalerror_strerror(e)); -#ifdef NDEBUG - icalerror_crash_here(); -#else - assert(0); -#endif - } -} - - -struct icalerror_string_map { - icalerrorenum error; - char name[160]; -}; - -static struct icalerror_string_map string_map[] = -{ - {ICAL_BADARG_ERROR,"Bad argument to function"}, - {ICAL_NEWFAILED_ERROR,"Failed to create a new object via a *_new() routine"}, - {ICAL_MALFORMEDDATA_ERROR,"An input string was not correctly formed or a component has missing or extra properties"}, - {ICAL_PARSE_ERROR,"Failed to parse a part of an iCal component"}, - {ICAL_INTERNAL_ERROR,"Random internal error. This indicates an error in the library code, not an error in use"}, - {ICAL_FILE_ERROR,"An operation on a file failed. Check errno for more detail."}, - {ICAL_ALLOCATION_ERROR,"Failed to allocate memory"}, - {ICAL_USAGE_ERROR,"The caller failed to properly sequence called to an object's interface"}, - {ICAL_NO_ERROR,"No error"}, - {ICAL_UNKNOWN_ERROR,"Unknown error type -- icalerror_strerror() was probably given bad input"} -}; char* icalerror_strerror(icalerrorenum e) { diff --git a/libical/src/libical/icalerror.h b/libical/src/libical/icalerror.h index df71110ecb..790fa90f22 100644 --- a/libical/src/libical/icalerror.h +++ b/libical/src/libical/icalerror.h @@ -43,6 +43,64 @@ void icalerror_stop_here(void); void icalerror_crash_here(void); +typedef enum icalerrorenum { + + ICAL_BADARG_ERROR, + ICAL_NEWFAILED_ERROR, + ICAL_ALLOCATION_ERROR, + ICAL_MALFORMEDDATA_ERROR, + ICAL_PARSE_ERROR, + ICAL_INTERNAL_ERROR, /* Like assert --internal consist. prob */ + ICAL_FILE_ERROR, + ICAL_USAGE_ERROR, + ICAL_UNIMPLEMENTED_ERROR, + ICAL_UNKNOWN_ERROR, /* Used for problems in input to icalerror_strerror()*/ + ICAL_NO_ERROR + +} icalerrorenum; + +/* The libical error enumeration, like errno*/ +extern icalerrorenum icalerrno; + +/* If true, libicl aborts after a call to icalerror_set_error*/ +extern int icalerror_errors_are_fatal; + +/* Warning messages */ + +#ifdef __GNUC__ca +#define icalerror_warn(message) {fprintf(stderr,"%s(), %s:%d: %s\n",__FUNCTION__,__FILE__,__LINE__,message);} +#else /* __GNU_C__ */ +#define icalerror_warn(message) {fprintf(stderr,"%s:%d: %s\n",__FILE__,__LINE__,message);} +#endif /* __GNU_C__ */ + + +void icalerror_clear_errno(void); +void _icalerror_set_errno(icalerrorenum); + +/* Make an individual error fatal or non-fatal. */ +typedef enum icalerrorstate { + ICAL_ERROR_FATAL, /* Not fata */ + ICAL_ERROR_NONFATAL, /* Fatal */ + ICAL_ERROR_DEFAULT, /* Use the value of icalerror_errors_are_fatal*/ + ICAL_ERROR_UNKNOWN /* Asked state for an unknown error type */ +} icalerrorstate ; + +char* icalerror_strerror(icalerrorenum e); +char* icalerror_perror(); +void icalerror_set_error_state( icalerrorenum error, icalerrorstate); +icalerrorstate icalerror_get_error_state( icalerrorenum error); + + +#define icalerror_set_errno(x) \ +icalerrno = x; \ +if(icalerror_get_error_state(x)==ICAL_ERROR_FATAL || \ + (icalerror_get_error_state(x)==ICAL_ERROR_DEFAULT && \ + icalerror_errors_are_fatal == 1 )){ \ + icalerror_warn(icalerror_strerror(x)); \ + assert(0); \ +} + + #ifdef ICAL_ERRORS_ARE_FATAL #undef NDEBUG #endif @@ -60,82 +118,33 @@ void icalerror_crash_here(void); #else /*__GNUC__*/ #define icalerror_assert(test,message) if(!(test)){fprintf(stderr,"%s:%d: %s\n",__FILE__,__LINE__,message);icalerror_stop_here(); abort();} #endif /*__GNUC__*/ -#else + +#else /* ICAL_ERRORS_ARE_FATAL */ #define icalerror_assert(test,message) -#endif +#endif /* ICAL_ERRORS_ARE_FATAL */ /* Check & abort if check fails */ #define icalerror_check_arg(test,arg) if(!(test)) { icalerror_set_errno(ICAL_BADARG_ERROR); } /* Check & return void if check fails*/ -#define icalerror_check_arg_rv(test,arg) if(!(test)) { icalerror_set_errno(ICAL_BADARG_ERROR); return; } +#define icalerror_check_arg_rv(test,arg) if(!(test)) {icalerror_set_errno(ICAL_BADARG_ERROR); return; } /* Check & return 0 if check fails*/ -#define icalerror_check_arg_rz(test,arg) if(!(test)) {icalerror_set_errno(ICAL_BADARG_ERROR); return 0;} +#define icalerror_check_arg_rz(test,arg) if(!(test)) { icalerror_set_errno(ICAL_BADARG_ERROR); return 0;} /* Check & return an error if check fails*/ -#define icalerror_check_arg_re(test,arg,error) if(!(test)) {icalerror_stop_here(); return error;} +#define icalerror_check_arg_re(test,arg,error) if(!(test)) { icalerror_stop_here(); assert(0); return error;} +/* Check & return something*/ +#define icalerror_check_arg_rx(test,arg,x) if(!(test)) { icalerror_set_errno(ICAL_BADARG_ERROR); return x;} -/* Warning messages */ -#ifdef ICAL_ERRORS_ARE_FATAL +/* String interfaces to set an error to NONFATAL and restore it to its + original value */ -#ifdef __GNUC__ -#define icalerror_warn(message) {fprintf(stderr,"%s(), %s:%d: %s\n",__FUNCTION__,__FILE__,__LINE__,message); abort();} -#else /* __GNU_C__ */ -#define icalerror_warn(message) {fprintf(stderr,"%s:%d: %s\n",__FILE__,__LINE__,message); abort();} -#endif /* __GNU_C__ */ - -#else /*ICAL_ERRORS_ARE_FATAL */ - -#ifdef __GNUC__ -#define icalerror_warn(message) {fprintf(stderr,"%s(), %s:%d: %s\n",__FUNCTION__,__FILE__,__LINE__,message);} -#else /* __GNU_C__ */ -#define icalerror_warn(message) {fprintf(stderr,"%s:%d: %s\n",__FILE__,__LINE__,message);} -#endif /* __GNU_C__ */ - -#endif /*ICAL_ERRORS_ARE_FATAL*/ - -typedef enum icalerrorenum { - - ICAL_BADARG_ERROR, - ICAL_NEWFAILED_ERROR, - ICAL_MALFORMEDDATA_ERROR, - ICAL_PARSE_ERROR, - ICAL_INTERNAL_ERROR, /* Like assert --internal consist. prob */ - ICAL_FILE_ERROR, - ICAL_ALLOCATION_ERROR, - ICAL_USAGE_ERROR, - ICAL_NO_ERROR, - ICAL_MULTIPLEINCLUSION_ERROR, - ICAL_TIMEDOUT_ERROR, - ICAL_UNKNOWN_ERROR /* Used for problems in input to icalerror_strerror()*/ - -} icalerrorenum; - -/* The libical error enumeration, like errno*/ -extern icalerrorenum icalerrno; - -/* If true, libicl aborts after a call to icalerror_set_error*/ -extern int icalerror_errors_are_fatal; - -void icalerror_clear_errno(void); -void icalerror_set_errno(icalerrorenum); - -/* Make an individual error fatal or non-fatal. */ -typedef enum icalerrorstate { - ICAL_ERROR_FATAL, /* Not fata */ - ICAL_ERROR_NONFATAL, /* Fatal */ - ICAL_ERROR_DEFAULT, /* Use the value of icalerror_errors_are_fatal*/ - ICAL_ERROR_UNKNOWN /* Asked state for an unknown error type */ -} icalerrorstate ; - -void icalerror_set_error_state( icalerrorenum error, icalerrorstate); -icalerrorstate icalerror_get_error_state( icalerrorenum error); - -char* icalerror_strerror(icalerrorenum e); +icalerrorstate icalerror_supress(const char* error); +void icalerror_restore(const char* error, icalerrorstate es); #endif /* !ICALERROR_H */ diff --git a/libical/src/libical/icallangbind.c b/libical/src/libical/icallangbind.c index d52f491b93..866eb700cc 100644 --- a/libical/src/libical/icallangbind.c +++ b/libical/src/libical/icallangbind.c @@ -18,13 +18,15 @@ ======================================================================*/ -#include "ical.h" +#include "icalcomponent.h" +#include "icalproperty.h" +#include "icalerror.h" +#include "icalmemory.h" #include <malloc.h> - - +#include <string.h> int* icallangbind_new_array(int size){ - int* p = malloc(size*sizeof(int)); + int* p = (int*)malloc(size*sizeof(int)); return p; /* Caller handles failures */ } @@ -36,136 +38,235 @@ int icallangbind_access_array(int* array, int index) { return array[index]; } -/* Return the nth occurrence of 'prop' in c */ -icalproperty* icallangbind_get_property(icalcomponent *c, int n, const char* prop) -{ - int count; - icalproperty_kind kind; - icalproperty *p; - icalcomponent * comps[3]; - int compno = 0; - int propno = 0; - if(c == 0 || prop == 0 || n < 0){ - return 0; - } - kind = icalenum_string_to_property_kind(prop); +/* LIke icalcomponent_get_first_component, buut takes a string for the + kind and can iterate over X properties as if each X name was a + seperate kind */ +icalproperty* icallangbind_get_first_property(icalcomponent *c, + const char* prop) +{ + icalproperty_kind kind = icalproperty_string_to_kind(prop); + icalproperty *p; if (kind == ICAL_NO_PROPERTY){ return 0; } - comps[0] = c; - comps[1] = icalcomponent_get_first_real_component(c); - comps[2] = 0; - if(kind == ICAL_X_PROPERTY){ + for(p = icalcomponent_get_first_property(c,kind); + p !=0; + p = icalcomponent_get_next_property(c,kind)){ + + if(strcmp(icalproperty_get_x_name(p),prop) == 0){ + return p; + } + } + } else { + p=icalcomponent_get_first_property(c,kind); - for(compno ==0; comps[compno]!=0 ; compno++){ + return p; + } + + return 0; - for(p = icalcomponent_get_first_property(comps[compno],kind); - p !=0; - p = icalcomponent_get_next_property(comps[compno],kind) - ){ +} - if(strcmp(icalproperty_get_x_name(p),prop) == 0){ +icalproperty* icallangbind_get_next_property(icalcomponent *c, + const char* prop) +{ + icalproperty_kind kind = icalenum_string_to_property_kind(prop); + icalproperty *p; - if(propno == n ){ - return p; - } - - propno++; - } - } - } + if (kind == ICAL_NO_PROPERTY){ + return 0; + } + if(kind == ICAL_X_PROPERTY){ + for(p = icalcomponent_get_next_property(c,kind); + p !=0; + p = icalcomponent_get_next_property(c,kind)){ + + if(strcmp(icalproperty_get_x_name(p),prop) == 0){ + return p; + } + } } else { - for(compno ==0; comps[compno]!=0 ; compno++){ - - for(propno=0, - p = icalcomponent_get_first_property(comps[compno],kind); - propno != n && p !=0; - propno++, - p = icalcomponent_get_next_property(comps[compno],kind) - ) - { - } - - if(p != 0){ - return p; - } - - } + p=icalcomponent_get_next_property(c,kind); + + return p; } return 0; } -const char* icallangbind_get_property_val(icalproperty* p) + +icalcomponent* icallangbind_get_first_component(icalcomponent *c, + const char* comp) { - icalvalue *v; - if (p == 0){ + icalcomponent_kind kind = icalenum_string_to_component_kind(comp); + + if (kind == ICAL_NO_COMPONENT){ return 0; } + return icalcomponent_get_first_component(c,kind); +} - v = icalproperty_get_value(p); +icalcomponent* icallangbind_get_next_component(icalcomponent *c, + const char* comp) +{ + icalcomponent_kind kind = icalenum_string_to_component_kind(comp); - if(v == 0){ - return v; + if (kind == ICAL_NO_COMPONENT){ + return 0; } - - return icalvalue_as_ical_string(v); - + return icalcomponent_get_next_component(c,kind); } -const char* icallangbind_get_parameter(icalproperty *p, const char* parameter) + +#define APPENDS(x) icalmemory_append_string(&buf, &buf_ptr, &buf_size, x); + +#define APPENDC(x) icalmemory_append_char(&buf, &buf_ptr, &buf_size, x); + +const char* icallangbind_property_eval_string(icalproperty* prop, char* sep) { - icalparameter_kind kind; + char tmp[25]; + size_t buf_size = 1024; + char* buf = icalmemory_new_buffer(buf_size); + char* buf_ptr = buf; icalparameter *param; - - if(p == 0 || parameter == 0){ - return 0; - } - kind = icalenum_string_to_parameter_kind(parameter); + icalvalue* value; - if(kind == ICAL_NO_PARAMETER){ + if( prop == 0){ return 0; } - if(kind == ICAL_X_PARAMETER){ - for(param = icalproperty_get_first_parameter(p,ICAL_X_PARAMETER); - param != 0; - param = icalproperty_get_next_parameter(p,ICAL_X_PARAMETER)){ + APPENDS("{ "); - if(strcmp(icalparameter_get_xname(param),parameter) ==0){ - return icalparameter_as_ical_string(param); - } - } + value = icalproperty_get_value(prop); - } else { + APPENDS(" 'name' "); + APPENDS(sep); + APPENDC('\''); + APPENDS(icalenum_property_kind_to_string(icalproperty_isa(prop))); + APPENDC('\''); - param = icalproperty_get_first_parameter(p,kind); - - if (param !=0){ - return icalparameter_as_ical_string(param); - } + if(value){ + APPENDS(", 'value_type' "); + APPENDS(sep); + APPENDC('\''); + APPENDS(icalenum_value_kind_to_string(icalvalue_isa(value))); + APPENDC('\''); + } + + APPENDS(", 'pid' "); + APPENDS(sep); + APPENDC('\''); + snprintf(tmp,25,"%p",prop); + APPENDS(tmp); + APPENDC('\''); + + + if(value){ + switch (icalvalue_isa(value)){ + case ICAL_ATTACH_VALUE: + case ICAL_BINARY_VALUE: + case ICAL_NO_VALUE: { + icalerror_set_errno(ICAL_INTERNAL_ERROR); + break; + } + + default: + { + const char* str = icalvalue_as_ical_string(value); + char* copy = (char*) malloc(strlen(str)+1); + + const char *i; + char *j; + + if(copy ==0){ + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + break; + } + /* Remove any newlines */ + + for(j=copy, i = str; *i != 0; j++,i++){ + if(*i=='\n'){ + i++; + } + *j = *i; + } + + *j = 0; + + APPENDS(", 'value'"); + APPENDS(sep); + APPENDC('\''); + APPENDS(copy); + APPENDC('\''); + + free(copy); + break; + + } + } } - return 0; -} + /* Add Parameters */ -icalcomponent* icallangbind_get_component(icalcomponent *c, const char* comp) -{ - if(c == 0 || comp == 0){ - return 0; + for(param = icalproperty_get_first_parameter(prop,ICAL_ANY_PARAMETER); + param != 0; + param = icalproperty_get_next_parameter(prop,ICAL_ANY_PARAMETER)){ + + const char* str = icalparameter_as_ical_string(param); + char *copy = icalmemory_tmp_copy(str); + char *v; + + if(copy == 0){ + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + continue; + } + + v = strchr(copy,'='); + + + if(v == 0){ + continue; + } + + *v = 0; + + v++; + + APPENDS(", "); + APPENDC('\''); + APPENDS(copy); + APPENDC('\''); + APPENDS(sep); + APPENDC('\''); + APPENDS(v); + APPENDC('\''); + } -} + APPENDC('}'); + icalmemory_add_tmp_buffer(buf); + return buf; +} + +#include "fcntl.h" +int icallangbind_string_to_open_flag(const char* str) +{ + if (strcmp(str,"r") == 0) {return O_RDONLY;} + else if (strcmp(str,"r+") == 0) {return O_RDWR;} + else if (strcmp(str,"w") == 0) {return O_WRONLY;} + else if (strcmp(str,"a") == 0) {return O_WRONLY|O_APPEND;} + else return -1; +} diff --git a/libical/src/libical/icalmemory.h b/libical/src/libical/icalmemory.h index 3ae77024c4..52364e289f 100644 --- a/libical/src/libical/icalmemory.h +++ b/libical/src/libical/icalmemory.h @@ -5,7 +5,6 @@ $Id$ - $Locker$ This program is free software; you can redistribute it and/or modify @@ -71,7 +70,8 @@ void icalmemory_append_string(char** buf, char** pos, size_t* buf_size, void icalmemory_append_char(char** buf, char** pos, size_t* buf_size, char ch); -/* A wrapper around strdup */ +/* A wrapper around strdup. Partly to trap calls to strdup, partly + because in -ansi, gcc on Red Hat claims that strudup is undeclared */ char* icalmemory_strdup(const char *s); #endif /* !ICALMEMORY_H */ diff --git a/libical/src/libical/icalparser.c b/libical/src/libical/icalparser.c index 462fd164af..44a302431c 100644 --- a/libical/src/libical/icalparser.c +++ b/libical/src/libical/icalparser.c @@ -43,6 +43,7 @@ #include "icalmemory.h" #include "icalerror.h" #include "icalvalue.h" +#include "icalderivedparameter.h" #include "icalparameter.h" #include "icalproperty.h" #include "icalcomponent.h" @@ -66,17 +67,19 @@ char* icalparser_get_param_name(char* line, char **end); struct icalparser_impl { - int buffer_full; - size_t tmp_buf_size; - char temp[TMP_BUF_SIZE]; - icalcomponent *root_component; - int version; - int level; - int lineno; - icalparser_state state; - pvl_list components; - - void *line_gen_data; + int buffer_full; /* flag indicates that temp is smaller that + data being read into it*/ + int continuation_line; /* last line read was a continuation line */ + size_t tmp_buf_size; + char temp[TMP_BUF_SIZE]; + icalcomponent *root_component; + int version; + int level; + int lineno; + icalparser_state state; + pvl_list components; + + void *line_gen_data; }; @@ -410,9 +413,20 @@ char* icalparser_get_line(icalparser *parser, line_p = line = icalmemory_new_buffer(buf_size); line[0] = '\0'; + /* Read lines by calling line_gen_func and putting the data into + impl->temp. If the line is a continuation line ( begins with a + space after a newline ) then append the data onto line and read + again. Otherwise, exit the loop. */ + while(1) { - /* The buffer is not clear, so transfer the data in it to the + /* The first part of the loop deals with the temp buffer, + which was read on he last pass through the loop. The + routine is split like this because it has to read lone line + ahead to determine if a line is a continuation line. */ + + + /* The tmp buffer is not clear, so transfer the data in it to the output. This may be left over from a previous call */ if (impl->temp[0] != '\0' ) { @@ -420,19 +434,37 @@ char* icalparser_get_line(icalparser *parser, mark the buffer as full. The means we will do another read later, because the line is not finished */ if (impl->temp[impl->tmp_buf_size-1] == 0 && - impl->temp[impl->tmp_buf_size-2] != '\n'){ + impl->temp[impl->tmp_buf_size-2] != '\n'&& + impl->temp[impl->tmp_buf_size-2] != 0 ){ impl->buffer_full = 1; } else { impl->buffer_full = 0; } /* Copy the temp to the output and clear the temp buffer. */ - icalmemory_append_string(&line,&line_p,&buf_size,impl->temp); - impl->temp[0] = '\0' ; + if(impl->continuation_line==1){ + /* back up the pointer to erase the continuation characters */ + impl->continuation_line = 0; + line_p--; + + if ( *(line_p-1) == '\r'){ + line_p--; + } + + /* copy one space up to eliminate the leading space*/ + icalmemory_append_string(&line,&line_p,&buf_size, + impl->temp+1); + + } else { + icalmemory_append_string(&line,&line_p,&buf_size,impl->temp); + } + + impl->temp[0] = '\0' ; } impl->temp[impl->tmp_buf_size-1] = 1; /* Mark end of buffer */ + /****** Here is where the routine gets string data ******************/ if ((*line_gen_func)(impl->temp,impl->tmp_buf_size,impl->line_gen_data) ==0){/* Get more data */ @@ -459,17 +491,7 @@ char* icalparser_get_line(icalparser *parser, if ( line_p > line+1 && *(line_p-1) == '\n' && impl->temp[0] == ' ') { - /* back up the pointer to erase the continuation characters */ - line_p--; - - if ( *(line_p-1) == '\r'){ - line_p--; - } - - /* shift the temp buffer down to eliminate the leading space*/ - memmove(&(impl->temp[0]),&(impl->temp[1]),impl->tmp_buf_size); - - impl->temp[impl->tmp_buf_size-1] = impl->temp[impl->tmp_buf_size-2]; + impl->continuation_line = 1; } else if ( impl->buffer_full == 1 ) { @@ -507,7 +529,7 @@ void insert_error(icalcomponent* comp, char* text, if (text == 0){ snprintf(temp,1024,"%s:",message); } else { - snprintf(temp,1024,"%s: \'%s\'",message,text); + snprintf(temp,1024,"%s: %s",message,text); } icalcomponent_add_property @@ -518,6 +540,20 @@ void insert_error(icalcomponent* comp, char* text, 0)); } +int line_is_blank(char* line){ + int i=0; + + for(i=0; *(line+i)!=0; i++){ + char c = *(line+i); + + if(c != ' ' && c != '\n' && c != '\t'){ + return 0; + } + } + + return 1; +} + icalcomponent* icalparser_parse(icalparser *parser, char* (*line_gen_func)(char *s, size_t size, void* d)) @@ -527,11 +563,14 @@ icalcomponent* icalparser_parse(icalparser *parser, icalcomponent *c=0; icalcomponent *root=0; struct icalparser_impl *impl = (struct icalparser_impl*)parser; + icalerrorstate es = icalerror_get_error_state(ICAL_MALFORMEDDATA_ERROR); icalerror_check_arg_rz((parser !=0),"parser"); + icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,ICAL_ERROR_NONFATAL); + do{ - line = icalparser_get_line(parser, line_gen_func); + line = icalparser_get_line(parser, line_gen_func); if ((c = icalparser_add_line(parser,line)) != 0){ @@ -570,10 +609,13 @@ icalcomponent* icalparser_parse(icalparser *parser, } } while ( line != 0); + icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,es); + return root; } + icalcomponent* icalparser_add_line(icalparser* parser, char* line) { @@ -582,6 +624,7 @@ icalcomponent* icalparser_add_line(icalparser* parser, char *end; int vcount = 0; icalproperty *prop; + icalproperty_kind prop_kind; icalvalue *value; icalvalue_kind value_kind = ICAL_NO_VALUE; @@ -596,6 +639,10 @@ icalcomponent* icalparser_add_line(icalparser* parser, return 0; } + if(line_is_blank(line) == 1){ + return 0; + } + /* Begin by getting the property name at the start of the line. The property name may end up being "BEGIN" or "END" in which case it is not really a property, but the marker for the start or end of @@ -626,11 +673,21 @@ icalcomponent* icalparser_add_line(icalparser* parser, if(strcmp(str,"BEGIN") == 0){ icalcomponent *c; + icalcomponent_kind comp_kind; impl->level++; str = icalparser_get_next_value(end,&end, value_kind); - c = icalcomponent_new_from_string(str); + + comp_kind = icalenum_string_to_component_kind(str); + + if (comp_kind == ICAL_NO_COMPONENT){ + c = icalcomponent_new(ICAL_XLICINVALID_COMPONENT); + insert_error(c,str,"Parse error in component name", + ICAL_XLICERRORTYPE_COMPONENTPARSEERROR); + } + + c = icalcomponent_new(comp_kind); if (c == 0){ c = icalcomponent_new(ICAL_XLICINVALID_COMPONENT); @@ -696,23 +753,29 @@ icalcomponent* icalparser_add_line(icalparser* parser, /********************************************************************** * Handle property names - **********************************************************************/ + **********************************************************************/ + /* At this point, the property name really is a property name, (Not a component name) so make a new property and add it to the component */ - prop = icalproperty_new_from_string(str); + + prop_kind = icalproperty_string_to_kind(str); + + prop = icalproperty_new(prop_kind); if (prop != 0){ icalcomponent *tail = pvl_data(pvl_tail(impl->components)); + if(prop_kind==ICAL_X_PROPERTY){ + icalproperty_set_x_name(prop,str); + } + icalcomponent_add_property(tail, prop); /* Set the value kind for the default for this type of property. This may be re-set by a VALUE parameter */ - value_kind = - icalenum_property_kind_to_value_kind( - icalproperty_isa(prop)); + value_kind = icalproperty_kind_to_value_kind(icalproperty_isa(prop)); } else { icalcomponent* tail = pvl_data(pvl_tail(impl->components)); @@ -755,13 +818,13 @@ icalcomponent* icalparser_add_line(icalparser* parser, if (name == 0){ /* 'tail' defined above */ - insert_error(tail, str, "Can't parse parameter name", + insert_error(tail, str, "Cant parse parameter name", ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR); tail = 0; break; } - kind = icalenum_string_to_parameter_kind(name); + kind = icalparameter_string_to_kind(name); if(kind == ICAL_X_PARAMETER){ param = icalparameter_new(ICAL_X_PARAMETER); @@ -773,11 +836,11 @@ icalcomponent* icalparser_add_line(icalparser* parser, } else if (kind != ICAL_NO_PARAMETER){ - param = icalparameter_new_from_string(kind,pvalue); + param = icalparameter_new_from_value_string(kind,pvalue); } else { /* Error. Failed to parse the parameter*/ /* 'tail' defined above */ - insert_error(tail, str, "Can't parse parameter name", + insert_error(tail, str, "Cant parse parameter name", ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR); tail = 0; impl->state = ICALPARSER_ERROR; @@ -786,7 +849,7 @@ icalcomponent* icalparser_add_line(icalparser* parser, if (param == 0){ /* 'tail' defined above */ - insert_error(tail,str,"Can't parse parameter value", + insert_error(tail,str,"Cant parse parameter value", ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR); tail = 0; @@ -798,7 +861,9 @@ icalcomponent* icalparser_add_line(icalparser* parser, if (icalparameter_isa(param)==ICAL_VALUE_PARAMETER){ value_kind = (icalvalue_kind) - icalparameter_get_value(param); + icalparameter_value_to_value_kind( + icalparameter_get_value(param) + ); if (value_kind == ICAL_NO_VALUE){ @@ -813,7 +878,7 @@ icalcomponent* icalparser_add_line(icalparser* parser, icalparameter_free(param); value_kind = - icalenum_property_kind_to_value_kind( + icalproperty_kind_to_value_kind( icalproperty_isa(prop)); icalparameter_free(param); @@ -868,9 +933,9 @@ icalcomponent* icalparser_add_line(icalparser* parser, icalproperty_kind prop_kind = icalproperty_isa(prop); icalcomponent* tail = pvl_data(pvl_tail(impl->components)); - sprintf(temp,"Can't parse as %s value in %s property. Removing entire property", - icalenum_value_kind_to_string(value_kind), - icalenum_property_kind_to_string(prop_kind)); + sprintf(temp,"Cant parse as %s value in %s property. Removing entire property", + icalvalue_kind_to_string(value_kind), + icalproperty_kind_to_string(prop_kind)); insert_error(tail, str, temp, ICAL_XLICERRORTYPE_VALUEPARSEERROR); @@ -897,7 +962,7 @@ icalcomponent* icalparser_add_line(icalparser* parser, icalcomponent *tail = pvl_data(pvl_tail(impl->components)); sprintf(temp,"No value for %s property. Removing entire property", - icalenum_property_kind_to_string(prop_kind)); + icalproperty_kind_to_string(prop_kind)); insert_error(tail, str, temp, ICAL_XLICERRORTYPE_VALUEPARSEERROR); @@ -975,8 +1040,8 @@ icalcomponent* icalparser_clean(icalparser* parser) } struct slg_data { - char* pos; - char* str; + const char* pos; + const char* str; }; char* string_line_generator(char *out, size_t buf_size, void *d) @@ -1017,18 +1082,26 @@ char* string_line_generator(char *out, size_t buf_size, void *d) return out; } -icalcomponent* icalparser_parse_string(char* str) +icalcomponent* icalparser_parse_string(const char* str) { icalcomponent *c; struct slg_data d; icalparser *p; + icalerrorstate es = icalerror_get_error_state(ICAL_PARSE_ERROR); + d.pos = 0; d.str = str; p = icalparser_new(); icalparser_set_gen_data(p,&d); + + icalerror_set_error_state(ICAL_PARSE_ERROR,ICAL_ERROR_NONFATAL); + c = icalparser_parse(p,string_line_generator); + + icalerror_set_error_state(ICAL_PARSE_ERROR,es); + icalparser_free(p); return c; diff --git a/libical/src/libical/icalparser.h b/libical/src/libical/icalparser.h index efbe86eb21..5e1c88ffc0 100644 --- a/libical/src/libical/icalparser.h +++ b/libical/src/libical/icalparser.h @@ -74,7 +74,7 @@ icalcomponent* icalparser_parse(icalparser *parser, void icalparser_set_gen_data(icalparser* parser, void* data); -icalcomponent* icalparser_parse_string(char* str); +icalcomponent* icalparser_parse_string(const char* str); /*********************************************************************** diff --git a/libical/src/libical/icalrecur.c b/libical/src/libical/icalrecur.c index d5c73e80dd..51fdf63a79 100644 --- a/libical/src/libical/icalrecur.c +++ b/libical/src/libical/icalrecur.c @@ -99,26 +99,29 @@ larger time span than the interval. For instance, if INTERVAL=DAILY, BYMONTH is a contracting rule part. - Check_contracting_rules() uses check_restriction() to do its - work. Check_restriction() uses expand_map[] to determine if a rule + Check_contracting_rules() uses icalrecur_check_rulepart() to do its + work. icalrecur_check_rulepart() uses expand_map[] to determine if a rule is contracting, and if it is, and if the BY rule part has some data, then the routine checks if the value of a component of the time is part of the byrule part. For instance, for "INTERVAL=DAILY; - BYMONTH=6,10", check_restriction() would check that the time value + BYMONTH=6,10", icalrecur_check_rulepart() would check that the time value given to it has a month of either 6 or 10. - icalrecurrencetype_test() Finally, icalrecur_iterator_next() does a few other checks on the time value, and if it passes, it returns the time. - A note about the end_of_data flag. This flag is usually set early in - a next_* routine and returned in the end. The way it is used allows - the next_* routine to set the last time back to the first element in - a BYxx rule, and then signal to the higer level routine to increment - the next higher level. For instance. WITH FREQ=MONTHLY;BYDAY=TU,FR, - After next_weekday_by_month runs though both TU and FR, it sets the - week day back to TU and sets end_of_data. This signals next_month to - increment the month. + A note about the end_of_data flag. The flag indicates that the + routine is at the end of its data -- the last BY rule if the routine + is using by rules, or the last day of the week/month/year/etc if + not. + + This flag is usually set early in a next_* routine and returned in + the end. The way it is used allows the next_* routine to set the + last time back to the first element in a BYxx rule, and then signal + to the higer level routine to increment the next higher level. For + instance. WITH FREQ=MONTHLY;BYDAY=TU,FR, After next_weekday_by_month + runs though both TU and FR, it sets the week day back to TU and sets + end_of_data to 1x. This signals next_month to increment the month. ======================================================================*/ @@ -143,9 +146,31 @@ #include <assert.h> #include <stddef.h> /* For offsetof() macro */ +#include "pvl.h" + #define TEMP_MAX 1024 +#define BYDAYIDX impl->by_indices[BY_DAY] +#define BYDAYPTR impl->by_ptrs[BY_DAY] + +#define BYMONIDX impl->by_indices[BY_MONTH] +#define BYMONPTR impl->by_ptrs[BY_MONTH] + +#define BYMDIDX impl->by_indices[BY_MONTH_DAY] +#define BYMDPTR impl->by_ptrs[BY_MONTH_DAY] + +#define BYWEEKIDX impl->by_indices[BY_WEEK_NO] +#define BYWEEKPTR impl->by_ptrs[BY_WEEK_NO] + +const char* icalrecur_freq_to_string(icalrecurrencetype_frequency kind); +icalrecurrencetype_frequency icalrecur_string_to_freq(const char* str); + +const char* icalrecur_weekday_to_string(icalrecurrencetype_weekday kind); +icalrecurrencetype_weekday icalrecur_string_to_weekday(const char* str); + + + /*********************** Rule parsing routines ************************/ struct icalrecur_parser { @@ -250,10 +275,10 @@ void icalrecur_add_byrules(struct icalrecur_parser *parser, short *array, /* Get optional sign. HACK. sign is not allowed for all BYxxx rule parts */ if( *t == '-'){ - sign = 1; + sign = -1; t++; } else if (*t == '+'){ - sign = -1; + sign = 1; t++; } @@ -279,7 +304,7 @@ void icalrecur_add_bydayrules(struct icalrecur_parser *parser, const char* vals) char* end; char* vals_copy; - vals_copy = strdup(vals); + vals_copy = icalmemory_strdup(vals); end = (char*)vals_copy+strlen(vals_copy); n = vals_copy; @@ -343,7 +368,7 @@ struct icalrecurrencetype icalrecurrencetype_from_string(const char* str) /* Set up the parser struct */ parser.rule = str; - parser.copy = strdup(parser.rule); + parser.copy = icalmemory_strdup(parser.rule); parser.this_clause = parser.copy; if(parser.copy == 0){ @@ -366,7 +391,7 @@ struct icalrecurrencetype icalrecurrencetype_from_string(const char* str) } if (strcmp(name,"FREQ") == 0){ - parser.rt.freq = icalrecur_string_to_recurrence(value); + parser.rt.freq = icalrecur_string_to_freq(value); } else if (strcmp(name,"COUNT") == 0){ parser.rt.count = atoi(value); } else if (strcmp(name,"UNTIL") == 0){ @@ -451,7 +476,7 @@ char* icalrecurrencetype_as_string(struct icalrecurrencetype *recur) icalmemory_append_string(&str,&str_p,&buf_sz,"FREQ="); icalmemory_append_string(&str,&str_p,&buf_sz, - icalrecur_recurrence_to_string(recur->freq)); + icalrecur_freq_to_string(recur->freq)); if(recur->until.year != 0){ @@ -493,7 +518,7 @@ char* icalrecurrencetype_as_string(struct icalrecurrencetype *recur) pos = icalrecurrencetype_day_position(array[i]); - if (pos == 1) + if (pos == 0) icalmemory_append_string(&str,&str_p,&buf_sz,daystr); else { sprintf(temp,"%d%s",pos,daystr); @@ -538,20 +563,21 @@ enum byrule { struct icalrecur_iterator_impl { - struct icaltimetype dtstart; /* Hack. Make into time_t */ - struct icaltimetype last; /* last time return from _iterator_next*/ - int occurrence_no; /* number of step made on t iterator */ - struct icalrecurrencetype rule; - - short days[366]; - short days_index; - - enum byrule byrule; - short by_indices[9]; - short orig_data[9]; /* 1 if there was data in the byrule */ - - - short *by_ptrs[9]; /* Pointers into the by_* array elements of the rule */ + struct icaltimetype dtstart; /* Hack. Make into time_t */ + struct icaltimetype last; /* last time return from _iterator_next*/ + int occurrence_no; /* number of step made on t iterator */ + struct icalrecurrencetype rule; + + short days[366]; + short days_index; + + enum byrule byrule; + short by_indices[9]; + short orig_data[9]; /* 1 if there was data in the byrule */ + + + short *by_ptrs[9]; /* Pointers into the by_* array elements of the rule */ + }; int icalrecur_iterator_sizeof_byarray(short* byarray) @@ -689,20 +715,23 @@ void setup_defaults(struct icalrecur_iterator_impl* impl, } -int expand_year_days(struct icalrecur_iterator_impl* impl,short year); - int has_by_data(struct icalrecur_iterator_impl* impl, enum byrule byrule){ return (impl->orig_data[byrule] == 1); } +int expand_year_days(struct icalrecur_iterator_impl* impl,short year); + + icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, struct icaltimetype dtstart) { struct icalrecur_iterator_impl* impl; icalrecurrencetype_frequency freq; + short days_in_month; + if ( ( impl = (struct icalrecur_iterator_impl *) malloc(sizeof(struct icalrecur_iterator_impl))) == 0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); @@ -733,6 +762,11 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, memset(impl->orig_data,0,9); + /* Note which by rules had data in them when the iterator was + created. We can't use the actuall by_x arrays, because the + empty ones will be given default values later in this + routine. The orig_data array will be used later in has_by_data */ + impl->orig_data[BY_MONTH] = (impl->rule.by_month[0]!=ICAL_RECURRENCE_ARRAY_MAX); impl->orig_data[BY_WEEK_NO] @@ -762,7 +796,7 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, icalrecur_two_byrule(impl,BY_YEAR_DAY,BY_MONTH_DAY) || icalrecur_two_byrule(impl,BY_YEAR_DAY,BY_DAY) ){ - icalerror_set_errno(ICAL_USAGE_ERROR); + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return 0; } @@ -770,18 +804,18 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, /* BYWEEKNO and BYMONTH rule parts may not both appear.*/ if(icalrecur_two_byrule(impl,BY_WEEK_NO,BY_MONTH)){ - icalerror_set_errno(ICAL_USAGE_ERROR); + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); - icalerror_set_errno(ICAL_USAGE_ERROR); + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return 0; } /* BYWEEKNO and BYMONTHDAY rule parts may not both appear.*/ if(icalrecur_two_byrule(impl,BY_WEEK_NO,BY_MONTH_DAY)){ - icalerror_set_errno(ICAL_USAGE_ERROR); + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); - icalerror_set_errno(ICAL_USAGE_ERROR); + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return 0; } @@ -790,10 +824,8 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, BYWEEKNO may appear. */ if(freq == ICAL_MONTHLY_RECURRENCE && - ( icalrecur_one_byrule(impl,BY_WEEK_NO) || - icalrecur_one_byrule(impl,BY_YEAR_DAY)) ) { - - icalerror_set_errno(ICAL_USAGE_ERROR); + icalrecur_one_byrule(impl,BY_WEEK_NO)){ + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return 0; } @@ -802,13 +834,17 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, BYYEARDAY may appear. */ if(freq == ICAL_WEEKLY_RECURRENCE && - ( icalrecur_one_byrule(impl,BY_MONTH_DAY) || - icalrecur_one_byrule(impl,BY_YEAR_DAY)) ) { - - icalerror_set_errno(ICAL_USAGE_ERROR); + icalrecur_one_byrule(impl,BY_MONTH_DAY )) { + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return 0; } + /* BYYEARDAY may only appear in YEARLY rules */ + if(freq != ICAL_YEARLY_RECURRENCE && + icalrecur_one_byrule(impl,BY_YEAR_DAY )) { + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); + return 0; + } /* Rewrite some of the rules and set up defaults to make later processing easier. Primarily, t involves copying an element @@ -831,6 +867,7 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, setup_defaults(impl,BY_MONTH,ICAL_MONTHLY_RECURRENCE,impl->dtstart.month, &(impl->last.month)); + if(impl->rule.freq == ICAL_WEEKLY_RECURRENCE ){ if(impl->by_ptrs[BY_DAY][0] == ICAL_RECURRENCE_ARRAY_MAX){ @@ -841,7 +878,7 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, } else { /* If there is BY_DAY data, then we need to move the initial - time to the start of the BY_DAY data. That if if the + time to the start of the BY_DAY data. That is if the start time is on a Wednesday, and the rule has BYDAY=MO,WE,FR, move the initial time back to monday. Otherwise, jumping to the next week ( jumping 7 @@ -864,10 +901,11 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, } + /* For YEARLY rule, begin by setting up the year days array */ if(impl->rule.freq == ICAL_YEARLY_RECURRENCE){ - expand_year_days(impl,impl->dtstart.year); - } + expand_year_days(impl,impl->last.year); + } /* If this is a monthly interval with by day data, then we need to @@ -882,28 +920,49 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]]); short poscount = 0; - short days_in_month = - icaltime_days_in_month(impl->last.month, impl->last.year) ; + days_in_month = + icaltime_days_in_month(impl->last.month, impl->last.year); - for(impl->last.day = 1; - impl->last.day <= days_in_month; - impl->last.day++){ - - if(icaltime_day_of_week(impl->last) == dow){ - if(++poscount == pos){ - break; - } - } - } + if(pos >= 0){ + /* Count up from the first day pf the month to find the + pos'th weekday of dow ( like the second monday. ) */ + + for(impl->last.day = 1; + impl->last.day <= days_in_month; + impl->last.day++){ + + if(icaltime_day_of_week(impl->last) == dow){ + if(++poscount == pos || pos == 0){ + break; + } + } + } + } else { + /* Count down from the last day pf the month to find the + pos'th weekday of dow ( like the second to last monday. ) */ + pos = -pos; + for(impl->last.day = days_in_month; + impl->last.day != 0; + impl->last.day--){ + + if(icaltime_day_of_week(impl->last) == dow){ + if(++poscount == pos ){ + break; + } + } + } + } + - if(impl->last.day > days_in_month){ - icalerror_set_errno(ICAL_USAGE_ERROR); + if(impl->last.day > days_in_month || impl->last.day == 0){ + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return 0; } } + return impl; } @@ -921,34 +980,59 @@ void icalrecur_iterator_free(icalrecur_iterator* i) } - - void increment_year(struct icalrecur_iterator_impl* impl, int inc) { impl->last.year+=inc; } - - - -void increment_month(struct icalrecur_iterator_impl* impl, int inc) +/* Increment month is different that the other incement_* routines -- + it figures out the interval for itself, and uses BYMONTH data if + available. */ +void increment_month(struct icalrecur_iterator_impl* impl) { int years; - impl->last.month+=inc; - - /* Months are offset by one */ - impl->last.month--; - - years = impl->last.month / 12; - - impl->last.month = impl->last.month % 12; - - impl->last.month++; - - if (years != 0){ - increment_year(impl,years); - } + if(has_by_data(impl,BY_MONTH) ){ + /* Ignore the frequency and use the byrule data */ + + impl->by_indices[BY_MONTH]++; + + if (impl->by_ptrs[BY_MONTH][impl->by_indices[BY_MONTH]] + ==ICAL_RECURRENCE_ARRAY_MAX){ + impl->by_indices[BY_MONTH] = 0; + + increment_year(impl,1); + + } + + impl->last.month = + impl->by_ptrs[BY_MONTH][impl->by_indices[BY_MONTH]]; + + } else { + + int inc; + + if(impl->rule.freq == ICAL_MONTHLY_RECURRENCE){ + inc = impl->rule.interval; + } else { + inc = 1; + } + + impl->last.month+=inc; + + /* Months are offset by one */ + impl->last.month--; + + years = impl->last.month / 12; + + impl->last.month = impl->last.month % 12; + + impl->last.month++; + + if (years != 0){ + increment_year(impl,years); + } + } } void increment_monthday(struct icalrecur_iterator_impl* impl, int inc) @@ -964,7 +1048,7 @@ void increment_monthday(struct icalrecur_iterator_impl* impl, int inc) if (impl->last.day > days_in_month){ impl->last.day = impl->last.day-days_in_month; - increment_month(impl,1); + increment_month(impl); } } } @@ -1211,46 +1295,6 @@ int next_day(struct icalrecur_iterator_impl* impl) } -/* This routine is only called by next_month and next_year, so it does - not have a clause for this_frequency */ -int next_monthday(struct icalrecur_iterator_impl* impl) -{ - - short has_by_data = (impl->by_ptrs[BY_MONTH_DAY][0]!=ICAL_RECURRENCE_ARRAY_MAX); - short mday; - short end_of_data = 0; - - assert(has_by_data ); - - if (next_hour(impl) == 0){ - return 0; - } - - impl->by_indices[BY_MONTH_DAY]++; - - mday = impl->by_ptrs[BY_MONTH_DAY][impl->by_indices[BY_MONTH_DAY]]; - - if ( mday ==ICAL_RECURRENCE_ARRAY_MAX){ - impl->by_indices[BY_MONTH_DAY] = 0; - - end_of_data = 1; - } - - if (mday > 0){ - impl->last.day = mday; - } else { - short days_in_month = icaltime_days_in_month(impl->last.month, - impl->last.year); - impl->last.day = days_in_month-mday+1; - } - - if(has_by_data && end_of_data ){ - increment_month(impl,1); - } - - return end_of_data; - -} int next_yearday(struct icalrecur_iterator_impl* impl) { @@ -1336,143 +1380,185 @@ int next_weekday_by_week(struct icalrecur_iterator_impl* impl) } -int next_weekday_by_month(struct icalrecur_iterator_impl* impl) -{ +int nth_weekday(short dow, short pos, struct icaltimetype t){ - short end_of_data = 0; - struct icaltimetype start_of_month; /* Start of month */ - short pos, poscount, dow, days_in_month; + short days_in_month = icaltime_days_in_month(t.month,t.year); + short end_dow, start_dow; + short wd; - if (next_hour(impl) == 0){ - return 0; - } + if(pos >= 0){ + t.day = 1; + start_dow = icaltime_day_of_week(t); + + if (pos != 0) { + pos--; + } + + /* find month day of first occurrence of dow -- such as the + month day of the first monday */ - assert( impl->by_ptrs[BY_DAY][0]!=ICAL_RECURRENCE_ARRAY_MAX); + wd = dow-start_dow+1; - while(1) { - impl->by_indices[BY_DAY]++; /* Look at next elem in BYDAY array */ - - /* Are we at the end of the BYDAY array? */ - if (impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]] - ==ICAL_RECURRENCE_ARRAY_MAX){ - - impl->by_indices[BY_DAY] = 0; /* Reset to 0 */ - end_of_data = 1; /* Signal that we're at the end */ - } - - dow = icalrecurrencetype_day_day_of_week( - impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]]); - pos = icalrecurrencetype_day_position( - impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]]); + if (wd <= 0){ + wd = wd + 7; + } - start_of_month = impl->last; + wd = wd + pos * 7; + + } else { + t.day = days_in_month; + end_dow = icaltime_day_of_week(t); - /* Find right day in month. HACK. Find an arithmetic way to do - this */ + pos++; - poscount = 0; - days_in_month = - icaltime_days_in_month(impl->last.month, impl->last.year) ; + /* find month day of last occurrence of dow -- such as the + month day of the last monday */ - for(start_of_month.day = 1; - start_of_month.day <= days_in_month; - start_of_month.day++){ + wd = (end_dow - dow); - if(icaltime_day_of_week(start_of_month) == dow){ - if(++poscount == pos){ - break; - } - } - } + if (wd < 0){ + wd = wd+ 7; + } - if (!end_of_data == 1 && - ( - start_of_month.day > days_in_month || - icaltime_compare(start_of_month,impl->last) <= 0 - ) - ){ - continue; - } + wd = days_in_month - wd; - impl->last.day = start_of_month.day; - impl->last.month = start_of_month.month; - impl->last.year = start_of_month.year; - - return end_of_data; - } + wd = wd + pos * 7; + } + + return wd; } + int next_month(struct icalrecur_iterator_impl* impl) { + int data_valid = 1; + + short this_frequency = (impl->rule.freq == ICAL_MONTHLY_RECURRENCE); + + assert( has_by_data(impl,BY_MONTH) || this_frequency); + + /* Iterate through the occurrences within a day. If we don't get to + the end of the intra-day data, don't bother going to the next + month */ + + if (next_hour(impl) == 0){ + return data_valid; /* Signal that the data is valid */ + } + + + /* Now iterate through the occurrences within a month -- by days, + weeks or weekdays. */ + + if(has_by_data(impl,BY_DAY) && has_by_data(impl,BY_MONTH_DAY)){ + /* Cases like: FREQ=MONTHLY;INTERVAL=1;BYDAY=FR;BYMONTHDAY=13 */ + short day, idx,j; + short days_in_month = icaltime_days_in_month(impl->last.month, + impl->last.year); + /* Iterate through the remaining days in the month and check if + each day is listed in the BY_DAY array and in the BY_MONTHDAY + array. This seems very inneficient, but I think it is the + simplest way to account for both BYDAY=1FR (First friday in + month) and BYDAY=FR ( every friday in month ) */ + + for(day = impl->last.day+1; day <= days_in_month; day++){ + for(idx = 0; BYDAYPTR[idx] != ICAL_RECURRENCE_ARRAY_MAX; idx++){ + for(j = 0; BYMDPTR[j]!=ICAL_RECURRENCE_ARRAY_MAX; j++){ + short dow = + icalrecurrencetype_day_day_of_week(BYDAYPTR[idx]); + short pos = icalrecurrencetype_day_position(BYDAYPTR[idx]); + short mday = BYMDPTR[j]; + short this_dow; + + impl->last.day = day; + this_dow = icaltime_day_of_week(impl->last); + + if( (pos == 0 && dow == this_dow && mday == day) || + (nth_weekday(dow,pos,impl->last) == day && mday==day)){ + goto MDEND; + } + } + } + } - short this_frequency = (impl->rule.freq == ICAL_MONTHLY_RECURRENCE); - - short end_of_data = 0; + MDEND: - assert( has_by_data(impl,BY_MONTH) || this_frequency); + if ( day > days_in_month){ + impl->last.day = 1; + increment_month(impl); + data_valid = 0; /* signal that impl->last is invalid */ + } - /* Week day data overrides monthday data */ - if(has_by_data(impl,BY_DAY)){ + + } else if(has_by_data(impl,BY_DAY)){ + /* Cases like: FREQ=MONTHLY;INTERVAL=1;BYDAY=FR */ /* For this case, the weekdays are relative to the month. BYDAY=FR -> First Friday in month, etc. */ - if (next_weekday_by_month(impl) == 0){ - return 0; - } - } else { - if (next_monthday(impl) == 0){ - return 0; - } - } - - if(has_by_data(impl,BY_MONTH) ){ - /* Ignore the frequency and use the byrule data */ - - impl->by_indices[BY_MONTH]++; - - if (impl->by_ptrs[BY_MONTH][impl->by_indices[BY_MONTH]] - ==ICAL_RECURRENCE_ARRAY_MAX){ - impl->by_indices[BY_MONTH] = 0; - - end_of_data = 1; + short day, idx; + short days_in_month = icaltime_days_in_month(impl->last.month, + impl->last.year); + + assert( BYDAYPTR[0]!=ICAL_RECURRENCE_ARRAY_MAX); + + /* Iterate through the remaining days in the month and check if + each day is listed in the BY_DAY array. This seems very + inneficient, but I think it is the simplest way to account + for both BYDAY=1FR (First friday in month) and BYDAY=FR ( + every friday in month ) */ + + for(day = impl->last.day+1; day <= days_in_month; day++){ + for(idx = 0; BYDAYPTR[idx] != ICAL_RECURRENCE_ARRAY_MAX; idx++){ + short dow = icalrecurrencetype_day_day_of_week(BYDAYPTR[idx]); + short pos = icalrecurrencetype_day_position(BYDAYPTR[idx]); + short this_dow; + + impl->last.day = day; + this_dow = icaltime_day_of_week(impl->last); + + if( (pos == 0 && dow == this_dow ) || + (nth_weekday(dow,pos,impl->last) == day)){ + goto DEND; + } + } } - impl->last.month = - impl->by_ptrs[BY_MONTH][impl->by_indices[BY_MONTH]]; + DEND: - } else if( !has_by_data(impl,BY_MONTH) && this_frequency ){ - - if(has_by_data(impl,BY_DAY)){ - - short dayinc = 28; - - /* BY_DAY data specified a day of week, but incrementing the - month changes the day of the week -- Nov 2 is not the - same DOW as Oct 2. So, we need to fix the day of week by - incrementing in even weeks into the next month. . */ - - - if ( impl->last.day + dayinc - <= icaltime_days_in_month(impl->last.month, impl->last.year)){ - dayinc += 7; - } + if ( day > days_in_month){ + impl->last.day = 1; + increment_month(impl); + data_valid = 0; /* signal that impl->last is invalid */ + } - increment_monthday(impl,dayinc); + } else if (has_by_data(impl,BY_MONTH_DAY)) { + /* Cases like: FREQ=MONTHLY;COUNT=10;BYMONTHDAY=-3 */ + short day; - } else { + assert( BYMDPTR[0]!=ICAL_RECURRENCE_ARRAY_MAX); - /* Compute the next value from the last time and the - frequency interval*/ - increment_month(impl,impl->rule.interval); + BYMDIDX++; + + /* Are we at the end of the BYDAY array? */ + if (BYMDPTR[BYMDIDX] ==ICAL_RECURRENCE_ARRAY_MAX){ + + BYMDIDX = 0; /* Reset to 0 */ + increment_month(impl); } - - } - - - if(has_by_data(impl,BY_MONTH) && end_of_data && this_frequency ){ - increment_year(impl,1); + + day = BYMDPTR[BYMDIDX]; + + if (day < 0) { + day = icaltime_days_in_month(impl->last.month,impl->last.year)+ + day + 1; + } + + impl->last.day = day; + + } else { + increment_month(impl); } - return end_of_data; + + return data_valid; /* Signal that the data is valid */ } @@ -1484,11 +1570,16 @@ int next_week(struct icalrecur_iterator_impl* impl) short end_of_data = 0; + /* Increment to the next week day */ if (next_weekday_by_week(impl) == 0){ - return 0; + return 0; /* Have not reached end of week yet */ } - if( impl->by_ptrs[BY_WEEK_NO][0]!=ICAL_RECURRENCE_ARRAY_MAX){ + /* If we get here, we have incremented through the entire week, and + can increment to the next week */ + + + if( has_by_data){ /* Use the Week Number byrule data */ int week_no; struct icaltimetype t; @@ -1513,11 +1604,11 @@ int next_week(struct icalrecur_iterator_impl* impl) impl->last = icaltime_normalize(impl->last); } else if( !has_by_data && this_frequency ){ - - + /* If there is no BY_WEEK_NO data, just jump forward 7 days. */ increment_monthday(impl,7*impl->rule.interval); } + if(has_by_data && end_of_data && this_frequency ){ increment_year(impl,1); } @@ -1527,6 +1618,69 @@ int next_week(struct icalrecur_iterator_impl* impl) } +pvl_list expand_by_day(struct icalrecur_iterator_impl* impl,short year) +{ + /* Try to calculate each of the occurrences. */ + int i; + pvl_list days_list = pvl_newlist(); + + short start_dow, end_dow, end_year_day, start_doy; + struct icaltimetype tmp = impl->last; + + tmp.year= year; + tmp.month = 1; + tmp.day = 1; + tmp.is_date = 1; + + start_dow = icaltime_day_of_week(tmp); + start_doy = icaltime_start_doy_of_week(tmp); + + /* Get the last day of the year*/ + tmp.year++; + tmp = icaltime_normalize(tmp); + tmp.day--; + tmp = icaltime_normalize(tmp); + + end_dow = icaltime_day_of_week(tmp); + end_year_day = icaltime_day_of_year(tmp); + + for(i = 0; BYDAYPTR[i] != ICAL_RECURRENCE_ARRAY_MAX; i++){ + short dow = + icalrecurrencetype_day_day_of_week(BYDAYPTR[i]); + short pos = icalrecurrencetype_day_position(BYDAYPTR[i]); + + if(pos == 0){ + /* add all of the days of the year with this day-of-week*/ + int week; + for(week = 0; week < 52 ; week ++){ + short doy = start_doy + (week * 7) + dow-1; + + if(doy > end_year_day){ + break; + } else { + pvl_push(days_list,(void*)(int)doy); + } + } + + } else if ( pos > 0) { + int first; + /* First occurrence of dow in year */ + if( dow >= start_dow) { + first = dow - start_dow + 1; + } else { + first = dow - start_dow + 8; + } + + pvl_push(days_list,(void*)(first+ (pos-1) * 7)); + + } else { /* pos < 0 */ + assert(0); + } + } + + return days_list; +} + /* For INTERVAL=YEARLY, set up the days[] array in the iterator to list all of the days of the current year that are specified in this @@ -1537,15 +1691,31 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year) int j,k; int days_index=0; struct icaltimetype t; + int flags; +#define HBD(x) has_by_data(impl,x) t.is_date = 1; /* Needed to make day_of_year routines work property */ memset(&t,0,sizeof(t)); memset(impl->days,ICAL_RECURRENCE_ARRAY_MAX_BYTE,sizeof(impl->days)); - if(has_by_data(impl,BY_MONTH) && !has_by_data(impl,BY_MONTH_DAY) - && !has_by_data(impl,BY_DAY)){ + flags = (HBD(BY_DAY) ? 1<<BY_DAY : 0) + + (HBD(BY_WEEK_NO) ? 1<<BY_WEEK_NO : 0) + + (HBD(BY_MONTH_DAY) ? 1<<BY_MONTH_DAY : 0) + + (HBD(BY_MONTH) ? 1<<BY_MONTH : 0) + + (HBD(BY_YEAR_DAY) ? 1<<BY_YEAR_DAY : 0); + + + switch(flags) { + + case 0: { + /* FREQ=YEARLY; */ + + break; + } + case 1<<BY_MONTH: { + /* FREQ=YEARLY; BYMONTH=3,11*/ for(j=0;impl->by_ptrs[BY_MONTH][j]!=ICAL_RECURRENCE_ARRAY_MAX;j++){ struct icaltimetype t; @@ -1562,10 +1732,81 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year) impl->days[days_index++] = doy; } + break; + } + case 1<<BY_MONTH_DAY: { + /* FREQ=YEARLY; BYMONTHDAY=1,15*/ + assert(0); + break; + } + + case (1<<BY_MONTH_DAY) + (1<<BY_MONTH): { + /* FREQ=YEARLY; BYMONTHDAY=1,15; BYMONTH=10 */ + + for(j=0;impl->by_ptrs[BY_MONTH][j]!=ICAL_RECURRENCE_ARRAY_MAX;j++){ + for(k=0;impl->by_ptrs[BY_MONTH_DAY][k]!=ICAL_RECURRENCE_ARRAY_MAX;k++) + { + short month = impl->by_ptrs[BY_MONTH][j]; + short month_day = impl->by_ptrs[BY_MONTH_DAY][k]; + short doy; + + t.day = month_day; + t.month = month; + t.year = year; + t.is_date = 1; + + doy = icaltime_day_of_year(t); + + impl->days[days_index++] = doy; + + } + } + + break; + } + + case 1<<BY_WEEK_NO: { + /* FREQ=YEARLY; BYWEEKNO=20,50 */ + + struct icaltimetype t; + short dow; + + t.day = impl->dtstart.day; + t.month = impl->dtstart.month; + t.year = year; + t.is_date = 1; + + dow = icaltime_day_of_week(t); + /* HACK Not finished */ + + break; + } + case (1<<BY_WEEK_NO) + (1<<BY_MONTH_DAY): { + /*FREQ=YEARLY; WEEKNO=20,50; BYMONTH= 6,11 */ + assert(0); + break; } - else if ( has_by_data(impl,BY_MONTH) && has_by_data(impl,BY_DAY)){ + + case 1<<BY_DAY: { + /*FREQ=YEARLY; BYDAY=TH,20MO,-10FR*/ + int days_index = 0; + pvl_elem i; + pvl_list days = expand_by_day(impl,year); + + + for(i=pvl_head(days);i!=0;i=pvl_next(i)){ + short day = (short)(int)pvl_data(i); + impl->days[days_index++] = day; + } + + break; + } + + case (1<<BY_DAY)+(1<<BY_MONTH): { + /*FREQ=YEARLY; BYDAY=TH,20MO,-10FR; BYMONTH = 12*/ + for(j=0;impl->by_ptrs[BY_MONTH][j]!=ICAL_RECURRENCE_ARRAY_MAX;j++){ short month = impl->by_ptrs[BY_MONTH][j]; @@ -1596,58 +1837,90 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year) } } } - } else if (has_by_data(impl,BY_MONTH) && has_by_data(impl,BY_MONTH_DAY)){ + break; + } - for(j=0;impl->by_ptrs[BY_MONTH][j]!=ICAL_RECURRENCE_ARRAY_MAX;j++){ - for(k=0;impl->by_ptrs[BY_MONTH_DAY][k]!=ICAL_RECURRENCE_ARRAY_MAX;k++) - { - short month = impl->by_ptrs[BY_MONTH][j]; - short month_day = impl->by_ptrs[BY_MONTH_DAY][k]; - short doy; + case (1<<BY_DAY) + (1<<BY_MONTH_DAY) : { + /*FREQ=YEARLY; BYDAY=TH,20MO,-10FR; BYMONTHDAY=1,15*/ + assert(0); + break; + } - t.day = month_day; - t.month = month; - t.year = year; - t.is_date = 1; + case (1<<BY_DAY) + (1<<BY_MONTH_DAY) + (1<<BY_MONTH): { + /*FREQ=YEARLY; BYDAY=TH,20MO,-10FR; BYMONTHDAY=10; MYMONTH=6,11*/ + + int days_index = 0; + pvl_elem itr; + pvl_list days = expand_by_day(impl,year); + + for(itr=pvl_head(days);itr!=0;itr=pvl_next(itr)){ + short day = (short)(int)pvl_data(itr); + struct icaltimetype tt; + short i,j; + + tt = icaltime_from_day_of_year(day,year); + + for(i = 0; BYMONPTR[i] != ICAL_RECURRENCE_ARRAY_MAX; i++){ + for(j = 0; BYMDPTR[j]!=ICAL_RECURRENCE_ARRAY_MAX; j++){ + short mday = BYMDPTR[j]; + short month = BYMONPTR[i]; + + if(tt.month == month && tt.day == mday){ + impl->days[days_index++] = day; + } + } + } - doy = icaltime_day_of_year(t); + } - impl->days[days_index++] = doy; + break; + } + + case (1<<BY_DAY) + (1<<BY_WEEK_NO) : { + /*FREQ=YEARLY; BYDAY=TH,20MO,-10FR; WEEKNO=20,50*/ + + int days_index = 0; + pvl_elem itr; + pvl_list days = expand_by_day(impl,year); + + for(itr=pvl_head(days);itr!=0;itr=pvl_next(itr)){ + short day = (short)(int)pvl_data(itr); + struct icaltimetype tt; + short i; + + tt = icaltime_from_day_of_year(day,year); + + for(i = 0; BYWEEKPTR[i] != ICAL_RECURRENCE_ARRAY_MAX; i++){ + short weekno = BYWEEKPTR[i]; + + if(weekno== icaltime_week_number(tt)){ + impl->days[days_index++] = day; + } } + } - } else if (has_by_data(impl,BY_WEEK_NO) && !has_by_data(impl,BY_DAY)){ - - struct icaltimetype t; - short dow; - - t.day = impl->dtstart.day; - t.month = impl->dtstart.month; - t.year = year; - t.is_date = 1; + break; + } - dow = icaltime_day_of_week(t); - /* HACK Not finished */ - + case (1<<BY_DAY) + (1<<BY_WEEK_NO) + (1<<BY_MONTH_DAY): { + /*FREQ=YEARLY; BYDAY=TH,20MO,-10FR; WEEKNO=20,50; BYMONTHDAY=1,15*/ + assert(0); + break; + } - } else if (has_by_data(impl,BY_WEEK_NO) && has_by_data(impl,BY_DAY)){ - /* HACK Not finished */ - } else if (has_by_data(impl,BY_YEAR_DAY)){ - + case 1<<BY_YEAR_DAY: { for(j=0;impl->by_ptrs[BY_YEAR_DAY][j]!=ICAL_RECURRENCE_ARRAY_MAX;j++){ short doy = impl->by_ptrs[BY_YEAR_DAY][j]; impl->days[days_index++] = doy; - } - - } else if (has_by_data(impl,BY_MONTH_DAY) ){ - /* HACK Not finished */ - - } else if (has_by_data(impl,BY_DAY)){ - /* HACK Not finished */ + } + break; + } - } else { - assert(0); - /* HACK Not finished */ + default: { + assert(0); + break; + } } @@ -1658,17 +1931,15 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year) int next_year(struct icalrecur_iterator_impl* impl) { struct icaltimetype next; - short end_of_data=0; if (next_hour(impl) == 0){ return 0; } - impl->days_index++; - - if (impl->days[impl->days_index] == ICAL_RECURRENCE_ARRAY_MAX){ + if (impl->days[++impl->days_index] == ICAL_RECURRENCE_ARRAY_MAX){ impl->days_index = 0; - end_of_data = 1; + increment_year(impl,impl->rule.interval); + expand_year_days(impl,impl->last.year); } next = icaltime_from_day_of_year(impl->days[impl->days_index],impl->last.year); @@ -1676,16 +1947,26 @@ int next_year(struct icalrecur_iterator_impl* impl) impl->last.day = next.day; impl->last.month = next.month; - - if(end_of_data){ - increment_year(impl,impl->rule.interval); - expand_year_days(impl,impl->last.year); - } - return 1; } -int check_restriction(struct icalrecur_iterator_impl* impl, +int icalrecur_check_rulepart(struct icalrecur_iterator_impl* impl, + short v, enum byrule byrule) +{ + int itr; + + if(impl->by_ptrs[byrule][0]!=ICAL_RECURRENCE_ARRAY_MAX){ + for(itr=0; impl->by_ptrs[byrule][itr]!=ICAL_RECURRENCE_ARRAY_MAX;itr++){ + if(impl->by_ptrs[byrule][itr] == v){ + return 1; + } + } + } + + return 0; +} + +int check_contract_restriction(struct icalrecur_iterator_impl* impl, enum byrule byrule, short v) { int pass = 0; @@ -1709,6 +1990,7 @@ int check_restriction(struct icalrecur_iterator_impl* impl, } } + int check_contracting_rules(struct icalrecur_iterator_impl* impl) { @@ -1717,14 +1999,14 @@ int check_contracting_rules(struct icalrecur_iterator_impl* impl) int year_day=0; if ( - check_restriction(impl,BY_SECOND,impl->last.second) && - check_restriction(impl,BY_MINUTE,impl->last.minute) && - check_restriction(impl,BY_HOUR,impl->last.hour) && - check_restriction(impl,BY_DAY,day_of_week) && - check_restriction(impl,BY_WEEK_NO,week_no) && - check_restriction(impl,BY_MONTH_DAY,impl->last.day) && - check_restriction(impl,BY_MONTH,impl->last.month) && - check_restriction(impl,BY_YEAR_DAY,year_day) ) + check_contract_restriction(impl,BY_SECOND,impl->last.second) && + check_contract_restriction(impl,BY_MINUTE,impl->last.minute) && + check_contract_restriction(impl,BY_HOUR,impl->last.hour) && + check_contract_restriction(impl,BY_DAY,day_of_week) && + check_contract_restriction(impl,BY_WEEK_NO,week_no) && + check_contract_restriction(impl,BY_MONTH_DAY,impl->last.day) && + check_contract_restriction(impl,BY_MONTH,impl->last.month) && + check_contract_restriction(impl,BY_YEAR_DAY,year_day) ) { return 1; @@ -1735,6 +2017,7 @@ int check_contracting_rules(struct icalrecur_iterator_impl* impl) struct icaltimetype icalrecur_iterator_next(icalrecur_iterator *itr) { + int valid = 1; struct icalrecur_iterator_impl* impl = (struct icalrecur_iterator_impl*)itr; @@ -1752,6 +2035,7 @@ struct icaltimetype icalrecur_iterator_next(icalrecur_iterator *itr) } do { + valid = 1; switch(impl->rule.freq){ case ICAL_SECONDLY_RECURRENCE: { @@ -1775,7 +2059,7 @@ struct icaltimetype icalrecur_iterator_next(icalrecur_iterator *itr) break; } case ICAL_MONTHLY_RECURRENCE: { - next_month(impl); + valid = next_month(impl); break; } case ICAL_YEARLY_RECURRENCE:{ @@ -1783,17 +2067,19 @@ struct icaltimetype icalrecur_iterator_next(icalrecur_iterator *itr) break; } default:{ - assert(0); /* HACK, need a better error */ + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); + return icaltime_null_time(); } } - if(impl->last.year >= 2038){ + if(impl->last.year >= 2038 ){ /* HACK */ return icaltime_null_time(); } } while(!check_contracting_rules(impl) - || icaltime_compare(impl->last,impl->dtstart) < 0); + || icaltime_compare(impl->last,impl->dtstart) < 0 + || valid == 0); /* Ignore null times and times that are after the until time */ @@ -1830,6 +2116,9 @@ thursday of the year) These routines decode the day values. The day's position in the period ( Nth-ness) and the numerical value of the day are encoded together as: pos*7 + dow + +A position of 0 means 'any' or 'every' + */ enum icalrecurrencetype_weekday icalrecurrencetype_day_day_of_week(short day) @@ -1845,9 +2134,6 @@ short icalrecurrencetype_day_position(short day) pos = (abs(day)-wd)/8 * ((day<0)?-1:1); - if(pos == 0){ - pos = 1; - } return pos; } @@ -1909,7 +2195,7 @@ struct { {ICAL_NO_RECURRENCE,0} }; -const char* icalrecur_recurrence_to_string(icalrecurrencetype_frequency kind) +const char* icalrecur_freq_to_string(icalrecurrencetype_frequency kind) { int i; @@ -1921,7 +2207,7 @@ const char* icalrecur_recurrence_to_string(icalrecurrencetype_frequency kind) return 0; } -icalrecurrencetype_frequency icalrecur_string_to_recurrence(const char* str) +icalrecurrencetype_frequency icalrecur_string_to_freq(const char* str) { int i; @@ -1933,6 +2219,10 @@ icalrecurrencetype_frequency icalrecur_string_to_recurrence(const char* str) return ICAL_NO_RECURRENCE; } +/* Fill an array with the 'count' number of occurrences generated by + the rrule. Note that the times are returned in UTC, but the times + are calculated in local time. YOu will have to convert the results + back into local time before using them. */ int icalrecur_expand_recurrence(char* rule, time_t start, int count, time_t* array) @@ -1953,7 +2243,7 @@ int icalrecur_expand_recurrence(char* rule, time_t start, next = icalrecur_iterator_next(ritr); !icaltime_is_null_time(next) && i < count; next = icalrecur_iterator_next(ritr)){ - + tt = icaltime_as_timet(next); if (tt >= start ){ diff --git a/libical/src/libical/icaltime.c b/libical/src/libical/icaltime.c index b3c94229bf..37ae194bd0 100644 --- a/libical/src/libical/icaltime.c +++ b/libical/src/libical/icaltime.c @@ -73,75 +73,80 @@ icaltime_from_timet(time_t tm, int is_date) return tt; } -/* This will hold the last "TZ=XXX" string we used with putenv(). After we - call putenv() again to set a new TZ string, we can free the previous one. - As far as I know, no libc implementations actually free the memory used in - the environment variables (how could they know if it is a static string or - a malloc'ed string?), so we have to free it ourselves. */ -static char* saved_tz = NULL; +/* Structure used by set_tz to hold an old value of TZ, and the new + value, which is in memory we will have to free in unset_tz */ +struct set_tz_save {char* orig_tzid; char* new_env_str;}; - -/* If you use set_tz(), you must call unset_tz() some time later to restore the - original TZ. Pass unset_tz() the string that set_tz() returns. */ -char* set_tz(const char* tzid) +/* Temporarily change the TZ environmental variable. */ +struct set_tz_save set_tz(const char* tzid) { - char *old_tz, *old_tz_copy = NULL, *new_tz; - - /* Get the old TZ setting and save a copy of it to return. */ - old_tz = getenv("TZ"); - if(old_tz){ - old_tz_copy = (char*)malloc(strlen (old_tz) + 4); - if(old_tz_copy == 0){ - icalerror_set_errno(ICAL_NEWFAILED_ERROR); - return 0; - } + char *orig_tzid = 0; + char *new_env_str; + struct set_tz_save savetz; + size_t tmp_sz; - strcpy (old_tz_copy, "TZ="); - strcpy (old_tz_copy + 3, old_tz); - } + savetz.orig_tzid = 0; + savetz.new_env_str = 0; - /* Create the new TZ string. */ - new_tz = (char*)malloc(strlen (tzid) + 4); + if(getenv("TZ") != 0){ + orig_tzid = (char*)icalmemory_strdup(getenv("TZ")); - if(new_tz == 0){ - icalerror_set_errno(ICAL_NEWFAILED_ERROR); - return 0; + if(orig_tzid == 0){ + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return savetz; + } } - strcpy (new_tz, "TZ="); - strcpy (new_tz + 3, tzid); + tmp_sz =strlen(tzid)+4; + new_env_str = (char*)malloc(tmp_sz); - /* Add the new TZ to the environment. */ - putenv(new_tz); + if(new_env_str == 0){ + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return savetz; + } + + /* Copy the TZid into a string with the form that putenv expects. */ + strcpy(new_env_str,"TZ="); + strcpy(new_env_str+3,tzid); - /* Free any previous TZ environment string we have used. */ - if (saved_tz) - free (saved_tz); + putenv(new_env_str); - /* Save a pointer to the TZ string we just set, so we can free it later. */ - saved_tz = new_tz; + /* Old value of TZ and the string we will have to free later */ + savetz.orig_tzid = orig_tzid; + savetz.new_env_str = new_env_str; - return old_tz_copy; /* This will be zero if the TZ env var was not set */ + return savetz; } -void unset_tz(char *tzstr) +void unset_tz(struct set_tz_save savetz) { - /* restore the original environment */ + /* restore the original TZ environment */ + + char* orig_tzid = savetz.orig_tzid; - if(tzstr!=0){ - putenv(tzstr); + if(orig_tzid!=0){ + size_t tmp_sz =strlen(orig_tzid)+4; + char* orig_env_str = (char*)malloc(tmp_sz); + + if(orig_env_str == 0){ + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return; + } + + strcpy(orig_env_str,"TZ="); + strcpy(orig_env_str+3,orig_tzid); + + putenv(orig_env_str); + + free(orig_tzid); } else { putenv("TZ"); /* Delete from environment */ } - /* Free any previous TZ environment string we have used. */ - if (saved_tz) - free (saved_tz); - - /* Save a pointer to the TZ string we just set, so we can free it later. - (This can possibly be NULL if there was no TZ to restore.) */ - saved_tz = tzstr; + if(savetz.new_env_str != 0){ + free(savetz.new_env_str); + } } @@ -324,7 +329,7 @@ struct icaltimetype icaltime_from_string(const char* str) } } else if (size == 8) { /* A DATE */ - tt.is_utc = 0; + tt.is_utc = 1; tt.is_date = 1; } else { /* error */ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); @@ -352,8 +357,9 @@ struct icaltimetype icaltime_from_string(const char* str) char ctime_str[20]; char* icaltime_as_ctime(struct icaltimetype t) { - time_t tt = icaltime_as_timet(t); - + time_t tt; + + tt = icaltime_as_timet(t); sprintf(ctime_str,"%s",ctime(&tt)); ctime_str[strlen(ctime_str)-1] = 0; @@ -400,6 +406,7 @@ short icaltime_day_of_week(struct icaltimetype t){ return tm->tm_wday+1; } +/* Day of the year that the first day of the week (Sunday) is on */ short icaltime_start_doy_of_week(struct icaltimetype t){ time_t tt = icaltime_as_timet(t); time_t start_tt; @@ -431,6 +438,19 @@ short icaltime_start_doy_of_week(struct icaltimetype t){ } +short icaltime_week_number(struct icaltimetype ictt) +{ + char str[5]; + time_t t = icaltime_as_timet(ictt); + int week_no; + + strftime(str,5,"%V", gmtime(&t)); + + week_no = atoi(str); + + return week_no; + +} short icaltime_day_of_year(struct icaltimetype t){ @@ -452,6 +472,7 @@ struct icaltimetype icaltime_from_day_of_year(short doy, short year) { struct tm stm; time_t tt; + struct set_tz_save old_tz = set_tz("UTC"); /* Get the time of january 1 of this year*/ memset(&stm,0,sizeof(struct tm)); @@ -459,6 +480,8 @@ struct icaltimetype icaltime_from_day_of_year(short doy, short year) stm.tm_mday = 1; tt = mktime(&stm); + unset_tz(old_tz); + /* Now add in the days */ @@ -536,380 +559,10 @@ icaltime_compare_date_only (struct icaltimetype a, struct icaltimetype b) } } -struct icalperiodtype icalperiodtype_from_string (const char* str) -{ - - struct icalperiodtype p, null_p; - char *s = strdup(str); - char *start, *end = s; - int old_ieaf = icalerror_errors_are_fatal; - - p.start = p.end = icaltime_null_time(); - p.duration = icaldurationtype_from_int(0); - - null_p = p; - - if(s == 0) goto error; - - start = s; - end = strchr(s, '/'); - - if(end == 0) goto error; - - *end = 0; - end++; - - p.start = icaltime_from_string(start); - - if (icaltime_is_null_time(p.start)) goto error; - - icalerror_errors_are_fatal = 0; - p.end = icaltime_from_string(end); - icalerror_errors_are_fatal = old_ieaf; - - if (icaltime_is_null_time(p.end)){ - - p.duration = icaldurationtype_from_string(end); - - if(icaldurationtype_as_int(p.duration) == 0) goto error; - } - - return p; - - error: - icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); - return null_p; -} - - -const char* icalperiodtype_as_ical_string(struct icalperiodtype p) -{ - - const char* start; - const char* end; - - char *buf; - size_t buf_size = 40; - char* buf_ptr = 0; - - buf = (char*)icalmemory_new_buffer(buf_size); - buf_ptr = buf; - - - start = icaltime_as_ical_string(p.start); - - icalmemory_append_string(&buf, &buf_ptr, &buf_size, start); - - if(!icaltime_is_null_time(p.end)){ - end = icaltime_as_ical_string(p.end); - } else { - end = icaldurationtype_as_ical_string(p.duration); - } - - icalmemory_append_char(&buf, &buf_ptr, &buf_size, '/'); - - icalmemory_append_string(&buf, &buf_ptr, &buf_size, end); - - return buf; -} - - -time_t -icalperiodtype_duration (struct icalperiodtype period); - - -time_t -icalperiodtype_end (struct icalperiodtype period); - - -struct icalperiodtype icalperiodtype_null_period() { - struct icalperiodtype p; - p.start = icaltime_null_time(); - p.end = icaltime_null_time(); - p.duration = icaldurationtype_null_duration(); - - return p; -} -int icalperiodtype_is_null_period(struct icalperiodtype p){ - - if(icaltime_is_null_time(p.start) && - icaltime_is_null_time(p.end) && - icaldurationtype_is_null_duration(p.duration)){ - return 1; - } else { - return 0; - } -} - -int icalperiodtype_is_valid_period(struct icalperiodtype p){ - if(icaltime_is_valid_time(p.start) && - (icaltime_is_valid_time(p.end) || icaltime_is_null_time(p.end)) ) - { - return 1; - } - - return 0; -} - -/* From Russel Steinthal */ -int icaldurationtype_as_int(struct icaldurationtype dur) -{ - return (int)( (dur.seconds + - (60 * dur.minutes) + - (60 * 60 * dur.hours) + - (60 * 60 * 24 * dur.days) + - (60 * 60 * 24 * 7 * dur.weeks)) - * (dur.is_neg==1? -1 : 1) ) ; -} - -/* From Seth Alves, <alves@hungry.com> */ -struct icaldurationtype icaldurationtype_from_int(int t) -{ - struct icaldurationtype dur; - int used = 0; - - dur.weeks = (t - used) / (60 * 60 * 24 * 7); - used += dur.weeks * (60 * 60 * 24 * 7); - dur.days = (t - used) / (60 * 60 * 24); - used += dur.days * (60 * 60 * 24); - dur.hours = (t - used) / (60 * 60); - used += dur.hours * (60 * 60); - dur.minutes = (t - used) / (60); - used += dur.minutes * (60); - dur.seconds = (t - used); - - dur.is_neg = t<0? 1 : 0; - - return dur; -} - -#ifndef ICAL_NO_LIBICAL -#include "icalvalue.h" -struct icaldurationtype icaldurationtype_from_string(const char* str) -{ - - int i; - int begin_flag = 0; - int time_flag = 0; - int date_flag = 0; - int week_flag = 0; - int digits=-1; - int scan_size = -1; - int size = strlen(str); - char p; - struct icaldurationtype d; - - memset(&d, 0, sizeof(struct icaldurationtype)); - - for(i=0;i != size;i++){ - p = str[i]; - - switch(p) - { - case '-': { - if(i != 0 || begin_flag == 1) goto error; - - d.is_neg = 1; - break; - } - - case 'P': { - if (i != 0 && i !=1 ) goto error; - begin_flag = 1; - break; - } - - case 'T': { - time_flag = 1; - break; - } - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - - /* HACK. Skip any more digits if the l;ast one - read has not been assigned */ - if(digits != -1){ - break; - } - - if (begin_flag == 0) goto error; - /* Get all of the digits, not one at a time */ - scan_size = sscanf((char*)(str+i),"%d",&digits); - if(scan_size == 0) goto error; - break; - } - - case 'H': { - if (time_flag == 0||week_flag == 1||d.hours !=0||digits ==-1) - goto error; - d.hours = digits; digits = -1; - break; - } - case 'M': { - if (time_flag == 0||week_flag==1||d.minutes != 0||digits ==-1) - goto error; - d.minutes = digits; digits = -1; - break; - } - case 'S': { - if (time_flag == 0||week_flag==1||d.seconds!=0||digits ==-1) - goto error; - d.seconds = digits; digits = -1; - break; - } - case 'W': { - if (time_flag==1||date_flag==1||d.weeks!=0||digits ==-1) - goto error; - week_flag = 1; - d.weeks = digits; digits = -1; - break; - } - case 'D': { - if (time_flag==1||week_flag==1||d.days!=0||digits ==-1) - goto error; - date_flag = 1; - d.days = digits; digits = -1; - break; - } - default: { - goto error; - } - - } - } - - return d; - - - error: - icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); - memset(&d, 0, sizeof(struct icaldurationtype)); - return d; - -} - -#define TMP_BUF_SIZE 1024 -void append_duration_segment(char** buf, char** buf_ptr, size_t* buf_size, - char* sep, unsigned int value) { - - char temp[TMP_BUF_SIZE]; - - sprintf(temp,"%d",value); - - icalmemory_append_string(buf, buf_ptr, buf_size, temp); - icalmemory_append_string(buf, buf_ptr, buf_size, sep); - -} - -char* icaldurationtype_as_ical_string(struct icaldurationtype d) -{ - - char *buf, *output_line; - size_t buf_size = 256; - char* buf_ptr = 0; - int seconds; - - buf = (char*)icalmemory_new_buffer(buf_size); - buf_ptr = buf; - - - seconds = icaldurationtype_as_int(d); - - if(seconds !=0){ - - if(d.is_neg == 1){ - icalmemory_append_char(&buf, &buf_ptr, &buf_size, '-'); - } - - icalmemory_append_char(&buf, &buf_ptr, &buf_size, 'P'); - - if (d.weeks != 0 ) { - append_duration_segment(&buf, &buf_ptr, &buf_size, "W", d.weeks); - } - - if (d.days != 0 ) { - append_duration_segment(&buf, &buf_ptr, &buf_size, "D", d.days); - } - - if (d.hours != 0 || d.minutes != 0 || d.seconds != 0) { - - icalmemory_append_string(&buf, &buf_ptr, &buf_size, "T"); - - if (d.hours != 0 ) { - append_duration_segment(&buf, &buf_ptr, &buf_size, "H", d.hours); - } - if (d.minutes != 0 ) { - append_duration_segment(&buf, &buf_ptr, &buf_size, "M", - d.minutes); - } - if (d.seconds != 0 ) { - append_duration_segment(&buf, &buf_ptr, &buf_size, "S", - d.seconds); - } - - } - } else { - icalmemory_append_string(&buf, &buf_ptr, &buf_size, "PTS0"); - } - - output_line = icalmemory_tmp_copy(buf); - icalmemory_free_buffer(buf); - - return output_line; - -} - -#endif - -struct icaldurationtype icaldurationtype_null_duration() -{ - struct icaldurationtype d; - - memset(&d,0,sizeof(struct icaldurationtype)); - - return d; -} - -int icaldurationtype_is_null_duration(struct icaldurationtype d) -{ - if(icaldurationtype_as_int(d) == 0){ - return 1; - } else { - return 0; - } -} - +/* These are defined in icalduration.c: struct icaltimetype icaltime_add(struct icaltimetype t, struct icaldurationtype d) -{ - int dt = icaldurationtype_as_int(d); - - t.second += dt; - - t = icaltime_normalize(t); - - return t; -} - struct icaldurationtype icaltime_subtract(struct icaltimetype t1, struct icaltimetype t2) -{ - - time_t t1t = icaltime_as_timet(t1); - time_t t2t = icaltime_as_timet(t2); - - return icaldurationtype_from_int(t1t-t2t); - - -} +*/ diff --git a/libical/src/libical/icaltime.h b/libical/src/libical/icaltime.h index 165b88d943..0f0379b76e 100644 --- a/libical/src/libical/icaltime.h +++ b/libical/src/libical/icaltime.h @@ -38,6 +38,7 @@ struct icaltime_span { int is_busy; /* 1->busy time, 0-> free time */ }; + struct icaltimetype { int year; @@ -56,12 +57,19 @@ struct icaltimetype /* Convert seconds past UNIX epoch to a timetype*/ struct icaltimetype icaltime_from_timet(time_t v, int is_date); + +/* Return the time as seconds past the UNIX epoch */ time_t icaltime_as_timet(struct icaltimetype); + +/* Return a string represention of the time, in RFC2445 format. The + string is owned by libical */ char* icaltime_as_ical_string(struct icaltimetype tt); /* Like icaltime_from_timet(), except that the input may be in seconds - past the epoch in floating time */ + past the epoch in floating time. This routine is deprecated */ struct icaltimetype icaltime_from_int(int v, int is_date, int is_utc); + +/* Like icaltime_as_timet, but in a floating epoch. This routine is deprecated */ int icaltime_as_int(struct icaltimetype); /* create a time from an ISO format string */ @@ -81,76 +89,56 @@ struct icaltimetype icaltime_as_utc(struct icaltimetype tt, struct icaltimetype icaltime_as_zone(struct icaltimetype tt, const char* tzid); - +/* Return a null time, which indicates no time has been set. This time represent the beginning of the epoch */ struct icaltimetype icaltime_null_time(void); +/* Return true of the time is null. */ int icaltime_is_null_time(struct icaltimetype t); + +/* Returns false if the time is clearly invalid, but is not null. This + is usually the result of creating a new time type buy not clearing + it, or setting one of the flags to an illegal value. */ int icaltime_is_valid_time(struct icaltimetype t); +/* Reset all of the time components to be in their normal ranges. For + instance, given a time with minutes=70, the minutes will be reduces + to 10, and the hour incremented. This allows the caller to do + arithmetic on times without worrying about overflow or + underflow. */ struct icaltimetype icaltime_normalize(struct icaltimetype t); +/* Return the day of the year of the given time */ short icaltime_day_of_year(struct icaltimetype t); + +/* Create a new time, given a day of year and a year. */ struct icaltimetype icaltime_from_day_of_year(short doy, short year); +/* Return the day of the week of the given time. Sunday is 1 */ short icaltime_day_of_week(struct icaltimetype t); + +/* Return the day of the year for the Sunday of the week that the + given time is within. */ short icaltime_start_doy_of_week(struct icaltimetype t); +/* Return a string with the time represented in the same format as ctime(). THe string is owned by libical */ char* icaltime_as_ctime(struct icaltimetype); -short icaltime_week_number(short day_of_month, short month, short year); +/* Return the week number for the week the given time is within */ +short icaltime_week_number(struct icaltimetype t); +/* Create a new time from a weeknumber and a year. */ struct icaltimetype icaltime_from_week_number(short week_number, short year); +/* Return -1, 0, or 1 to indicate that a<b, a==b or a>b */ int icaltime_compare(struct icaltimetype a,struct icaltimetype b); +/* like icaltime_compare, but only use the date parts. */ int icaltime_compare_date_only(struct icaltimetype a, struct icaltimetype b); - +/* Return the number of days in the given month */ short icaltime_days_in_month(short month,short year); -struct icaldurationtype -{ - int is_neg; - unsigned int days; - unsigned int weeks; - unsigned int hours; - unsigned int minutes; - unsigned int seconds; -}; - -struct icaldurationtype icaldurationtype_from_int(int t); -struct icaldurationtype icaldurationtype_from_string(const char*); -int icaldurationtype_as_int(struct icaldurationtype duration); -char* icaldurationtype_as_ical_string(struct icaldurationtype d); -struct icaldurationtype icaldurationtype_null_duration(); -int icaldurationtype_is_null_duration(struct icaldurationtype d); - -struct icalperiodtype -{ - struct icaltimetype start; /* Must be absolute */ - struct icaltimetype end; /* Must be absolute */ - struct icaldurationtype duration; -}; - -struct icalperiodtype icalperiodtype_from_string (const char* str); -const char* icalperiodtype_as_ical_string(struct icalperiodtype p); -struct icalperiodtype icalperiodtype_null_period(); -int icalperiodtype_is_null_period(struct icalperiodtype p); -int icalperiodtype_is_valid_period(struct icalperiodtype p); - -time_t icalperiodtype_duration(struct icalperiodtype period); -time_t icalperiodtype_end(struct icalperiodtype period); - - - -struct icaltimetype icaltime_add(struct icaltimetype t, - struct icaldurationtype d); - -struct icaldurationtype icaltime_subtract(struct icaltimetype t1, - struct icaltimetype t2); - - #endif /* !ICALTIME_H */ diff --git a/libical/src/libical/icaltypes.h b/libical/src/libical/icaltypes.h index 7c0d2dd617..04e04c9dc3 100644 --- a/libical/src/libical/icaltypes.h +++ b/libical/src/libical/icaltypes.h @@ -25,8 +25,11 @@ #define ICALTYPES_H #include <time.h> -#include "icalenums.h" /* for recurrence enums */ +#include "icalenums.h" #include "icaltime.h" +#include "icalduration.h" +#include "icalperiod.h" + /* This type type should probably be an opaque type... */ struct icalattachtype @@ -104,4 +107,30 @@ struct icalreqstattype { struct icalreqstattype icalreqstattype_from_string(char* str); char* icalreqstattype_as_string(struct icalreqstattype); + + +struct icaltimezonephase { + const char* tzname; + int is_stdandard; /* 1 = standard tme, 0 = daylight savings time */ + struct icaltimetype dtstart; + int offsetto; + int tzoffsetfrom; + const char* comment; + struct icaldatetimeperiodtype rdate; + const char* rrule; +}; + + +struct icaltimezonetype { + const char* tzid; + struct icaltimetype last_mod; + const char* tzurl; + + /* Array of phases. The end of the array is a phase with tzname == 0 */ + struct icaltimezonephase *phases; +}; + +void icaltimezonetype_free(struct icaltimezonetype tzt); + + #endif /* !ICALTYPES_H */ diff --git a/libical/src/libicalss/Makefile.am b/libical/src/libicalss/Makefile.am index 732d970738..28a3adc6ee 100644 --- a/libical/src/libicalss/Makefile.am +++ b/libical/src/libicalss/Makefile.am @@ -7,11 +7,10 @@ LEX_OUTPUT_ROOT = lex.ss all: icalss.h INCLUDES = \ - -I$(top_builddir) \ -I$(top_srcdir)/src \ -I$(top_builddir)/src \ -I$(top_srcdir)/src/libical \ - -I$(srcdir)/libical + -I$(top_builddir)/src/libical libicalss_la_LDFLAGS = -version-info 0:0:0 @@ -25,11 +24,14 @@ libicalss_la_SOURCES = \ icalfilesetimpl.h \ icalset.c \ icalsslexer.l \ - icalssutil.c \ icalssyacc.h \ icalssyacc.y \ icalspanlist.c \ icalmessage.c \ + icalcstpclient.c \ + icalcstpclient.h \ + icalcstpserver.c \ + icalcstpserver.h \ icalcstp.c libicalssincludedir = $(includedir) @@ -40,11 +42,13 @@ COMBINEDHEADERS = \ icalfileset.h \ icaldirset.h \ icalcalendar.h \ - icalssutil.h \ icalclassify.h \ icalspanlist.h \ icalmessage.h \ - icalcstp.h + icalcstp.h \ + icalcstpclient.h \ + icalcstpserver.h + icalss.h: $(COMBINEDHEADERS) cat $(COMBINEDHEADERS) | egrep -v "#include.*\"ical" \ diff --git a/libical/src/libicalss/icalcstp.h b/libical/src/libicalss/icalcstp.h index 2ebccd622a..dfc361830e 100644 --- a/libical/src/libicalss/icalcstp.h +++ b/libical/src/libicalss/icalcstp.h @@ -30,134 +30,48 @@ #include "ical.h" -/********************** Server (Reciever) Interfaces *************************/ - -/* On the server side, the caller will recieve data from the incoming - socket and pass it to icalcstps_next_input. The caller then takes - the return from icalcstps_next_outpu and sends it out through the - socket. This gives the caller a point of control. If the cstp code - connected to the socket itself, it would be hard for the caller to - do anything else after the cstp code was started. - - All of the server abd client command routines will generate - response codes. On the server side, these responses will be turned - into text and sent to the client. On the client side, the reponse - is the one sent from the server. - - Since each command can return multiple responses, the responses are - stored in the icalcstps object and are accesses by - icalcstps_first_response() and icalcstps_next_response() - - How to use: - - 1) Construct a new icalcstps, bound to your code via stubs - 2) Repeat forever: - 2a) Get string from client & give to icalcstps_next_input() - 2b) Repeat until icalcstp_next_output returns 0: - 2b1) Call icalcstps_next_output. - 2b2) Send string to client. -*/ - - - -typedef void icalcstps; - -/* Er, they aren't really stubs, but pointers to the rountines that - icalcstps_process_incoming will call when it recognizes a CSTP - command in the data. BTW, the CONTINUE command is named 'cont' - because 'continue' is a C keyword */ -struct icalcstps_stubs { - icalerrorenum (*abort)(icalcstps* cstp); - icalerrorenum (*authenticate)(icalcstps* cstp, char* mechanism, - char* data); - icalerrorenum (*calidexpand)(icalcstps* cstp, char* calid); - icalerrorenum (*capability)(icalcstps* cstp); - icalerrorenum (*cont)(icalcstps* cstp, unsigned int time); - icalerrorenum (*identify)(icalcstps* cstp, char* id); - icalerrorenum (*disconnect)(icalcstps* cstp); - icalerrorenum (*sendata)(icalcstps* cstp, unsigned int time, - icalcomponent *comp); - icalerrorenum (*starttls)(icalcstps* cstp, char* command, - char* data); - icalerrorenum (*upnexpand)(icalcstps* cstp, char* upn); - icalerrorenum (*unknown)(icalcstps* cstp, char* command, char* data); +/* Connection state, from the state machine in RFC2445 */ +enum cstps_state { + NO_STATE, + CONNECTED, + AUTHENTICATED, + IDENTIFIED, + DISCONNECTED, + RECEIVE }; +/* CSTP Commands that a client can issue to a server */ +typedef enum icalcstp_command { + ICAL_ABORT_COMMAND, + ICAL_AUTHENTICATE_COMMAND, + ICAL_CAPABILITY_COMMAND, + ICAL_CONTINUE_COMMAND, + ICAL_CALIDEXPAND_COMMAND, + ICAL_IDENTIFY_COMMAND, + ICAL_DISCONNECT_COMMAND, + ICAL_SENDDATA_COMMAND, + ICAL_STARTTLS_COMMAND, + ICAL_UPNEXPAND_COMMAND, + ICAL_COMPLETE_COMMAND, + ICAL_UNKNOWN_COMMAND +} icalcstp_command; + + + +/* A statement is a combination of command or response code and a + component that the server and client exchage with each other. */ +struct icalcstp_statement { + icalcstp_command command; + char* str_data; /* If non-NUll use as arguments to command */ + int int_data; /* If non-NULL use as arguments to command */ + + icalrequeststatus code; + + icalcomponent* data; +}; -icalcstps* icalcstps_new(struct icalcstps_stubs stubs); - -void icalcstps_free(icalcstps* cstp); - -int icalcstps_set_timeout(icalcstps* cstp, int sec); - -/* Get the next string to send to the client */ -char* icalcstps_next_output(icalcstps* cstp); - -/* process the next string from the client */ -int icalcstps_next_input(icalcstps* cstp); - - -/********************** Client (Sender) Interfaces **************************/ - -/* How to use: - - 1) Construct a new icalcstpc - 2) Issue a command by calling one of the command routines. - 3) Repeat until both call icalcstpc_next_output and - icalcstpc_next_input return 0: - 3a) Call icalcstpc_next_output. Send string to server. - 3b) Get string from server, & give to icalcstp_next_input() - 4) Iterate with icalcstpc_first_response & icalcstp_next_response to - get the servers responses - 5) Repeat at #2 -*/ - -typedef void* icalcstpc; - -/* Response code sent by the server. */ -typedef struct icalcstpc_response { - icalrequeststatus code; - char *arg; /* These strings are owned by libical */ - char *debug_text; - char *more_text; - void* result; -} icalcstpc_response; - -icalcstps* icalcstpc_new(); - -void* icalcstpc_free(icalcstpc* cstpc); - -int icalcstpc_set_timeout(icalcstpc* cstp, int sec); - - -/* Get the next string to send to the server */ -char* icalcstpc_next_output(icalcstpc* cstp); - -/* process the next string from the server */ -int icalcstpc_next_input(icalcstpc* cstp); - -/* After icalcstpc_next_input returns a 0, there are responses - ready. use these to get them */ -icalcstpc_response icalcstpc_first_response(icalcstpc* cstp); -icalcstpc_response icalcstpc_next_response(icalcstpc* cstp); - -/* Issue a command */ -icalerrorenum icalcstpc_abort(icalcstpc* cstp); -icalerrorenum icalcstpc_authenticate(icalcstpc* cstp, char* mechanism, - char* init_data, char* f(char*) ); -icalerrorenum icalcstpc_capability(icalcstpc* cstp); -icalerrorenum icalcstpc_calidexpand(icalcstpc* cstp,char* calid); -icalerrorenum icalcstpc_continue(icalcstpc* cstp, unsigned int time); -icalerrorenum icalcstpc_disconnect(icalcstpc* cstp); -icalerrorenum icalcstpc_identify(icalcstpc* cstp, char* id); -icalerrorenum icalcstpc_starttls(icalcstpc* cstp, char* command, - char* init_data, char* f(char*)); -icalerrorenum icalcstpc_senddata(icalcstpc* cstp, unsigned int time, - icalcomponent *comp); -icalerrorenum icalcstpc_upnexpand(icalcstpc* cstp,char* calid); -icalerrorenum icalcstpc_sendata(icalcstpc* cstp, unsigned int time, - icalcomponent *comp); - +const char* icalcstp_command_to_string(icalcstp_command command); +icalcstp_command icalcstp_string_to_command(const char* str); #endif /* !ICALCSTP_H */ diff --git a/libical/src/libicalvcal/Makefile.am b/libical/src/libicalvcal/Makefile.am index 3c307e7f4c..c409347d14 100644 --- a/libical/src/libicalvcal/Makefile.am +++ b/libical/src/libicalvcal/Makefile.am @@ -4,8 +4,7 @@ INCLUDES = \ -I$(top_builddir) \ -I$(top_srcdir)/src/libical \ -I$(top_builddir)/src/libical \ - -I$(top_srcdir)/src/libicalss \ - -I$(srcdir) + -I$(top_srcdir)/src/libicalss libicalvcal_la_LDFLAGS = -version-info 0:0:0 diff --git a/libical/src/test/Makefile.am b/libical/src/test/Makefile.am index 2830afdaa0..d4fa33c040 100644 --- a/libical/src/test/Makefile.am +++ b/libical/src/test/Makefile.am @@ -1,16 +1,16 @@ noinst_PROGRAMS = copycluster regression parser storage stow recur testmime testvcal process testclassify -LDADD = ../libicalss/libicalss.la ../libicalvcal/libicalvcal.la ../libical/libical.la +LDADD = ../libicalss/.libs/libicalss.a ../libicalvcal/.libs/libicalvcal.a ../libical/.libs/libical.a -INCLUDES = \ - -I. \ - -I../libicalvcal \ - -I$(srcdir)/../libicalvcal \ - -I$(srcdir) \ - -I../libical \ - -I$(srcdir)/../libical \ - -I../libicalss \ +INCLUDES = \ + -I. \ + -I../libicalvcal \ + -I$(srcdir)/../libicalvcal \ + -I$(srcdir) \ + -I../libical \ + -I$(srcdir)/../libical \ + -I../libicalss \ -I$(srcdir)/../libicalss copycluster_SOURCES = copycluster.c diff --git a/libical/src/test/copycluster.c b/libical/src/test/copycluster.c index fa87e25385..4eefc37758 100644 --- a/libical/src/test/copycluster.c +++ b/libical/src/test/copycluster.c @@ -31,8 +31,14 @@ #include "icalfileset.h" #include <errno.h> #include <string.h> /* For strerror */ +#include <signal.h> /* for signal */ +#include <unistd.h> /* for alarm */ #include "icalrestriction.h" +static void sig_alrm(int i){ + fprintf(stderr,"Could not get lock on file\n"); + exit(1); +} /* This program copies a file that holds iCal components to an other file. */ @@ -57,10 +63,14 @@ int main(int c, char *argv[]){ } - icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR, ICAL_ERROR_NONFATAL); icalerror_set_error_state(ICAL_PARSE_ERROR, ICAL_ERROR_NONFATAL); + + signal(SIGALRM,sig_alrm); + + alarm(0); clusterin = icalfileset_new(argv[1]); + alarm(0); if (clusterin == 0){ printf("Could not open input cluster \"%s\"",argv[1]); @@ -81,13 +91,16 @@ int main(int c, char *argv[]){ itr != 0; itr = icalset_get_next_component(clusterin)){ + icalerror_set_error_state(ICAL_BADARG_ERROR, ICAL_ERROR_NONFATAL); icalrestriction_check(itr); + icalerror_set_error_state(ICAL_BADARG_ERROR, ICAL_ERROR_DEFAULT); if (itr != 0){ if(tostdout){ printf("--------------\n%s\n",icalcomponent_as_ical_string(itr)); + } else { icalfileset_add_component(clusterout, diff --git a/libical/src/test/regression.c b/libical/src/test/regression.c index 00c686d027..3512905cfe 100644 --- a/libical/src/test/regression.c +++ b/libical/src/test/regression.c @@ -41,6 +41,14 @@ #include <sys/time.h> /* for select */ +/* For GNU libc, strcmp appears to be a macro, so using strcmp in + assert results in incomprehansible assertion messages. This + eliminates the problem */ + +int regrstrcmp(const char* a, const char* b){ + return strcmp(a,b); +} + /* This example creates and minipulates the ical object that appears * in rfc 2445, page 137 */ @@ -253,7 +261,7 @@ icalcomponent* create_new_component() icalproperty_add_parameter( property, - icalparameter_new_rsvp(1) + icalparameter_new_rsvp(ICAL_RSVP_TRUE) ); icalproperty_add_parameter( @@ -380,7 +388,7 @@ icalcomponent* create_new_component_with_va_args() icalproperty_vanew_attendee( "employee-A@host.com", icalparameter_new_role(ICAL_ROLE_REQPARTICIPANT), - icalparameter_new_rsvp(1), + icalparameter_new_rsvp(ICAL_RSVP_TRUE), icalparameter_new_cutype(ICAL_CUTYPE_GROUP), 0 ), @@ -440,7 +448,7 @@ char** get_required_attendees(icalproperty* event) if ( icalparameter_get_role(parameter) == ICAL_ROLE_REQPARTICIPANT) { - attendees[c++] = strdup(icalproperty_get_attendee(p)); + attendees[c++] = icalmemory_strdup(icalproperty_get_attendee(p)); if (c >= max) { max *= 2; @@ -542,6 +550,35 @@ void test_values() if (v!=0) icalvalue_free(v); + assert(ICAL_BOOLEAN_VALUE == + icalparameter_value_to_value_kind(ICAL_VALUE_BOOLEAN)); + assert(ICAL_UTCOFFSET_VALUE == + icalparameter_value_to_value_kind(ICAL_VALUE_UTCOFFSET)); + assert(ICAL_RECUR_VALUE == + icalparameter_value_to_value_kind(ICAL_VALUE_RECUR)); + assert(ICAL_CALADDRESS_VALUE == + icalparameter_value_to_value_kind(ICAL_VALUE_CALADDRESS)); + assert(ICAL_PERIOD_VALUE == + icalparameter_value_to_value_kind(ICAL_VALUE_PERIOD)); + assert(ICAL_BINARY_VALUE == + icalparameter_value_to_value_kind(ICAL_VALUE_BINARY)); + assert(ICAL_TEXT_VALUE == + icalparameter_value_to_value_kind(ICAL_VALUE_TEXT)); + assert(ICAL_DURATION_VALUE == + icalparameter_value_to_value_kind(ICAL_VALUE_DURATION)); + assert(ICAL_INTEGER_VALUE == icalparameter_value_to_value_kind(ICAL_VALUE_INTEGER)); + assert(ICAL_TIME_VALUE == + icalparameter_value_to_value_kind(ICAL_VALUE_TIME)); + assert(ICAL_URI_VALUE == + icalparameter_value_to_value_kind(ICAL_VALUE_URI)); + assert(ICAL_FLOAT_VALUE == + icalparameter_value_to_value_kind(ICAL_VALUE_FLOAT)); + assert(ICAL_X_VALUE == + icalparameter_value_to_value_kind(ICAL_VALUE_X)); + assert(ICAL_DATETIME_VALUE == + icalparameter_value_to_value_kind(ICAL_VALUE_DATETIME)); + assert(ICAL_DATE_VALUE == + icalparameter_value_to_value_kind(ICAL_VALUE_DATE)); /* v = icalvalue_new_caladdress(0); @@ -604,14 +641,48 @@ void test_properties() void test_parameters() { icalparameter *p; + int i; + int enums[] = {ICAL_CUTYPE_INDIVIDUAL,ICAL_CUTYPE_RESOURCE,ICAL_FBTYPE_BUSY,ICAL_PARTSTAT_NEEDSACTION,ICAL_ROLE_NONPARTICIPANT,ICAL_XLICCOMPARETYPE_LESSEQUAL,ICAL_XLICERRORTYPE_MIMEPARSEERROR,-1}; + + char* str1 = "A Common Name"; - p = icalparameter_new_cn("A Common Name"); + p = icalparameter_new_cn(str1); printf("Common Name: %s\n",icalparameter_get_cn(p)); + assert(regrstrcmp(str1,icalparameter_get_cn(p)) == 0); + printf("As String: %s\n",icalparameter_as_ical_string(p)); + assert(regrstrcmp(icalparameter_as_ical_string(p),"CN=A Common Name")==0); + icalparameter_free(p); + + + p = icalparameter_new_from_string("PARTSTAT=ACCEPTED"); + assert(icalparameter_isa(p) == ICAL_PARTSTAT_PARAMETER); + assert(icalparameter_get_partstat(p) == ICAL_PARTSTAT_ACCEPTED); + + p = icalparameter_new_from_string("ROLE=CHAIR"); + assert(icalparameter_isa(p) == ICAL_ROLE_PARAMETER); + assert(icalparameter_get_partstat(p) == ICAL_ROLE_CHAIR); + + p = icalparameter_new_from_string("PARTSTAT=X-FOO"); + assert(icalparameter_isa(p) == ICAL_PARTSTAT_PARAMETER); + assert(icalparameter_get_partstat(p) == ICAL_PARTSTAT_X); + + p = icalparameter_new_from_string("X-PARAM=X-FOO"); + assert(icalparameter_isa(p) == ICAL_X_PARAMETER); + + + for (i=0;enums[i] != -1; i++){ + + printf("%s\n",icalparameter_enum_to_string(enums[i])); + assert(icalparameter_string_to_enum( + icalparameter_enum_to_string(enums[i]))==enums[i]); + } + + } @@ -1038,7 +1109,7 @@ void test_restriction() icalproperty_vanew_attendee( "employee-A@host.com", icalparameter_new_role(ICAL_ROLE_REQPARTICIPANT), - icalparameter_new_rsvp(1), + icalparameter_new_rsvp(ICAL_RSVP_TRUE), icalparameter_new_cutype(ICAL_CUTYPE_GROUP), 0 ), @@ -1047,7 +1118,7 @@ void test_restriction() icalproperty_new_class("PUBLIC"), icalproperty_new_created(atime), icalproperty_new_summary("XYZ Project Review"), -/* icalproperty_vanew_dtstart( + /* icalproperty_new_dtstart( atime, icalparameter_new_tzid("US-Eastern"), 0 @@ -1171,6 +1242,23 @@ void test_recur() } +void test_expand_recurrence(){ + + time_t arr[10]; + time_t now = 931057385; + int i; + icalrecur_expand_recurrence( "FREQ=MONTHLY;BYDAY=MO,WE", now, + 5, arr ); + + printf("Start %s",ctime(&now) ); + for (i=0; i<5; i++) + { + printf("i=%d %s\n", i, ctime(&arr[i]) ); + } + +} + + enum byrule { NO_CONTRACTION = -1, @@ -1336,12 +1424,28 @@ void test_period() { struct icalperiodtype p; + icalvalue *v; p = icalperiodtype_from_string("19971015T050000Z/PT8H30M"); printf("%s\n",icalperiodtype_as_ical_string(p)); + assert(strcmp(icalperiodtype_as_ical_string(p), + "19971015T050000Z/PT8H30M") == 0); p = icalperiodtype_from_string("19971015T050000Z/19971015T060000Z"); printf("%s\n",icalperiodtype_as_ical_string(p)); + assert(strcmp(icalperiodtype_as_ical_string(p), + "19971015T050000Z/19971015T060000Z") == 0); + + p = icalperiodtype_from_string("19970101T120000/PT3H"); + printf("%s\n",icalperiodtype_as_ical_string(p)); + assert(strcmp(icalperiodtype_as_ical_string(p), + "19970101T120000/PT3H") == 0); + + v = icalvalue_new_from_string(ICAL_PERIOD_VALUE,"19970101T120000/PT3H"); + printf("%s\n",icalvalue_as_ical_string(v)); + assert(strcmp(icalvalue_as_ical_string(v), + "19970101T120000/PT3H") == 0); + } @@ -1473,10 +1577,10 @@ void do_test_time(char* zone) printf("Orig (ical) : %s\n", ictt_as_string(ictt)); icttnorm = ictt; icttnorm.second -= 60 * 60 * 24 * 5; - icttnorm = icaltime_normalize(ictt); + icttnorm = icaltime_normalize(icttnorm); printf("-5d in sec : %s\n", ictt_as_string(icttnorm)); icttnorm.day += 60; - icttnorm = icaltime_normalize(ictt); + icttnorm = icaltime_normalize(icttnorm); printf("+60 d : %s\n", ictt_as_string(icttnorm)); @@ -1754,7 +1858,7 @@ char* test_set_tz(const char* tzid) /* Put the new time zone into the environment */ if(getenv("TZ") != 0){ - tzstr = (char*)strdup(getenv("TZ")); + tzstr = (char*)icalmemory_strdup(getenv("TZ")); if(tzstr == 0){ icalerror_set_errno(ICAL_NEWFAILED_ERROR); @@ -2301,6 +2405,10 @@ void test_recur_parser() } +char* ical_strstr(const char *haystack, const char *needle){ + return strstr(haystack,needle); +} + void test_doy() { struct icaltimetype tt1, tt2; @@ -2310,17 +2418,22 @@ void test_doy() doy = icaltime_day_of_year(tt1); tt2 = icaltime_from_day_of_year(doy,1995); printf("%d %s %s\n",doy, icaltime_as_ctime(tt1),icaltime_as_ctime(tt2)); + assert(tt2.day == 1 && tt2.month == 3); + assert(doy == 60); tt1 = icaltime_from_string("19960301"); doy = icaltime_day_of_year(tt1); tt2 = icaltime_from_day_of_year(doy,1996); printf("%d %s %s\n",doy, icaltime_as_ctime(tt1),icaltime_as_ctime(tt2)); + assert(tt2.day == 1 && tt2.month == 3); + assert(doy == 61); tt1 = icaltime_from_string("19970301"); doy = icaltime_day_of_year(tt1); tt2 = icaltime_from_day_of_year(doy,1997); printf("%d %s %s\n",doy, icaltime_as_ctime(tt1),icaltime_as_ctime(tt2)); - + assert(tt2.day == 1 && tt2.month == 3); + assert(doy == 60); } @@ -2832,17 +2945,54 @@ void test_file_locks() assert(sec == final); } -/* For GNU libc, strcmp appears to be a macro, so using strcmp in assert results in incomprehansible assertion messages. This eliminates the problem */ +void test_action() +{ + icalcomponent *c; + icalproperty *p; + + static const char test_icalcomp_str[] = +"BEGIN:VEVENT\n" +"ACTION:EMAIL\n" +"ACTION:PROCEDURE\n" +"ACTION:AUDIO\n" +"ACTION:FUBAR\n" +"END:VEVENT\r\n"; + + + c = icalparser_parse_string ((char *) test_icalcomp_str); + if (!c) { + fprintf (stderr, "main(): could not parse the component\n"); + exit (EXIT_FAILURE); + } + + printf("%s\n\n",icalcomponent_as_ical_string(c)); + + p = icalcomponent_get_first_property(c,ICAL_ACTION_PROPERTY); + + assert(icalproperty_get_action(p) == ICAL_ACTION_EMAIL); + + p = icalcomponent_get_next_property(c,ICAL_ACTION_PROPERTY); + + assert(icalproperty_get_action(p) == ICAL_ACTION_PROCEDURE); + + p = icalcomponent_get_next_property(c,ICAL_ACTION_PROPERTY); + + assert(icalproperty_get_action(p) == ICAL_ACTION_AUDIO); + + p = icalcomponent_get_next_property(c,ICAL_ACTION_PROPERTY); + + assert(icalproperty_get_action(p) == ICAL_ACTION_X); + assert(regrstrcmp(icalvalue_get_x(icalproperty_get_value(p)), "FUBAR")==0); + -int ttstrcmp(const char* a, const char* b){ - return strcmp(a,b); } + + void test_trigger() { struct icaltriggertype tr; - struct icaldatetimeperiodtype dtp; icalcomponent *c; icalproperty *p; char* str; @@ -2883,7 +3033,7 @@ void test_trigger() str = icalproperty_as_ical_string(p); printf("%s\n",str); - assert(ttstrcmp("TRIGGER\n ;VALUE=DATE-TIME\n :19970101T120000\n",str) == 0); + assert(regrstrcmp("TRIGGER\n ;VALUE=DATE-TIME\n :19970101T120000\n",str) == 0); icalproperty_free(p); /* TRIGGER, as a DURATION */ @@ -2893,7 +3043,7 @@ void test_trigger() str = icalproperty_as_ical_string(p); printf("%s\n",str); - assert(ttstrcmp("TRIGGER\n :P3DT3H50M45S\n",str) == 0); + assert(regrstrcmp("TRIGGER\n ;VALUE=DURATION\n :P3DT3H50M45S\n",str) == 0); icalproperty_free(p); /* TRIGGER, as a DATETIME, VALUE=DATETIME*/ @@ -2904,7 +3054,7 @@ void test_trigger() str = icalproperty_as_ical_string(p); printf("%s\n",str); - assert(ttstrcmp("TRIGGER\n ;VALUE=DATE-TIME\n :19970101T120000\n",str) == 0); + assert(regrstrcmp("TRIGGER\n ;VALUE=DATE-TIME\n :19970101T120000\n",str) == 0); icalproperty_free(p); /*TRIGGER, as a DURATION, VALUE=DATETIME */ @@ -2916,7 +3066,7 @@ void test_trigger() str = icalproperty_as_ical_string(p); printf("%s\n",str); - assert(ttstrcmp("TRIGGER\n ;VALUE=DURATION\n :P3DT3H50M45S\n",str) == 0); + assert(regrstrcmp("TRIGGER\n ;VALUE=DURATION\n :P3DT3H50M45S\n",str) == 0); icalproperty_free(p); /* TRIGGER, as a DATETIME, VALUE=DURATION*/ @@ -2927,7 +3077,7 @@ void test_trigger() str = icalproperty_as_ical_string(p); printf("%s\n",str); - assert(ttstrcmp("TRIGGER\n ;VALUE=DATE-TIME\n :19970101T120000\n",str) == 0); + assert(regrstrcmp("TRIGGER\n ;VALUE=DATE-TIME\n :19970101T120000\n",str) == 0); icalproperty_free(p); /*TRIGGER, as a DURATION, VALUE=DURATION */ @@ -2939,7 +3089,7 @@ void test_trigger() str = icalproperty_as_ical_string(p); printf("%s\n",str); - assert(ttstrcmp("TRIGGER\n ;VALUE=DURATION\n :P3DT3H50M45S\n",str) == 0); + assert(regrstrcmp("TRIGGER\n ;VALUE=DURATION\n :P3DT3H50M45S\n",str) == 0); icalproperty_free(p); @@ -2951,7 +3101,7 @@ void test_trigger() str = icalproperty_as_ical_string(p); printf("%s\n",str); - assert(ttstrcmp("TRIGGER\n ;VALUE=DATE-TIME\n :19970101T120000\n",str) == 0); + assert(regrstrcmp("TRIGGER\n ;VALUE=DATE-TIME\n :19970101T120000\n",str) == 0); icalproperty_free(p); /*TRIGGER, as a DURATION, VALUE=BINARY */ @@ -2963,7 +3113,7 @@ void test_trigger() str = icalproperty_as_ical_string(p); printf("%s\n",str); - assert(ttstrcmp("TRIGGER\n ;VALUE=DURATION\n :P3DT3H50M45S\n",str) == 0); + assert(regrstrcmp("TRIGGER\n ;VALUE=DURATION\n :P3DT3H50M45S\n",str) == 0); icalproperty_free(p); @@ -2976,7 +3126,6 @@ void test_rdate() struct icaldatetimeperiodtype dtp; icalproperty *p; char* str; - struct icaltimetype time = icaltime_from_string("19970101T120000"); struct icalperiodtype period; period.start = icaltime_from_string("19970101T120000"); @@ -2989,7 +3138,7 @@ void test_rdate() p = icalproperty_new_rdate(dtp); str = icalproperty_as_ical_string(p); printf("%s\n",str); - assert(ttstrcmp("RDATE\n :19970101T120000\n",str) == 0); + assert(regrstrcmp("RDATE\n ;VALUE=DATE-TIME\n :19970101T120000\n",str) == 0); icalproperty_free(p); @@ -3000,7 +3149,7 @@ void test_rdate() str = icalproperty_as_ical_string(p); printf("%s\n",str); - assert(ttstrcmp("RDATE\n ;VALUE=PERIOD\n :19970101T120000/PT3H10M15S\n",str) == 0); + assert(regrstrcmp("RDATE\n ;VALUE=PERIOD\n :19970101T120000/PT3H10M15S\n",str) == 0); icalproperty_free(p); /* RDATE, as DATE-TIME, VALUE=DATE-TIME */ @@ -3010,7 +3159,7 @@ void test_rdate() icalproperty_add_parameter(p,icalparameter_new_value(ICAL_VALUE_DATETIME)); str = icalproperty_as_ical_string(p); printf("%s\n",str); - assert(ttstrcmp("RDATE\n ;VALUE=DATE-TIME\n :19970101T120000\n",str) == 0); + assert(regrstrcmp("RDATE\n ;VALUE=DATE-TIME\n :19970101T120000\n",str) == 0); icalproperty_free(p); @@ -3021,7 +3170,7 @@ void test_rdate() icalproperty_add_parameter(p,icalparameter_new_value(ICAL_VALUE_DATETIME)); str = icalproperty_as_ical_string(p); printf("%s\n",str); - assert(ttstrcmp("RDATE\n ;VALUE=PERIOD\n :19970101T120000/PT3H10M15S\n",str) == 0); + assert(regrstrcmp("RDATE\n ;VALUE=PERIOD\n :19970101T120000/PT3H10M15S\n",str) == 0); icalproperty_free(p); @@ -3032,7 +3181,7 @@ void test_rdate() icalproperty_add_parameter(p,icalparameter_new_value(ICAL_VALUE_PERIOD)); str = icalproperty_as_ical_string(p); printf("%s\n",str); - assert(ttstrcmp("RDATE\n ;VALUE=DATE-TIME\n :19970101T120000\n",str) == 0); + assert(regrstrcmp("RDATE\n ;VALUE=DATE-TIME\n :19970101T120000\n",str) == 0); icalproperty_free(p); @@ -3043,7 +3192,7 @@ void test_rdate() icalproperty_add_parameter(p,icalparameter_new_value(ICAL_VALUE_PERIOD)); str = icalproperty_as_ical_string(p); printf("%s\n",str); - assert(ttstrcmp("RDATE\n ;VALUE=PERIOD\n :19970101T120000/PT3H10M15S\n",str) == 0); + assert(regrstrcmp("RDATE\n ;VALUE=PERIOD\n :19970101T120000/PT3H10M15S\n",str) == 0); icalproperty_free(p); @@ -3054,7 +3203,7 @@ void test_rdate() icalproperty_add_parameter(p,icalparameter_new_value(ICAL_VALUE_BINARY)); str = icalproperty_as_ical_string(p); printf("%s\n",str); - assert(ttstrcmp("RDATE\n ;VALUE=DATE-TIME\n :19970101T120000\n",str) == 0); + assert(regrstrcmp("RDATE\n ;VALUE=DATE-TIME\n :19970101T120000\n",str) == 0); icalproperty_free(p); @@ -3065,29 +3214,150 @@ void test_rdate() icalproperty_add_parameter(p,icalparameter_new_value(ICAL_VALUE_BINARY)); str = icalproperty_as_ical_string(p); printf("%s\n",str); - assert(ttstrcmp("RDATE\n ;VALUE=PERIOD\n :19970101T120000/PT3H10M15S\n",str) == 0); + assert(regrstrcmp("RDATE\n ;VALUE=PERIOD\n :19970101T120000/PT3H10M15S\n",str) == 0); icalproperty_free(p); } +void test_langbind() +{ + icalcomponent *c, *inner; + icalproperty *p; + + static const char test_str[] = +"BEGIN:VEVENT\n" +"ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:MAILTO:employee-A@host.com\n" +"COMMENT: Comment that \n spans a line\n" +"DTSTART:19970101T120000\n" +"DTSTART:19970101T120000Z\n" +"DTSTART:19970101\n" +"DURATION:P3DT4H25M\n" +"FREEBUSY:19970101T120000/19970101T120000\n" +"FREEBUSY:19970101T120000/P3DT4H25M\n" +"END:VEVENT\n"; + + + printf("%s\n",test_str); + + c = icalparser_parse_string(test_str); + inner = icalcomponent_get_inner(c); + + + for( + p = icallangbind_get_first_property(inner,"ANY"); + p != 0; + p = icallangbind_get_next_property(inner,"ANY") + ) { + + printf("%s\n",icallangbind_property_eval_string(p,":")); + } + + + + p = icalcomponent_get_first_property(inner,ICAL_ATTENDEE_PROPERTY); + + icalproperty_set_parameter_from_string(p,"CUTYPE","INDIVIDUAL"); + + printf("%s\n",icalproperty_as_ical_string(p)); + + + icalproperty_set_value_from_string(p,"mary@foo.org","TEXT"); + + printf("%s\n",icalproperty_as_ical_string(p)); + +} + +void test_property_parse() +{ + icalproperty *p; + + p= icalproperty_new_from_string( + "ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:MAILTO:employee-A@host.com"); + + assert (p != 0); + printf("%s\n",icalproperty_as_ical_string(p)); + + + p= icalproperty_new_from_string("DTSTART:19970101T120000Z\n"); + + assert (p != 0); + printf("%s\n",icalproperty_as_ical_string(p)); + +} + + +void test_value_parameter() +{ + + icalcomponent *c; + icalproperty *p; + icalparameter *param; + + static const char test_icalcomp_str[] = +"BEGIN:VEVENT\n" +"DTSTART;VALUE=DATE-TIME:19971123T123000\n" +"DTSTART;VALUE=DATE:19971123\n" +"DTSTART;VALUE=FOO:19971123T123000\n" +"END:VEVENT\n"; + + c = icalparser_parse_string ((char *) test_icalcomp_str); + if (!c) { + fprintf (stderr, "main(): could not parse the component\n"); + exit (EXIT_FAILURE); + } + + printf("%s",icalcomponent_as_ical_string(c)); + + p = icalcomponent_get_first_property(c,ICAL_DTSTART_PROPERTY); + param = icalproperty_get_first_parameter(p,ICAL_VALUE_PARAMETER); + assert(icalparameter_get_value(param) == ICAL_VALUE_DATETIME); + + p = icalcomponent_get_next_property(c,ICAL_DTSTART_PROPERTY); + param = icalproperty_get_first_parameter(p,ICAL_VALUE_PARAMETER); + assert(icalparameter_get_value(param) == ICAL_VALUE_DATE); + +} + + +void test_x_property() +{ + icalproperty *p; + + p= icalproperty_new_from_string( + "X-LIC-PROPERTY: This is a note"); + + printf("%s\n",icalproperty_as_ical_string(p)); + + assert(icalproperty_isa(p) == ICAL_X_PROPERTY); + assert(regrstrcmp(icalproperty_get_x_name(p),"X-LIC-PROPERTY")==0); + assert(regrstrcmp(icalproperty_get_x(p)," This is a note")==0); + +} + int main(int argc, char *argv[]) { int c; extern char *optarg; - extern int optind, optopt; + extern int optopt; int errflg=0; char* program_name = strrchr(argv[0],'/'); - int ttime=0, trecur=0,tspan=0, tmisc=0, tgauge = 0, tfile = 0; + int ttime=0, trecur=0,tspan=0, tmisc=0, tgauge = 0, tfile = 0, + tbasic = 0; if(argc==1) { - ttime = trecur = tspan = tmisc = tgauge = tfile = 1; + ttime = trecur = tspan = tmisc = tgauge = tfile = tbasic = 1; } - while ((c = getopt(argc, argv, "t:s:r:m:g:f:")) != -1) { + while ((c = getopt(argc, argv, "t:s:r:m:g:f:b:")) != -1) { switch (c) { + case 'b': { + tbasic = atoi(optarg); + break; + } + case 't': { ttime = atoi(optarg); break; @@ -3146,7 +3416,7 @@ int main(int argc, char *argv[]) printf("\n------------Test time----------------\n"); test_time(); } - + if(ttime==1 || ttime==4){ printf("\n------------Test day of year---------\n"); test_doy(); @@ -3179,6 +3449,13 @@ int main(int argc, char *argv[]) test_recur_parameter_bug(); } + if(trecur==1 || trecur==5){ + printf("\n------------Test Array Expansion---------\n"); + test_expand_recurrence(); + } + + + if(tspan==1 || tspan==2){ printf("\n------------Test FBlist------------\n"); @@ -3239,6 +3516,55 @@ int main(int argc, char *argv[]) test_rdate(); } + if(tmisc == 1 || tmisc == 6){ + + printf("\n------------Test language binding---------------\n"); + test_langbind(); + } + + + if(tmisc == 1 || tmisc == 7){ + + printf("\n------------Test property parser---------------\n"); + test_property_parse(); + } + + if(tmisc == 1 || tmisc == 8){ + printf("\n------------Test Action ------------------\n"); + test_action(); + } + + if(tmisc == 1 || tmisc == 9){ + printf("\n------------Test Value Parameter ------------------\n"); + test_value_parameter(); + } + + if(tmisc == 1 || tmisc == 10){ + printf("\n------------Test X property ------------------\n"); + test_x_property(); + } + + + if(tbasic == 1 || tbasic == 2){ + printf("\n------------Test Values---------------\n"); + test_values(); + } + + if(tbasic == 1 || tbasic == 3){ + printf("\n------------Test Parameters-----------\n"); + test_parameters(); + } + + if(tbasic == 1 || tbasic == 4){ + printf("\n------------Test Properties-----------\n"); + test_properties(); + } + + if(tbasic == 1 || tbasic == 5){ + printf("\n------------Test Components ----------\n"); + test_components(); + } + if(tmisc == 1){ printf("\n------------Test Convenience ------------\n"); @@ -3262,18 +3588,6 @@ int main(int argc, char *argv[]) printf("\n------------Test Compare---------------\n"); test_compare(); - printf("\n------------Test Values---------------\n"); - test_values(); - - printf("\n------------Test Parameters-----------\n"); - test_parameters(); - - printf("\n------------Test Properties-----------\n"); - test_properties(); - - printf("\n------------Test Components ----------\n"); - test_components(); - printf("\n------------Create Components --------\n"); create_new_component(); diff --git a/libical/src/test/stow.c b/libical/src/test/stow.c index 2570e3ad0c..e676c677f3 100644 --- a/libical/src/test/stow.c +++ b/libical/src/test/stow.c @@ -49,6 +49,10 @@ char* program_name; void usage(char *message); +#ifndef PATH_MAX +#define PATH_MAX 256 /* HACK */ +#endif + enum options { STORE_IN_FILE, @@ -485,7 +489,7 @@ void usage(char *message) fprintf(stderr,"Usage: %s [-emdcn] [-i inputfile] [-o outputfile] [-u calid]\n",program_name); fprintf(stderr,"-e\tInput data is encapsulated in a MIME Message \n\ -m\tInput is raw iCal \n\ --i\tSpecify input file. Otherwise, input comed from stdin\n\ +-i\tSpecify input file. Otherwise, input comes from stdin\n\ -o\tSpecify file to save incoming message to\n\ -d\tSpecify database to send data to\n\ -u\tSet the calid to store the data to\n\ diff --git a/libical/test-data/0 b/libical/test-data/0 index 9328d854eb..ed915ad582 100644 --- a/libical/test-data/0 +++ b/libical/test-data/0 @@ -1,5 +1,7 @@ BEGIN:VCALENDAR BEGIN:VEVENT SUMMARY:Bastille Day Party This option indicates that xauth should attempt to break any authority file locks before proceeding. +SUMMARY:Bastille Day Party This option indicates that xauth should + attempt to break any authority file locks before proceeding. END:VEVENT END:VCALENDAR diff --git a/libical/test-data/1 b/libical/test-data/1 index 3670e54141..a4d078d47b 100644 --- a/libical/test-data/1 +++ b/libical/test-data/1 @@ -32,8 +32,7 @@ CREATED:19980309T130000Z SUMMARY:XYZ Project Review DTSTAR;TZID=US-Eastern:19980312T083000 DTEND;TZID=US-Eastern:19980312T093000 -LOCATION:1CP Conference -Room 4350 +LOCATION:1CP Conference Room 4350 END:VEVENT END:VCALENDAR diff --git a/libical/test-data/2445.ics b/libical/test-data/2445.ics index ce94e62e9f..ecf6f106ff 100644 --- a/libical/test-data/2445.ics +++ b/libical/test-data/2445.ics @@ -10,7 +10,7 @@ END:VCALENDAR BEGIN:VEVENT UID:19970901T130000Z-123401@host.com -DTSTAMP:19970901T1300Z +DTSTAMP:19970901T130000Z DTSTART:19970903T163000Z DTEND:19970903T190000Z SUMMARY:Annual Employee Review @@ -20,7 +20,7 @@ END:VEVENT BEGIN:VEVENT UID:19970901T130000Z-123402@host.com -DTSTAMP:19970901T1300Z +DTSTAMP:19970901T130000Z DTSTART:19970401T163000Z DTEND:19970402T010000Z SUMMARY:Laurel is in sensitivity awareness class. @@ -31,7 +31,7 @@ END:VEVENT BEGIN:VEVENT UID:19970901T130000Z-123403@host.com -DTSTAMP:19970901T1300Z +DTSTAMP:19970901T130000Z DTSTART:19971102 SUMMARY:Our Blissful Anniversary CLASS:CONFIDENTIAL @@ -41,7 +41,7 @@ END:VEVENT BEGIN:VTODO UID:19970901T130000Z-123404@host.com -DTSTAMP:19970901T1300Z +DTSTAMP:19970901T130000Z DTSTART:19970415T133000Z DUE:19970416T045959Z SUMMARY:1996 Income Tax Preparation @@ -53,7 +53,7 @@ END:VTODO BEGIN:VJOURNAL UID:19970901T130000Z-123405@host.com -DTSTAMP:19970901T1300Z +DTSTAMP:19970901T130000Z DTSTART;VALUE=DATE:19970317 SUMMARY:Staff meeting minutes DESCRIPTION:1. Staff meeting: Participants include Joe\, Lisa @@ -253,7 +253,7 @@ METHOD:PUBLISH VERSION:2.0 PRODID:-//ABC Corporation//NONSGML My Product//EN BEGIN:VEVENT -DTSTAMP:19970324T1200Z +DTSTAMP:19970324T120000Z SEQUENCE:0 UID:uid3@host1.com ORGANIZER:MAILTO:jdoe@host1.com @@ -284,7 +284,7 @@ STATUS:NEEDS-ACTION SUMMARY:Submit Income Taxes BEGIN:VALARM ACTION:AUDIO -TRIGGER:19980403T120000 +TRIGGER:P1DT25M ATTACH;FMTTYPE=audio/basic:http://host.com/pub/audio- files/ssbanner.aud REPEAT:4 diff --git a/libical/test-data/2446.ics b/libical/test-data/2446.ics index 032276c3a8..c6e2359aa1 100644 --- a/libical/test-data/2446.ics +++ b/libical/test-data/2446.ics @@ -106,6 +106,7 @@ RRULE:FREQ=YEARLY;INTERVAL=1 SUMMARY: Bastille Day END:VEVENT END:VCALENDAR + BEGIN:VCALENDAR PRODID:-//ACME/DesktopCalendar//EN METHOD:REQUEST @@ -120,13 +121,14 @@ ATTENDEE;RSVP=FALSE;CUTYPE=ROOM:conf_Big@example.com ATTENDEE;ROLE=NON-PARTICIPANT;RSVP=FALSE:Mailto:E@example.com DTSTAMP:19970611T190000Z DTSTART:19970701T200000Z -DTEND:19970701T2000000Z +DTEND:19970701T200000Z SUMMARY:Conference UID:calsrv.example.com-873970198738777@example.com SEQUENCE:0 STATUS:CONFIRMED END:VEVENT END:VCALENDAR + BEGIN:VCALENDAR PRODID:-//ACME/DesktopCalendar//EN METHOD:REPLY @@ -826,7 +828,7 @@ SUMMARY:Create the requirements document UID:calsrv.example.com-873970198738777-00@example.com SEQUENCE:0 DTSTAMP:19970717T200000Z -STATUS:Needs Action +STATUS:NEEDS-ACTION END:VTODO END:VCALENDAR BEGIN:VCALENDAR @@ -904,7 +906,7 @@ SUMMARY:Create the requirements document UID:calsrv.example.com-873970198738777-00@example.com SEQUENCE:1 DTSTAMP:19970718T100000Z -STATUS:IN-PROGRESS +STATUS:IN-PROCESS PERCENT-COMPLETE:40 END:VTODO END:VCALENDAR @@ -978,7 +980,7 @@ BEGIN:VEVENT UID:acme-12345@host1.com SEQUENCE:3 RRULE:FREQ=WEEKLY -RDATE;VALUE=PERIOD:19970819T210000Z/199700819T220000Z +RDATE;VALUE=PERIOD:19970819T210000Z/19970819T220000Z ORGANIZER:Mailto:A@example.com ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED:Mailto:A@example.com ATTENDEE:Mailto:B@example.com |