From e6f1da7f4681def1f8b0472a504dda549f9f4b89 Mon Sep 17 00:00:00 2001 From: JP Rosevear Date: Tue, 17 Apr 2001 17:54:48 +0000 Subject: Finish merge of new libical 0.23a version 2001-04-17 JP Rosevear * Finish merge of new libical 0.23a version svn path=/trunk/; revision=9420 --- libical/src/Makefile.am | 9 +- libical/src/libical/Makefile.am | 143 ++++-- libical/src/libical/icalcomponent.c | 96 +++- libical/src/libical/icalcomponent.h | 61 ++- libical/src/libical/icalenums.c | 496 -------------------- libical/src/libical/icalenums.h | 349 ++------------ libical/src/libical/icalerror.c | 115 +++-- libical/src/libical/icalerror.h | 131 +++--- libical/src/libical/icallangbind.c | 279 +++++++---- libical/src/libical/icalmemory.h | 4 +- libical/src/libical/icalparser.c | 169 +++++-- libical/src/libical/icalparser.h | 2 +- libical/src/libical/icalrecur.c | 910 ++++++++++++++++++++++++------------ libical/src/libical/icaltime.c | 501 +++----------------- libical/src/libical/icaltime.h | 80 ++-- libical/src/libical/icaltypes.h | 31 +- libical/src/libicalss/Makefile.am | 14 +- libical/src/libicalss/icalcstp.h | 164 ++----- libical/src/libicalvcal/Makefile.am | 3 +- libical/src/test/Makefile.am | 18 +- libical/src/test/copycluster.c | 15 +- libical/src/test/regression.c | 410 ++++++++++++++-- libical/src/test/stow.c | 6 +- 23 files changed, 1886 insertions(+), 2120 deletions(-) (limited to 'libical/src') 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 /* for malloc */ #include /* 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 /* For strncmp */ #include -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 - - +#include 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 #include /* 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_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_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<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<days[days_index++] = day; + } + + break; + } + + case (1<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<days[days_index++] = day; + } + } + } - doy = icaltime_day_of_year(t); + } - impl->days[days_index++] = doy; + break; + } + + case (1<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_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, */ -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 ab */ 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 -#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 #include /* For strerror */ +#include /* for signal */ +#include /* 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 /* 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\ -- cgit v1.2.3