summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorAllen Winter <allen.winter@kdab.com>2014-06-28 17:45:24 -0400
committerAllen Winter <allen.winter@kdab.com>2014-06-28 17:45:24 -0400
commit43858141030ba123a4959231cadc9951b983f0fd (patch)
tree8256c1dbf3ca7c9e58a3dbecf07cf826fb2e0ce2 /src/test
downloadlibical-git-1.0.0.tar.gz
libical 1.0.0 (non-ancestor)v1.0.01.0.0
Diffstat (limited to 'src/test')
-rw-r--r--src/test/2445.ics326
-rw-r--r--src/test/2446.ics0
-rw-r--r--src/test/CMakeLists.txt103
-rw-r--r--src/test/Makefile.am65
-rw-r--r--src/test/Makefile.in823
-rw-r--r--src/test/copycluster.c150
-rw-r--r--src/test/findobj.c71
-rw-r--r--src/test/icaltestparser.c122
-rw-r--r--src/test/itip.ics14
-rw-r--r--src/test/outgoing.ics544
-rw-r--r--src/test/process.c416
-rw-r--r--src/test/recur.c163
-rw-r--r--src/test/recur.dsp102
-rw-r--r--src/test/regression-classify.c193
-rw-r--r--src/test/regression-component.c570
-rw-r--r--src/test/regression-cxx.cpp137
-rw-r--r--src/test/regression-recur.c199
-rw-r--r--src/test/regression-storage.c808
-rw-r--r--src/test/regression-utils.c180
-rw-r--r--src/test/regression.c3907
-rw-r--r--src/test/regression.dsp125
-rw-r--r--src/test/regression.h55
-rw-r--r--src/test/storage.c873
-rw-r--r--src/test/stow.c895
-rw-r--r--src/test/testclassify.c129
-rw-r--r--src/test/testmime.c351
-rw-r--r--src/test/testvcal.c64
-rw-r--r--src/test/timezones.c165
28 files changed, 11550 insertions, 0 deletions
diff --git a/src/test/2445.ics b/src/test/2445.ics
new file mode 100644
index 00000000..71cf45e7
--- /dev/null
+++ b/src/test/2445.ics
@@ -0,0 +1,326 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//hacksw/handcal//NONSGML v1.0//EN
+BEGIN:VEVENT
+DTSTAMP:19970901T1300Z
+DTSTART:19970714T170000Z
+DTEND:19970715T035959Z
+SUMMARY:Bastille Day Party
+END:VEVENT
+END:VCALENDAR
+
+BEGIN:VEVENT
+UID:19970901T130000Z-123401@host.com
+DTSTAMP:19970901T1300Z
+DTSTART:19970903T163000Z
+DTEND:19970903T190000Z
+SUMMARY:Annual Employee Review
+CLASS:PRIVATE
+CATEGORIES:BUSINESS,HUMAN RESOURCES
+END:VEVENT
+
+BEGIN:VEVENT
+UID:19970901T130000Z-123402@host.com
+DTSTAMP:19970901T1300Z
+DTSTART:19970401T163000Z
+DTEND:19970402T010000Z
+SUMMARY:Laurel is in sensitivity awareness class.
+CLASS:PUBLIC
+CATEGORIES:BUSINESS,HUMAN RESOURCES
+TRANSP:TRANSPARENT
+END:VEVENT
+
+BEGIN:VEVENT
+UID:19970901T130000Z-123403@host.com
+DTSTAMP:19970901T1300Z
+DTSTART:19971102
+SUMMARY:Our Blissful Anniversary
+CLASS:CONFIDENTIAL
+CATEGORIES:ANNIVERSARY,PERSONAL,SPECIAL OCCASION
+RRULE:FREQ=YEARLY
+END:VEVENT
+
+BEGIN:VTODO
+UID:19970901T130000Z-123404@host.com
+DTSTAMP:19970901T1300Z
+DTSTART:19970415T133000Z
+DUE:19970416T045959Z
+SUMMARY:1996 Income Tax Preparation
+CLASS:CONFIDENTIAL
+CATEGORIES:FAMILY,FINANCE
+PRIORITY:1
+STATUS:NEEDS-ACTION
+END:VTODO
+BEGIN:VJOURNAL
+UID:19970901T130000Z-123405@host.com
+DTSTAMP:19970901T1300Z
+DTSTART;VALUE=DATE:19970317
+SUMMARY:Staff meeting minutes
+DESCRIPTION:1. Staff meeting: Participants include Joe\, Lisa
+ and Bob. Aurora project plans were reviewed. There is currently
+ no budget reserves for this project. Lisa will escalate to
+ management. Next meeting on Tuesday.\n
+ 2. Telephone Conference: ABC Corp. sales representative called
+ to discuss new printer. Promised to get us a demo by Friday.\n
+ 3. Henry Miller (Handsoff Insurance): Car was totaled by tree.
+ Is looking into a loaner car. 654-2323 (tel).
+END:VJOURNAL
+BEGIN:VFREEBUSY
+ORGANIZER:MAILTO:jane_doe@host1.com
+ATTENDEE:MAILTO:john_public@host2.com
+DTSTART:19971015T050000Z
+DTEND:19971016T050000Z
+DTSTAMP:19970901T083000Z
+END:VFREEBUSY
+BEGIN:VFREEBUSY
+ORGANIZER:MAILTO:jane_doe@host1.com
+ATTENDEE:MAILTO:john_public@host2.com
+DTSTAMP:19970901T100000Z
+FREEBUSY;VALUE=PERIOD:19971015T050000Z/PT8H30M,
+ 19971015T160000Z/PT5H30M,19971015T223000Z/PT6H30M
+URL:http://host2.com/pub/busy/jpublic-01.ifb
+COMMENT:This iCalendar file contains busy time information for
+ the next three months.
+END:VFREEBUSY
+BEGIN:VFREEBUSY
+ORGANIZER:jsmith@host.com
+DTSTART:19980313T141711Z
+DTEND:19980410T141711Z
+FREEBUSY:19980314T233000Z/19980315T003000Z
+FREEBUSY:19980316T153000Z/19980316T163000Z
+FREEBUSY:19980318T030000Z/19980318T040000Z
+URL:http://www.host.com/calendar/busytime/jsmith.ifb
+END:VFREEBUSY
+BEGIN:VTIMEZONE
+TZID:US-Eastern
+LAST-MODIFIED:19870101T000000Z
+BEGIN:STANDARD
+DTSTAMP:19970901T130000Z
+DTSTART:19971026T020000
+RDATE:19971026T020000
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+TZNAME:EST
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:19971026T020000
+RDATE:19970406T020000
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+TZNAME:EDT
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VTIMEZONE
+TZID:US-Eastern
+LAST-MODIFIED:19870101T000000Z
+TZURL:http://zones.stds_r_us.net/tz/US-Eastern
+BEGIN:STANDARD
+DTSTART:19671029T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+TZNAME:EST
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:19870405T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+TZNAME:EDT
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VTIMEZONE
+TZID:US--Fictitious-Eastern
+LAST-MODIFIED:19870101T000000Z
+BEGIN:STANDARD
+DTSTART:19671029T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+TZNAME:EST
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:19870405T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=19980404T070000Z
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+TZNAME:EDT
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VTIMEZONE
+TZID:US--Fictitious-Eastern
+LAST-MODIFIED:19870101T000000Z
+BEGIN:STANDARD
+DTSTART:19671029T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+TZNAME:EST
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:19870405T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=19980404T070000Z
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+TZNAME:EDT
+END:DAYLIGHT
+BEGIN:DAYLIGHT
+DTSTART:19990424T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=4
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+TZNAME:EDT
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VALARM
+TRIGGER;VALUE=DATE-TIME:19970317T133000Z
+REPEAT:4
+DURATION:PT15M
+ACTION:AUDIO
+ATTACH;FMTTYPE=audio/basic:ftp://host.com/pub/sounds/bell-01.aud
+END:VALARM
+BEGIN:VALARM
+TRIGGER:-PT30M
+REPEAT:2
+DURATION:PT15M
+ACTION:DISPLAY
+DESCRIPTION:Breakfast meeting with executive\n
+ team at 8:30 AM EST.
+END:VALARM
+BEGIN:VALARM
+TRIGGER:-P2D
+ACTION:EMAIL
+ATTENDEE:MAILTO:john_doe@host.com
+SUMMARY:*** REMINDER: SEND AGENDA FOR WEEKLY STAFF MEETING ***
+DESCRIPTION:A draft agenda needs to be sent out to the attendees
+ to the weekly managers meeting (MGR-LIST). Attached is a
+ pointer the document template for the agenda file.
+ATTACH;FMTTYPE=application/binary:http://host.com/templates/agen
+ da.doc
+END:VALARM
+BEGIN:VALARM
+TRIGGER;VALUE=DATE-TIME:19980101T050000Z
+REPEAT:23
+DURATION:PT1H
+ACTION:PROCEDURE
+ATTACH;FMTTYPE=application/binary:ftp://host.com/novo-
+ procs/felizano.exe
+END:VALARM
+BEGIN:VCALENDAR
+PRODID:-//RDU Software//NONSGML HandCal//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+TZID:US-Eastern
+BEGIN:STANDARD
+DTSTART:19981025T020000
+RDATE:19981025T020000
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+TZNAME:EST
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:19990404T020000
+RDATE:19990404T020000
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+TZNAME:EDT
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:19980309T231000Z
+UID:guid-1.host1.com
+ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com
+ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:
+ MAILTO:employee-A@host.com
+DESCRIPTION:Project XYZ Review Meeting
+CATEGORIES:MEETING
+CLASS:PUBLIC
+CREATED:19980309T130000Z
+SUMMARY:XYZ Project Review
+DTSTART;TZID=US-Eastern:19980312T083000
+DTEND;TZID=US-Eastern:19980312T093000
+LOCATION:1CP Conference Room 4350
+END:VEVENT
+END:VCALENDAR
+
+BEGIN:VCALENDAR
+METHOD:PUBLISH
+VERSION:2.0
+PRODID:-//ABC Corporation//NONSGML My Product//EN
+BEGIN:VEVENT
+DTSTAMP:19970324T1200Z
+SEQUENCE:0
+UID:uid3@host1.com
+ORGANIZER:MAILTO:jdoe@host1.com
+DTSTART:19970324T123000Z
+DTEND:19970324T210000Z
+CATEGORIES:MEETING,PROJECT
+CLASS:PUBLIC
+SUMMARY:Calendaring Interoperability Planning Meeting
+DESCRIPTION:Discuss how we can test c&s interoperability\n
+ using iCalendar and other IETF standards.
+LOCATION:LDB Lobby
+ATTACH;FMTTYPE=application/postscript:ftp://xyzCorp.com/pub/
+ conf/bkgrnd.ps
+END:VEVENT
+END:VCALENDAR
+
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//ABC Corporation//NONSGML My Product//EN
+BEGIN:VTODO
+DTSTAMP:19980130T134500Z
+SEQUENCE:2
+UID:uid4@host1.com
+ORGANIZER:MAILTO:unclesam@us.gov
+ATTENDEE;PARTSTAT=ACCEPTED:MAILTO:jqpublic@host.com
+DUE:19980415T235959
+STATUS:NEEDS-ACTION
+SUMMARY:Submit Income Taxes
+BEGIN:VALARM
+ACTION:AUDIO
+TRIGGER:19980403T120000
+ATTACH;FMTTYPE=audio/basic:http://host.com/pub/audio-
+ files/ssbanner.aud
+REPEAT:4
+DURATION:PT1H
+END:VALARM
+END:VTODO
+END:VCALENDAR
+
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//ABC Corporation//NONSGML My Product//EN
+BEGIN:VJOURNAL
+DTSTAMP:19970324T120000Z
+UID:uid5@host1.com
+ORGANIZER:MAILTO:jsmith@host.com
+STATUS:DRAFT
+CLASS:PUBLIC
+CATEGORIES:Project Report, XYZ, Weekly Meeting
+DESCRIPTION:Project xyz Review Meeting Minutes\n
+ Agenda\n1. Review of project version 1.0 requirements.\n2.
+ Definition
+ of project processes.\n3. Review of project schedule.\n
+ Participants: John Smith\, Jane Doe\, Jim Dandy\n-It was
+ decided that the requirements need to be signed off by
+ product marketing.\n-Project processes were accepted.\n
+ -Project schedule needs to account for scheduled holidays
+ and employee vacation time. Check with HR for specific
+ dates.\n-New schedule will be distributed by Friday.\n-
+ Next weeks meeting is cancelled. No meeting until 3/23.
+END:VJOURNAL
+END:VCALENDAR
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//RDU Software//NONSGML HandCal//EN
+BEGIN:VFREEBUSY
+ORGANIZER:MAILTO:jsmith@host.com
+DTSTART:19980313T141711Z
+DTEND:19980410T141711Z
+FREEBUSY:19980314T233000Z/19980315T003000Z
+FREEBUSY:19980316T153000Z/19980316T163000Z
+FREEBUSY:19980318T030000Z/19980318T040000Z
+URL:http://www.host.com/calendar/busytime/jsmith.ifb
+END:VFREEBUSY
+END:VCALENDAR
diff --git a/src/test/2446.ics b/src/test/2446.ics
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/test/2446.ics
diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt
new file mode 100644
index 00000000..a75089dc
--- /dev/null
+++ b/src/test/CMakeLists.txt
@@ -0,0 +1,103 @@
+include_directories(
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/src
+ ${CMAKE_BINARY_DIR}/src
+)
+
+set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR})
+
+set(TEST_DATADIR "\\\"${CMAKE_SOURCE_DIR}/test-data\\\"")
+add_definitions(-DTEST_DATADIR=${TEST_DATADIR})
+
+########### next target ###############
+
+set(copycluster_SRCS copycluster.c)
+
+add_executable(copycluster ${copycluster_SRCS})
+
+target_link_libraries(copycluster ical icalss)
+
+########### next target ###############
+
+set(regression_SRCS
+ regression.c
+ regression.h
+ regression-component.c
+ regression-classify.c
+ regression-utils.c
+ regression-recur.c
+ regression-storage.c
+)
+
+add_executable(regression ${regression_SRCS})
+
+target_link_libraries(regression ical icalss icalvcal)
+
+add_test(NAME regression WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin COMMAND regression)
+
+########### next target ###############
+
+set(parser_SRCS icaltestparser.c)
+
+add_executable(parser ${parser_SRCS})
+
+target_link_libraries(parser ical icalss)
+
+########### next target ###############
+
+if(NOT WIN32)
+ set(STOW_SRCS stow.c)
+
+ add_executable(stow ${STOW_SRCS})
+
+ target_link_libraries(stow ical icalss)
+endif(NOT WIN32)
+
+########### next target ###############
+
+set(recur_SRCS recur.c)
+
+add_executable(recur ${recur_SRCS})
+
+target_link_libraries(recur ical icalss)
+
+########### next target ###############
+
+if(HAVE_UNISTD_H)
+ set(testmime_SRCS testmime.c)
+
+ add_executable(testmime ${testmime_SRCS})
+
+ target_link_libraries(testmime ical icalss)
+endif(HAVE_UNISTD_H)
+
+########### next target ###############
+
+set(testvcal_SRCS testvcal.c)
+
+add_executable(testvcal ${testvcal_SRCS})
+
+target_link_libraries(testvcal ical icalss icalvcal)
+
+########### next target ###############
+
+set(process_SRCS process.c)
+
+add_executable(process ${process_SRCS})
+
+target_link_libraries(process ical icalss)
+
+########### next target ###############
+
+if(NOT WIN32)
+ set(timezones_SRCS timezones.c)
+
+ add_executable(timezones ${timezones_SRCS})
+
+ target_link_libraries(timezones ical icalss)
+
+ add_test(NAME timezones WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin COMMAND timezones)
+endif(NOT WIN32)
+
+########### install files ###############
+
diff --git a/src/test/Makefile.am b/src/test/Makefile.am
new file mode 100644
index 00000000..6305bd4c
--- /dev/null
+++ b/src/test/Makefile.am
@@ -0,0 +1,65 @@
+regression_SOURCES = \
+ regression.c \
+ regression.h \
+ regression-component.c \
+ regression-classify.c \
+ regression-utils.c \
+ regression-recur.c \
+ regression-storage.c
+
+if WITH_CXX_BINDINGS
+cxx_inc=-DWITH_CXX_BINDINGS
+cxx_libs=../libical/libical_cxx.la
+regression_SOURCES += \
+regression-cxx.cpp
+else
+cxx_inc=
+cxx_libs=
+endif
+
+if WITH_BDB4
+bdb4_inc=-DWITH_BDB -I@BDB_DIR@/include
+bdb4_libs=@BDB_DIR_LIB@/@BDB_LIB@
+else
+bdb4_inc=
+bdb4_libs=
+endif
+
+if OS_WIN32
+else
+STOW = stow
+TIMEZONES = timezones
+endif
+
+check_PROGRAMS = copycluster regression parser $(STOW) recur testmime testvcal process $(TIMEZONES)
+
+LDADD = ../libicalss/libicalss.la ../libicalvcal/libicalvcal.la $(cxx_libs) ../libical/libical.la $(bdb4_libs)
+
+LIBS = @PTHREAD_LIBS@
+
+INCLUDES = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/src \
+ -I$(top_builddir)/src \
+ -I$(top_srcdir)/src/libical \
+ -I$(top_builddir)/src/libical \
+ -I$(top_builddir)/src/libicalss \
+ -I$(top_srcdir)/src/libicalss \
+ -DTEST_DATADIR=\"$(top_srcdir)/test-data\" \
+ $(cxx_inc) $(bdb4_inc)
+
+TESTS=regression timezones
+
+parser_SOURCES = icaltestparser.c
+
+# clusterin.vcd should be a real file with data but it doesn't seem to be in cvs
+CLEANFILES = \
+ test_fileset.ics \
+ test_fileset_locktest.ics \
+ filesetout.ics \
+ clusterin.vcd
+
+clean-local:
+ rm -rf calendar
+
+distclean: clean \ No newline at end of file
diff --git a/src/test/Makefile.in b/src/test/Makefile.in
new file mode 100644
index 00000000..9a546b6d
--- /dev/null
+++ b/src/test/Makefile.in
@@ -0,0 +1,823 @@
+# Makefile.in generated by automake 1.12.2 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2012 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+@WITH_CXX_BINDINGS_TRUE@am__append_1 = \
+@WITH_CXX_BINDINGS_TRUE@regression-cxx.cpp
+
+check_PROGRAMS = copycluster$(EXEEXT) regression$(EXEEXT) \
+ parser$(EXEEXT) $(am__EXEEXT_1) recur$(EXEEXT) \
+ testmime$(EXEEXT) testvcal$(EXEEXT) process$(EXEEXT) \
+ $(am__EXEEXT_2)
+TESTS = regression$(EXEEXT) timezones$(EXEEXT)
+subdir = src/test
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(top_srcdir)/depcomp $(top_srcdir)/mkinstalldirs
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+@OS_WIN32_FALSE@am__EXEEXT_1 = stow$(EXEEXT)
+@OS_WIN32_FALSE@am__EXEEXT_2 = timezones$(EXEEXT)
+copycluster_SOURCES = copycluster.c
+copycluster_OBJECTS = copycluster.$(OBJEXT)
+copycluster_LDADD = $(LDADD)
+@WITH_CXX_BINDINGS_TRUE@am__DEPENDENCIES_1 = \
+@WITH_CXX_BINDINGS_TRUE@ ../libical/libical_cxx.la
+am__DEPENDENCIES_2 =
+copycluster_DEPENDENCIES = ../libicalss/libicalss.la \
+ ../libicalvcal/libicalvcal.la $(am__DEPENDENCIES_1) \
+ ../libical/libical.la $(am__DEPENDENCIES_2)
+am_parser_OBJECTS = icaltestparser.$(OBJEXT)
+parser_OBJECTS = $(am_parser_OBJECTS)
+parser_LDADD = $(LDADD)
+parser_DEPENDENCIES = ../libicalss/libicalss.la \
+ ../libicalvcal/libicalvcal.la $(am__DEPENDENCIES_1) \
+ ../libical/libical.la $(am__DEPENDENCIES_2)
+process_SOURCES = process.c
+process_OBJECTS = process.$(OBJEXT)
+process_LDADD = $(LDADD)
+process_DEPENDENCIES = ../libicalss/libicalss.la \
+ ../libicalvcal/libicalvcal.la $(am__DEPENDENCIES_1) \
+ ../libical/libical.la $(am__DEPENDENCIES_2)
+recur_SOURCES = recur.c
+recur_OBJECTS = recur.$(OBJEXT)
+recur_LDADD = $(LDADD)
+recur_DEPENDENCIES = ../libicalss/libicalss.la \
+ ../libicalvcal/libicalvcal.la $(am__DEPENDENCIES_1) \
+ ../libical/libical.la $(am__DEPENDENCIES_2)
+am__regression_SOURCES_DIST = regression.c regression.h \
+ regression-component.c regression-classify.c \
+ regression-utils.c regression-recur.c regression-storage.c \
+ regression-cxx.cpp
+@WITH_CXX_BINDINGS_TRUE@am__objects_1 = regression-cxx.$(OBJEXT)
+am_regression_OBJECTS = regression.$(OBJEXT) \
+ regression-component.$(OBJEXT) regression-classify.$(OBJEXT) \
+ regression-utils.$(OBJEXT) regression-recur.$(OBJEXT) \
+ regression-storage.$(OBJEXT) $(am__objects_1)
+regression_OBJECTS = $(am_regression_OBJECTS)
+regression_LDADD = $(LDADD)
+regression_DEPENDENCIES = ../libicalss/libicalss.la \
+ ../libicalvcal/libicalvcal.la $(am__DEPENDENCIES_1) \
+ ../libical/libical.la $(am__DEPENDENCIES_2)
+stow_SOURCES = stow.c
+stow_OBJECTS = stow.$(OBJEXT)
+stow_LDADD = $(LDADD)
+stow_DEPENDENCIES = ../libicalss/libicalss.la \
+ ../libicalvcal/libicalvcal.la $(am__DEPENDENCIES_1) \
+ ../libical/libical.la $(am__DEPENDENCIES_2)
+testmime_SOURCES = testmime.c
+testmime_OBJECTS = testmime.$(OBJEXT)
+testmime_LDADD = $(LDADD)
+testmime_DEPENDENCIES = ../libicalss/libicalss.la \
+ ../libicalvcal/libicalvcal.la $(am__DEPENDENCIES_1) \
+ ../libical/libical.la $(am__DEPENDENCIES_2)
+testvcal_SOURCES = testvcal.c
+testvcal_OBJECTS = testvcal.$(OBJEXT)
+testvcal_LDADD = $(LDADD)
+testvcal_DEPENDENCIES = ../libicalss/libicalss.la \
+ ../libicalvcal/libicalvcal.la $(am__DEPENDENCIES_1) \
+ ../libical/libical.la $(am__DEPENDENCIES_2)
+timezones_SOURCES = timezones.c
+timezones_OBJECTS = timezones.$(OBJEXT)
+timezones_LDADD = $(LDADD)
+timezones_DEPENDENCIES = ../libicalss/libicalss.la \
+ ../libicalvcal/libicalvcal.la $(am__DEPENDENCIES_1) \
+ ../libical/libical.la $(am__DEPENDENCIES_2)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = copycluster.c $(parser_SOURCES) process.c recur.c \
+ $(regression_SOURCES) stow.c testmime.c testvcal.c timezones.c
+DIST_SOURCES = copycluster.c $(parser_SOURCES) process.c recur.c \
+ $(am__regression_SOURCES_DIST) stow.c testmime.c testvcal.c \
+ timezones.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = $(am__tty_colors_dummy)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BDB_DIR = @BDB_DIR@
+BDB_DIR_INCLUDE = @BDB_DIR_INCLUDE@
+BDB_DIR_LIB = @BDB_DIR_LIB@
+BDB_LIB = @BDB_LIB@
+BDB_VERSION = @BDB_VERSION@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+JAR = @JAR@
+JAVA = @JAVA@
+JAVAC = @JAVAC@
+JAVAH = @JAVAH@
+JAVA_PLATFORM = @JAVA_PLATFORM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @PTHREAD_LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+PY_CFLAGS = @PY_CFLAGS@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+ZONE_INFO = @ZONE_INFO@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+swig_val = @swig_val@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+regression_SOURCES = regression.c regression.h regression-component.c \
+ regression-classify.c regression-utils.c regression-recur.c \
+ regression-storage.c $(am__append_1)
+@WITH_CXX_BINDINGS_FALSE@cxx_inc =
+@WITH_CXX_BINDINGS_TRUE@cxx_inc = -DWITH_CXX_BINDINGS
+@WITH_CXX_BINDINGS_FALSE@cxx_libs =
+@WITH_CXX_BINDINGS_TRUE@cxx_libs = ../libical/libical_cxx.la
+@WITH_BDB4_FALSE@bdb4_inc =
+@WITH_BDB4_TRUE@bdb4_inc = -DWITH_BDB -I@BDB_DIR@/include
+@WITH_BDB4_FALSE@bdb4_libs =
+@WITH_BDB4_TRUE@bdb4_libs = @BDB_DIR_LIB@/@BDB_LIB@
+@OS_WIN32_FALSE@STOW = stow
+@OS_WIN32_FALSE@TIMEZONES = timezones
+LDADD = ../libicalss/libicalss.la ../libicalvcal/libicalvcal.la $(cxx_libs) ../libical/libical.la $(bdb4_libs)
+INCLUDES = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/src \
+ -I$(top_builddir)/src \
+ -I$(top_srcdir)/src/libical \
+ -I$(top_builddir)/src/libical \
+ -I$(top_builddir)/src/libicalss \
+ -I$(top_srcdir)/src/libicalss \
+ -DTEST_DATADIR=\"$(top_srcdir)/test-data\" \
+ $(cxx_inc) $(bdb4_inc)
+
+parser_SOURCES = icaltestparser.c
+
+# clusterin.vcd should be a real file with data but it doesn't seem to be in cvs
+CLEANFILES = \
+ test_fileset.ics \
+ test_fileset_locktest.ics \
+ filesetout.ics \
+ clusterin.vcd
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .cpp .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/test/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/test/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+copycluster$(EXEEXT): $(copycluster_OBJECTS) $(copycluster_DEPENDENCIES) $(EXTRA_copycluster_DEPENDENCIES)
+ @rm -f copycluster$(EXEEXT)
+ $(LINK) $(copycluster_OBJECTS) $(copycluster_LDADD) $(LIBS)
+parser$(EXEEXT): $(parser_OBJECTS) $(parser_DEPENDENCIES) $(EXTRA_parser_DEPENDENCIES)
+ @rm -f parser$(EXEEXT)
+ $(LINK) $(parser_OBJECTS) $(parser_LDADD) $(LIBS)
+process$(EXEEXT): $(process_OBJECTS) $(process_DEPENDENCIES) $(EXTRA_process_DEPENDENCIES)
+ @rm -f process$(EXEEXT)
+ $(LINK) $(process_OBJECTS) $(process_LDADD) $(LIBS)
+recur$(EXEEXT): $(recur_OBJECTS) $(recur_DEPENDENCIES) $(EXTRA_recur_DEPENDENCIES)
+ @rm -f recur$(EXEEXT)
+ $(LINK) $(recur_OBJECTS) $(recur_LDADD) $(LIBS)
+regression$(EXEEXT): $(regression_OBJECTS) $(regression_DEPENDENCIES) $(EXTRA_regression_DEPENDENCIES)
+ @rm -f regression$(EXEEXT)
+ $(CXXLINK) $(regression_OBJECTS) $(regression_LDADD) $(LIBS)
+stow$(EXEEXT): $(stow_OBJECTS) $(stow_DEPENDENCIES) $(EXTRA_stow_DEPENDENCIES)
+ @rm -f stow$(EXEEXT)
+ $(LINK) $(stow_OBJECTS) $(stow_LDADD) $(LIBS)
+testmime$(EXEEXT): $(testmime_OBJECTS) $(testmime_DEPENDENCIES) $(EXTRA_testmime_DEPENDENCIES)
+ @rm -f testmime$(EXEEXT)
+ $(LINK) $(testmime_OBJECTS) $(testmime_LDADD) $(LIBS)
+testvcal$(EXEEXT): $(testvcal_OBJECTS) $(testvcal_DEPENDENCIES) $(EXTRA_testvcal_DEPENDENCIES)
+ @rm -f testvcal$(EXEEXT)
+ $(LINK) $(testvcal_OBJECTS) $(testvcal_LDADD) $(LIBS)
+timezones$(EXEEXT): $(timezones_OBJECTS) $(timezones_DEPENDENCIES) $(EXTRA_timezones_DEPENDENCIES)
+ @rm -f timezones$(EXEEXT)
+ $(LINK) $(timezones_OBJECTS) $(timezones_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/copycluster.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icaltestparser.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/recur.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regression-classify.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regression-component.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regression-cxx.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regression-recur.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regression-storage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regression-utils.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regression.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stow.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testmime.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testvcal.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timezones.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+cscopelist: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ fi; \
+ echo "$${col}$$dashes$${std}"; \
+ echo "$${col}$$banner$${std}"; \
+ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+ test -z "$$report" || echo "$${col}$$report$${std}"; \
+ echo "$${col}$$dashes$${std}"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool clean-local \
+ mostlyclean-am
+
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
+ clean-checkPROGRAMS clean-generic clean-libtool clean-local \
+ cscopelist ctags distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am
+
+
+clean-local:
+ rm -rf calendar
+
+distclean: clean
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/test/copycluster.c b/src/test/copycluster.c
new file mode 100644
index 00000000..b7ef03ea
--- /dev/null
+++ b/src/test/copycluster.c
@@ -0,0 +1,150 @@
+/* -*- Mode: C -*-
+ ======================================================================
+ FILE: copycluster.c
+ CREATOR: eric 15 January 2000
+
+ $Id: copycluster.c,v 1.18 2008-02-03 16:10:46 dothebart Exp $
+ $Locker: $
+
+ (C) COPYRIGHT 2000 Eric Busboom
+ http://www.softwarestudio.org
+
+ The contents of this file are subject to the Mozilla Public License
+ Version 1.0 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and
+ limitations under the License.
+
+ The Original Code is eric. The Initial Developer of the Original
+ Code is Eric Busboom
+
+
+ ======================================================================*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h> /* for printf */
+#include <errno.h>
+#include <string.h> /* For strerror */
+#include <signal.h> /* for signal */
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h> /* for alarm */
+#endif
+#include <stdlib.h> /* for exit */
+
+#include <libical/ical.h>
+#include <libicalss/icalss.h>
+
+#ifdef SIGALRM
+
+static void sig_alrm(int i){
+ fprintf(stderr,"Could not get lock on file\n");
+ exit(1);
+}
+
+#endif
+
+/* This program copies a file that holds iCal components to an other file. */
+
+
+void usage(char* arg0) {
+ printf("usage: %s cluster-file1 cluster-file2\n",arg0);
+}
+
+int main(int c, char *argv[]){
+
+ icalset *clusterin, *clusterout = NULL;
+ icalcomponent *itr;
+ int count=0;
+ int tostdout = 0;
+
+ if(c < 2 || c > 3){
+ usage(argv[0]);
+ exit(1);
+ }
+
+ if (c == 2){
+ tostdout = 1;
+ }
+
+
+ /*icalerror_set_error_state(ICAL_PARSE_ERROR, ICAL_ERROR_NONFATAL);*/
+
+#ifdef SIGALRM
+ signal(SIGALRM,sig_alrm);
+ alarm(10);
+#endif
+ clusterin = icalfileset_new(argv[1]);
+#ifdef SIGALRM
+ alarm(0);
+#endif
+ if (clusterin == 0){
+ printf("Could not open input cluster \"%s\"\n",argv[1]);
+ if(icalerrno!= ICAL_NO_ERROR){
+ printf("Error: %s\n",icalerror_strerror(icalerrno));
+ }
+ exit(1);
+ }
+
+ if (!tostdout){
+#ifdef SIGALRM
+ alarm(10);
+#endif
+ clusterout = icalfileset_new(argv[2]);
+#ifdef SIGALRM
+ alarm(0);
+#endif
+ if (clusterout == 0){
+ printf("Could not open output cluster \"%s\"\n",argv[2]);
+ exit(1);
+ }
+ }
+
+
+ for (itr = icalset_get_first_component(clusterin);
+ 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,
+ icalcomponent_new_clone(itr));
+ }
+
+ count++;
+
+ } else {
+ printf("Got NULL component");
+ }
+ }
+
+
+ printf("Transfered %d components\n",count);
+
+ icalset_free(clusterin);
+
+ if (!tostdout){
+ icalfileset_mark(clusterout);
+ icalset_free(clusterout);
+ }
+
+ return 0;
+}
+
+
diff --git a/src/test/findobj.c b/src/test/findobj.c
new file mode 100644
index 00000000..99188c49
--- /dev/null
+++ b/src/test/findobj.c
@@ -0,0 +1,71 @@
+/* -*- Mode: C -*-
+ ======================================================================
+ FILE: findobj.c
+ CREATOR: eric 11 February 2000
+
+ $Id: findobj.c,v 1.3 2008-01-02 20:07:45 dothebart Exp $
+ $Locker: $
+
+ (C) COPYRIGHT 2000 Eric Busboom
+ http://www.softwarestudio.org
+
+ The contents of this file are subject to the Mozilla Public License
+ Version 1.0 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and
+ limitations under the License.
+
+ The Original Code is eric. The Initial Developer of the Original
+ Code is Eric Busboom
+
+
+ ======================================================================*/
+
+#include <stdio.h> /* for printf */
+#include <errno.h>
+#include <string.h> /* For strerror */
+
+#include <libical/ical.h>
+#include <libicalss/icalss.h>
+
+/* This program finds an object stored in a calendar */
+
+void usage(char* arg0) {
+ printf("usage: %s calendar-dir uid\n",arg0);
+}
+
+int main(int c, char *argv[]){
+
+ icalcalendar *cal;
+ icaldirset *booked;
+ icalcomponent *itr;
+
+ if(c < 2 || c > 3){
+ usage(argv[0]);
+ exit(1);
+ }
+
+ cal = icalcalendar_new(argv[1]);
+
+ if(cal == 0){
+ fprintf(stderr,"%s: error in opening calendar \"%s\": %s. errno is \"%s\"\n",
+ argv[0],argv[1],icalerror_strerror(icalerrno),
+ strerror(errno));
+ }
+
+ booked = icalcalendar_get_booked(cal);
+
+ itr = icaldirset_fetch(booked,argv[2]);
+
+
+ if(itr != 0){
+ printf("%s",icalcomponent_as_ical_string(itr));
+ }
+
+ return 0;
+}
+
diff --git a/src/test/icaltestparser.c b/src/test/icaltestparser.c
new file mode 100644
index 00000000..017d4ffd
--- /dev/null
+++ b/src/test/icaltestparser.c
@@ -0,0 +1,122 @@
+/* -*- Mode: C -*-
+ ======================================================================
+ FILE: icaltestparser.c
+ CREATOR: eric 20 June 1999
+
+ $Id: icaltestparser.c,v 1.4 2008-01-02 20:07:45 dothebart Exp $
+ $Locker: $
+
+ The contents of this file are subject to the Mozilla Public License
+ Version 1.0 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and
+ limitations under the License.
+
+ The original author is Eric Busboom
+ The original code is icaltestparser.c
+
+
+ (C) COPYRIGHT 1999 The Software Studio.
+ http://www.softwarestudio.org
+
+ ======================================================================*/
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <libical/ical.h>
+
+#include <stdlib.h>
+
+char str[] = "BEGIN:VCALENDAR\
+PRODID:\"-//RDU Software//NONSGML HandCal//EN\"\
+VERSION:2.0\
+BEGIN:VTIMEZONE\
+TZID:US-Eastern\
+BEGIN:STANDARD\
+DTSTART:19990404T020000\
+RDATE:19990u404xT020000\
+TZOFFSETFROM:-0500\
+TZOFFSETTO:-0400\
+END:STANDARD\
+BEGIN:DAYLIGHT\
+DTSTART:19990404T020000\
+RDATE:19990404T020000\
+TZOFFSETFROM:-0500\
+TZOFFSETTO:-0400\
+TZNAME:EDT\
+Dkjhgri:derhvnv;\
+BEGIN:dfkjh\
+END:dfdfkjh\
+END:DAYLIGHT\
+END:VTIMEZONE\
+BEGIN:VEVENT\
+GEO:Bongo\
+DTSTAMP:19980309T231000Z\
+UID:guid-1.host1.com\
+ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com\
+ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP\
+ :MAILTO:employee-A@host.com\
+DESCRIPTION:Project XYZ Review Meeting\
+CATEGORIES:MEETING\
+CLASS:PUBLIC\
+CREATED:19980309T130000Z\
+SUMMARY:XYZ Project Review\
+DTSTART;TZID=US-Eastern:19980312T083000\
+DTEND;TZID=US-Eastern:19980312T093000\
+LOCATION:1CP Conference Room 4350\
+END:VEVENT\
+END:VCALENDAR\
+";
+
+extern int yydebug;
+
+/* Have the parser fetch data from stdin */
+
+char* read_stream(char *s, size_t size, void *d)
+{
+ char *c = fgets(s,size, (FILE*)d);
+
+ return c;
+
+}
+
+
+
+int main(int argc, char* argv[])
+{
+
+ char* line;
+ FILE* stream;
+ icalcomponent *c;
+ icalparser *parser = icalparser_new();
+
+ stream = fopen(argv[1],"r");
+
+ assert(stream != 0);
+
+ icalparser_set_gen_data(parser,stream);
+
+ do{
+
+ line = icalparser_get_line(parser,read_stream);
+
+ c = icalparser_add_line(parser,line);
+
+
+ if (c != 0){
+ /*icalcomponent_convert_errors(c);*/
+ printf("%s",icalcomponent_as_ical_string(c));
+ printf("\n---------------\n");
+ icalcomponent_free(c);
+ }
+
+ } while ( line != 0);
+
+ return 0;
+ }
diff --git a/src/test/itip.ics b/src/test/itip.ics
new file mode 100644
index 00000000..9a71660a
--- /dev/null
+++ b/src/test/itip.ics
@@ -0,0 +1,14 @@
+
+BEGIN:VCALENDAR
+METHOD:REPLY
+PRODID:-//ACME/DesktopCalendar//EN
+VERSION:2.0
+BEGIN:VEVENT
+ORGANIZER:mailto:a@example.com
+ATTENDEE:mailto:eric@agony.busboom.org
+DTSTART:19970701T200000Z
+DTSTAMP:19970611T190000Z
+SUMMARY:ST. PAUL SAINTS -VS- DULUTH-SUPERIOR DUKES
+UID:0981234-1234234-23@example.com
+END:VEVENT
+END:VCALENDAR
diff --git a/src/test/outgoing.ics b/src/test/outgoing.ics
new file mode 100644
index 00000000..9f9fd3fd
--- /dev/null
+++ b/src/test/outgoing.ics
@@ -0,0 +1,544 @@
+BEGIN:VCALENDAR
+METHOD
+ :REPLY
+VERSION
+ :2.0
+PRODID
+ :-//SoftwareStudio//NONSGML libical 0.21 //EN
+BEGIN:VEVENT
+DTSTAMP
+ :20001121T170735Z
+UID
+ :calsrv.example.com-873970198738703@example.com
+ORGANIZER
+ :Mailto:bob@cal.softwarestudio.org
+SUMMARY
+ : Overlap 1
+SEQUENCE
+ :0
+COMMENT
+ :I can make it to this meeting
+ATTENDEE
+ ;ROLE=CHAIR
+ ;CUTYPE=INDIVIDUAL
+ ;CN=Alice
+ ;PARTSTAT=ACCEPTED
+ :Mailto:alice@cal.softwarestudio.org
+END:VEVENT
+END:VCALENDAR
+BEGIN:VCALENDAR
+METHOD
+ :REPLY
+VERSION
+ :2.0
+PRODID
+ :-//SoftwareStudio//NONSGML libical 0.21 //EN
+BEGIN:VEVENT
+DTSTAMP
+ :20001121T170735Z
+UID
+ :calsrv.example.com-873970198738704@example.com
+ORGANIZER
+ :Mailto:bob@cal.softwarestudio.org
+SUMMARY
+ :Overlap 2
+SEQUENCE
+ :0
+COMMENT
+ :I can make it to this meeting
+ATTENDEE
+ ;ROLE=CHAIR
+ ;CUTYPE=INDIVIDUAL
+ ;CN=Alice
+ ;PARTSTAT=ACCEPTED
+ :Mailto:alice@cal.softwarestudio.org
+END:VEVENT
+END:VCALENDAR
+BEGIN:VCALENDAR
+METHOD
+ :REPLY
+VERSION
+ :2.0
+PRODID
+ :-//SoftwareStudio//NONSGML libical 0.21 //EN
+BEGIN:VEVENT
+DTSTAMP
+ :20001121T170735Z
+UID
+ :calsrv.example.com-873970198738705@example.com
+ORGANIZER
+ :Mailto:bob@cal.softwarestudio.org
+SUMMARY
+ :Overlap 3
+SEQUENCE
+ :0
+COMMENT
+ :I can make it to this meeting
+ATTENDEE
+ ;ROLE=CHAIR
+ ;CUTYPE=INDIVIDUAL
+ ;CN=Alice
+ ;PARTSTAT=ACCEPTED
+ :Mailto:alice@cal.softwarestudio.org
+END:VEVENT
+END:VCALENDAR
+BEGIN:VCALENDAR
+METHOD
+ :REPLY
+VERSION
+ :2.0
+PRODID
+ :-//SoftwareStudio//NONSGML libical 0.21 //EN
+BEGIN:VEVENT
+DTSTAMP
+ :20001121T170953Z
+UID
+ :calsrv.example.com-873970198738703@example.com
+ORGANIZER
+ :Mailto:bob@cal.softwarestudio.org
+SUMMARY
+ : Overlap 1
+SEQUENCE
+ :0
+COMMENT
+ :I can make it to this meeting
+ATTENDEE
+ ;ROLE=CHAIR
+ ;CUTYPE=INDIVIDUAL
+ ;CN=Alice
+ ;PARTSTAT=ACCEPTED
+ :Mailto:alice@cal.softwarestudio.org
+END:VEVENT
+END:VCALENDAR
+BEGIN:VCALENDAR
+METHOD
+ :REPLY
+VERSION
+ :2.0
+PRODID
+ :-//SoftwareStudio//NONSGML libical 0.21 //EN
+BEGIN:VEVENT
+DTSTAMP
+ :20001121T170953Z
+UID
+ :calsrv.example.com-873970198738704@example.com
+ORGANIZER
+ :Mailto:bob@cal.softwarestudio.org
+SUMMARY
+ :Overlap 2
+SEQUENCE
+ :0
+COMMENT
+ :I can make it to this meeting
+ATTENDEE
+ ;ROLE=CHAIR
+ ;CUTYPE=INDIVIDUAL
+ ;CN=Alice
+ ;PARTSTAT=ACCEPTED
+ :Mailto:alice@cal.softwarestudio.org
+END:VEVENT
+END:VCALENDAR
+BEGIN:VCALENDAR
+METHOD
+ :REPLY
+VERSION
+ :2.0
+PRODID
+ :-//SoftwareStudio//NONSGML libical 0.21 //EN
+BEGIN:VEVENT
+DTSTAMP
+ :20001121T170953Z
+UID
+ :calsrv.example.com-873970198738705@example.com
+ORGANIZER
+ :Mailto:bob@cal.softwarestudio.org
+SUMMARY
+ :Overlap 3
+SEQUENCE
+ :0
+COMMENT
+ :I can make it to this meeting
+ATTENDEE
+ ;ROLE=CHAIR
+ ;CUTYPE=INDIVIDUAL
+ ;CN=Alice
+ ;PARTSTAT=ACCEPTED
+ :Mailto:alice@cal.softwarestudio.org
+END:VEVENT
+END:VCALENDAR
+BEGIN:VCALENDAR
+METHOD
+ :REPLY
+VERSION
+ :2.0
+PRODID
+ :-//SoftwareStudio//NONSGML libical 0.21 //EN
+BEGIN:VEVENT
+DTSTAMP
+ :20001121T171147Z
+UID
+ :calsrv.example.com-873970198738703@example.com
+ORGANIZER
+ :Mailto:bob@cal.softwarestudio.org
+SUMMARY
+ : Overlap 1
+SEQUENCE
+ :0
+COMMENT
+ :Unfortunately\, I have another commitment that conflicts with this
+ meeting. I am delegating my attendance to Bob.
+ATTENDEE
+ ;ROLE=CHAIR
+ ;CUTYPE=INDIVIDUAL
+ ;CN=Alice
+ ;PARTSTAT=DELEGATED
+ ;DELEGATED-TO=bob@cal.softwarestudio.org
+ :Mailto:alice@cal.softwarestudio.org
+END:VEVENT
+END:VCALENDAR
+BEGIN:VCALENDAR
+X-LIC-NOTE
+ : Overlap with Slot 2\, 1300 to 1400\, should be counterproposed
+METHOD
+ :REQUEST
+VERSION
+ :2.0
+BEGIN:VEVENT
+ORGANIZER
+ :Mailto:bob@cal.softwarestudio.org
+ATTENDEE
+ ;ROLE=CHAIR
+ ;CUTYPE=INDIVIDUAL
+ ;CN=Alice
+ :Mailto:alice@cal.softwarestudio.org
+ATTENDEE
+ ;RSVP=TRUE
+ ;CUTYPE=INDIVIDUAL
+ ;CN=B
+ :Mailto:B@example.com
+DTSTAMP
+ :19970611T040000Z
+DTSTART
+ :19970701T070000
+DTEND
+ :19970701T080000
+SUMMARY
+ :Overlap 2
+UID
+ :calsrv.example.com-873970198738704@example.com
+SEQUENCE
+ :0
+STATUS
+ :CONFIRMED
+END:VEVENT
+END:VCALENDAR
+BEGIN:VCALENDAR
+METHOD
+ :REPLY
+VERSION
+ :2.0
+PRODID
+ :-//SoftwareStudio//NONSGML libical 0.21 //EN
+BEGIN:VEVENT
+DTSTAMP
+ :20001121T171147Z
+UID
+ :calsrv.example.com-873970198738705@example.com
+ORGANIZER
+ :Mailto:bob@cal.softwarestudio.org
+SUMMARY
+ :Overlap 3
+SEQUENCE
+ :0
+COMMENT
+ :I can't make it to this meeting
+ATTENDEE
+ ;ROLE=CHAIR
+ ;CUTYPE=INDIVIDUAL
+ ;CN=Alice
+ ;PARTSTAT=DECLINED
+ :Mailto:alice@cal.softwarestudio.org
+END:VEVENT
+END:VCALENDAR
+BEGIN:VCALENDAR
+METHOD
+ :REPLY
+VERSION
+ :2.0
+PRODID
+ :-//SoftwareStudio//NONSGML libical 0.21 //EN
+BEGIN:VEVENT
+DTSTAMP
+ :20001121T171154Z
+UID
+ :calsrv.example.com-873970198738703@example.com
+ORGANIZER
+ :Mailto:bob@cal.softwarestudio.org
+SUMMARY
+ : Overlap 1
+SEQUENCE
+ :0
+COMMENT
+ :Unfortunately\, I have another commitment that conflicts with this
+ meeting. I am delegating my attendance to Bob.
+ATTENDEE
+ ;ROLE=CHAIR
+ ;CUTYPE=INDIVIDUAL
+ ;CN=Alice
+ ;PARTSTAT=DELEGATED
+ ;DELEGATED-TO=bob@cal.softwarestudio.org
+ :Mailto:alice@cal.softwarestudio.org
+END:VEVENT
+END:VCALENDAR
+BEGIN:VCALENDAR
+X-LIC-NOTE
+ : Overlap with Slot 2\, 1300 to 1400\, should be counterproposed
+METHOD
+ :REQUEST
+VERSION
+ :2.0
+BEGIN:VEVENT
+ORGANIZER
+ :Mailto:bob@cal.softwarestudio.org
+ATTENDEE
+ ;ROLE=CHAIR
+ ;CUTYPE=INDIVIDUAL
+ ;CN=Alice
+ :Mailto:alice@cal.softwarestudio.org
+ATTENDEE
+ ;RSVP=TRUE
+ ;CUTYPE=INDIVIDUAL
+ ;CN=B
+ :Mailto:B@example.com
+DTSTAMP
+ :19970611T040000Z
+DTSTART
+ :19970701T070000
+DTEND
+ :19970701T080000
+SUMMARY
+ :Overlap 2
+UID
+ :calsrv.example.com-873970198738704@example.com
+SEQUENCE
+ :0
+STATUS
+ :CONFIRMED
+END:VEVENT
+END:VCALENDAR
+BEGIN:VCALENDAR
+METHOD
+ :REPLY
+VERSION
+ :2.0
+PRODID
+ :-//SoftwareStudio//NONSGML libical 0.21 //EN
+BEGIN:VEVENT
+DTSTAMP
+ :20001121T171154Z
+UID
+ :calsrv.example.com-873970198738705@example.com
+ORGANIZER
+ :Mailto:bob@cal.softwarestudio.org
+SUMMARY
+ :Overlap 3
+SEQUENCE
+ :0
+COMMENT
+ :I can't make it to this meeting
+ATTENDEE
+ ;ROLE=CHAIR
+ ;CUTYPE=INDIVIDUAL
+ ;CN=Alice
+ ;PARTSTAT=DECLINED
+ :Mailto:alice@cal.softwarestudio.org
+END:VEVENT
+END:VCALENDAR
+BEGIN:VCALENDAR
+METHOD
+ :REPLY
+VERSION
+ :2.0
+PRODID
+ :-//SoftwareStudio//NONSGML libical 0.21 //EN
+BEGIN:VEVENT
+DTSTAMP
+ :20001121T144324Z
+UID
+ :calsrv.example.com-873970198738703@example.com
+ORGANIZER
+ :Mailto:bob@cal.softwarestudio.org
+SUMMARY
+ : Overlap 1
+SEQUENCE
+ :0
+COMMENT
+ :Unfortunately\, I have another commitment that conflicts with this
+ meeting. I am delegating my attendance to Bob.
+ATTENDEE
+ ;ROLE=CHAIR
+ ;CUTYPE=INDIVIDUAL
+ ;CN=Alice
+ ;PARTSTAT=DELEGATED
+ ;DELEGATED-TO=bob@cal.softwarestudio.org
+ :Mailto:alice@cal.softwarestudio.org
+END:VEVENT
+END:VCALENDAR
+BEGIN:VCALENDAR
+X-LIC-NOTE
+ : Overlap with Slot 2\, 1300 to 1400\, should be counterproposed
+METHOD
+ :REQUEST
+VERSION
+ :2.0
+BEGIN:VEVENT
+ORGANIZER
+ :Mailto:bob@cal.softwarestudio.org
+ATTENDEE
+ ;ROLE=CHAIR
+ ;CUTYPE=INDIVIDUAL
+ ;CN=Alice
+ :Mailto:alice@cal.softwarestudio.org
+ATTENDEE
+ ;RSVP=TRUE
+ ;CUTYPE=INDIVIDUAL
+ ;CN=B
+ :Mailto:B@example.com
+DTSTAMP
+ :19970611T040000Z
+DTSTART
+ :19970701T230000
+DTEND
+ :19970702T000000
+SUMMARY
+ :Overlap 2
+UID
+ :calsrv.example.com-873970198738704@example.com
+SEQUENCE
+ :0
+STATUS
+ :CONFIRMED
+END:VEVENT
+END:VCALENDAR
+BEGIN:VCALENDAR
+METHOD
+ :REPLY
+VERSION
+ :2.0
+PRODID
+ :-//SoftwareStudio//NONSGML libical 0.21 //EN
+BEGIN:VEVENT
+DTSTAMP
+ :20001121T144324Z
+UID
+ :calsrv.example.com-873970198738705@example.com
+ORGANIZER
+ :Mailto:bob@cal.softwarestudio.org
+SUMMARY
+ :Overlap 3
+SEQUENCE
+ :0
+COMMENT
+ :I can't make it to this meeting
+ATTENDEE
+ ;ROLE=CHAIR
+ ;CUTYPE=INDIVIDUAL
+ ;CN=Alice
+ ;PARTSTAT=DECLINED
+ :Mailto:alice@cal.softwarestudio.org
+END:VEVENT
+END:VCALENDAR
+BEGIN:VCALENDAR
+METHOD
+ :REPLY
+VERSION
+ :2.0
+PRODID
+ :-//SoftwareStudio//NONSGML libical 0.21 //EN
+BEGIN:VEVENT
+DTSTAMP
+ :20001121T144412Z
+UID
+ :calsrv.example.com-873970198738703@example.com
+ORGANIZER
+ :Mailto:bob@cal.softwarestudio.org
+SUMMARY
+ : Overlap 1
+SEQUENCE
+ :0
+COMMENT
+ :Unfortunately\, I have another commitment that conflicts with this
+ meeting. I am delegating my attendance to Bob.
+ATTENDEE
+ ;ROLE=CHAIR
+ ;CUTYPE=INDIVIDUAL
+ ;CN=Alice
+ ;PARTSTAT=DELEGATED
+ ;DELEGATED-TO=bob@cal.softwarestudio.org
+ :Mailto:alice@cal.softwarestudio.org
+END:VEVENT
+END:VCALENDAR
+BEGIN:VCALENDAR
+X-LIC-NOTE
+ : Overlap with Slot 2\, 1300 to 1400\, should be counterproposed
+METHOD
+ :REQUEST
+VERSION
+ :2.0
+BEGIN:VEVENT
+ORGANIZER
+ :Mailto:bob@cal.softwarestudio.org
+ATTENDEE
+ ;ROLE=CHAIR
+ ;CUTYPE=INDIVIDUAL
+ ;CN=Alice
+ :Mailto:alice@cal.softwarestudio.org
+ATTENDEE
+ ;RSVP=TRUE
+ ;CUTYPE=INDIVIDUAL
+ ;CN=B
+ :Mailto:B@example.com
+DTSTAMP
+ :19970611T040000Z
+DTSTART
+ :19970701T230000
+DTEND
+ :19970702T000000
+SUMMARY
+ :Overlap 2
+UID
+ :calsrv.example.com-873970198738704@example.com
+SEQUENCE
+ :0
+STATUS
+ :CONFIRMED
+END:VEVENT
+END:VCALENDAR
+BEGIN:VCALENDAR
+METHOD
+ :REPLY
+VERSION
+ :2.0
+PRODID
+ :-//SoftwareStudio//NONSGML libical 0.21 //EN
+BEGIN:VEVENT
+DTSTAMP
+ :20001121T144412Z
+UID
+ :calsrv.example.com-873970198738705@example.com
+ORGANIZER
+ :Mailto:bob@cal.softwarestudio.org
+SUMMARY
+ :Overlap 3
+SEQUENCE
+ :0
+COMMENT
+ :I can't make it to this meeting
+ATTENDEE
+ ;ROLE=CHAIR
+ ;CUTYPE=INDIVIDUAL
+ ;CN=Alice
+ ;PARTSTAT=DECLINED
+ :Mailto:alice@cal.softwarestudio.org
+END:VEVENT
+END:VCALENDAR
diff --git a/src/test/process.c b/src/test/process.c
new file mode 100644
index 00000000..6bd84bdd
--- /dev/null
+++ b/src/test/process.c
@@ -0,0 +1,416 @@
+/* -*- Mode: C -*-
+ ======================================================================
+ FILE: process.c
+ CREATOR: eric 11 February 2000
+
+ $Id: process.c,v 1.10 2008-02-03 16:10:46 dothebart Exp $
+ $Locker: $
+
+ (C) COPYRIGHT 2000 Eric Busboom
+ http://www.softwarestudio.org
+
+ The contents of this file are subject to the Mozilla Public License
+ Version 1.0 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and
+ limitations under the License.
+
+ ======================================================================*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h> /* for printf */
+#include <errno.h>
+#include <string.h> /* For strerror */
+#include <stdlib.h> /* for free */
+
+#if defined(_MSC_VER)
+#define snprintf _snprintf
+#endif
+
+#include <libical/ical.h>
+#include <libicalss/icalss.h>
+
+void send_message(icalcomponent *reply,const char* this_user)
+{
+ printf("From: %s\n\n%s\n",this_user,icalcomponent_as_ical_string(reply));
+
+
+}
+
+
+int main(int argc, char* argv[])
+{
+ icalcomponent *c, *next_c = NULL;
+ int i=0;
+ const char *class_string;
+ int dont_remove;
+ icalfileset_options options = {O_RDONLY, 0644, 0};
+
+ icalset* f = icalset_new(ICAL_FILE_SET, TEST_DATADIR "/process-incoming.ics", &options);
+ icalset* trash = icalset_new_file("trash.ics");
+ icalset* cal = icalset_new(ICAL_FILE_SET, TEST_DATADIR "/process-calendar.ics", &options);
+ icalset* out = icalset_new_file("outgoing.ics");
+
+ const char* this_user = "alice@cal.softwarestudio.org";
+
+ assert(f!= 0);
+ assert(cal!=0);
+ assert(trash!=0);
+ assert(out!=0);
+
+
+ /* Foreach incoming message */
+ for(c=icalset_get_first_component(f);c!=0;c = next_c){
+
+ icalproperty_xlicclass class;
+ icalcomponent *match;
+ icalcomponent *inner;
+ icalcomponent *reply = 0;
+
+ assert(c!=0);
+
+ inner = icalcomponent_get_first_real_component(c);
+
+ i++;
+ reply = 0;
+ dont_remove = 0;
+
+ if(inner == 0){
+ printf("Bad component, no inner\n %s\n",
+ icalcomponent_as_ical_string(c));
+ continue;
+ }
+
+ /* Find a booked component that is matched to the incoming
+ message, based on the incoming component's UID, SEQUENCE
+ and RECURRENCE-ID*/
+
+ match = icalset_fetch_match(cal,c);
+
+ class = icalclassify(c,match,this_user);
+
+ class_string = icalproperty_enum_to_string(class);
+
+ /* Print out the notes associated with the incoming component
+ and the matched component in the */
+ {
+ const char *c_note=0;
+ const char *m_note=0;
+ icalproperty *p;
+
+ for(p = icalcomponent_get_first_property(c,ICAL_X_PROPERTY);
+ p!= 0;
+ p = icalcomponent_get_next_property(c,ICAL_X_PROPERTY)){
+
+ if(strcmp(icalproperty_get_x_name(p),"X-LIC-NOTE")==0){
+ c_note = icalproperty_get_x(p);
+ }
+ }
+
+ if (match != 0){
+ for(p = icalcomponent_get_first_property(match,
+ ICAL_X_PROPERTY);
+ p!= 0;
+ p = icalcomponent_get_next_property(match,
+ ICAL_X_PROPERTY)){
+ if(strcmp(icalproperty_get_x_name(p),"X-LIC-NOTE")==0){
+ m_note = icalproperty_get_x(p);
+ }
+ }
+ }
+
+ if(c_note != 0){
+ printf("Incoming: %s\n",c_note);
+ }
+ if(m_note != 0){
+ printf("Match : %s\n",m_note);
+ }
+ }
+
+ /* Main processing structure */
+
+ switch (class){
+ case ICAL_XLICCLASS_NONE: {
+ char temp[1024];
+ /* Huh? Return an error to sender */
+ icalrestriction_check(c);
+ icalcomponent_convert_errors(c);
+
+ snprintf(temp,1024,"I can't understand the component you sent. \n Here is the component you sent, possibly with error messages:\n %s",icalcomponent_as_ical_string(c));
+
+ reply = icalmessage_new_error_reply(
+ c,
+ this_user,
+ temp,
+ "",
+ ICAL_UNKNOWN_STATUS
+ );
+
+
+
+ break;
+ }
+ case ICAL_XLICCLASS_PUBLISHNEW: {
+
+ /* Don't accept published events from anyone but
+ self. If self, fall through to ICAL_XLICCLASS_REQUESTNEW */
+
+
+
+ }
+ case ICAL_XLICCLASS_REQUESTNEW: {
+
+ /* Book the new component if it does not overlap
+ anything. If the time is busy and the start time is
+ an even modulo 4, delegate to
+ bob@cal.softwarestudio.org. If the time is busy and
+ is 1 modulo 4, counterpropose for the first
+ available free time. Otherwise, deline the meeting */
+
+ icalcomponent *overlaps;
+ overlaps = icalclassify_find_overlaps(cal,c);
+
+ if(overlaps == 0){
+ /* No overlaps, book the meeting */
+/* icalset_add_component(cal,icalcomponent_new_clone(c));*/
+
+ /* Return a reply */
+ reply = icalmessage_new_accept_reply(c,this_user,
+ "I can make it to this meeting");
+
+ icalset_add_component(out,reply);
+
+ } else {
+ /* There was a conflict, so delegate, counterpropose
+ or decline it */
+ struct icaltimetype dtstart
+ = icalcomponent_get_dtstart(c);
+
+ if(dtstart.hour%4 == 0){
+ /* Delegate the meeting */
+ reply = icalmessage_new_delegate_reply(c,
+ this_user,
+ "bob@cal.softwarestudio.org",
+ "Unfortunately, I have another commitment that \
+conflicts with this meeting. I am delegating my attendance to Bob. ");
+
+ icalset_add_component(out,reply);
+
+ } else if (dtstart.hour%4 == 1) {
+ /* Counter propose to next available time */
+ icalcomponent *newc;
+ struct icalperiodtype next_time;
+
+ icalspanlist *spanl =
+ icalspanlist_new(cal,dtstart,
+ icaltime_null_time());
+
+ next_time = icalspanlist_next_free_time(
+ spanl,icalcomponent_get_dtstart(c));
+
+ newc = icalcomponent_new_clone(c);
+
+ icalcomponent_set_dtstart(newc,next_time.start);
+
+
+ /* Hack, the duration of the counterproposed
+ meeting may be longer than the free time
+ available */
+ icalcomponent_set_duration(newc,
+ icalcomponent_get_duration(c));
+
+ reply = icalmessage_new_counterpropose_reply(c,
+ newc,
+ this_user,
+ "Unfortunately, I have another commitment that \
+conflicts with this meeting. I am proposing a time that works better for me.");
+
+ icalset_add_component(out,reply);
+
+ } else {
+ /* Decline the meeting */
+
+ reply = icalmessage_new_decline_reply(c,
+ this_user,
+ "I can't make it to this meeting");
+
+ icalset_add_component(out,reply);
+
+ }
+
+
+ }
+ break;
+ }
+ case ICAL_XLICCLASS_PUBLISHFREEBUSY: {
+ /* Store the busy time information in a file named after
+ the sender */
+ break;
+ }
+
+ case ICAL_XLICCLASS_PUBLISHUPDATE: {
+ /* Only accept publish updates from self. If self, fall
+ throught to ICAL_XLICCLASS_REQUESTUPDATE */
+ }
+
+ case ICAL_XLICCLASS_REQUESTUPDATE: {
+ /* always accept the changes */
+ break;
+ }
+
+ case ICAL_XLICCLASS_REQUESTRESCHEDULE: {
+ /* Use same rules as REQUEST_NEW */
+ icalcomponent *overlaps;
+ overlaps = icalclassify_find_overlaps(cal,c);
+
+ break;
+ }
+ case ICAL_XLICCLASS_REQUESTDELEGATE: {
+
+ break;
+ }
+ case ICAL_XLICCLASS_REQUESTNEWORGANIZER: {
+ break;
+ }
+ case ICAL_XLICCLASS_REQUESTFORWARD: {
+ break;
+ }
+ case ICAL_XLICCLASS_REQUESTSTATUS: {
+ break;
+ }
+
+ case ICAL_XLICCLASS_REQUESTFREEBUSY: {
+ break;
+ }
+ case ICAL_XLICCLASS_REPLYACCEPT: {
+ /* Change the PARTSTAT of the sender */
+ break;
+ }
+ case ICAL_XLICCLASS_REPLYDECLINE: {
+ /* Change the PARTSTAT of the sender */
+ break;
+ }
+ case ICAL_XLICCLASS_REPLYCRASHERACCEPT: {
+ /* Add the crasher to the ATTENDEE list with the
+ appropriate PARTSTAT */
+ break;
+ }
+ case ICAL_XLICCLASS_REPLYCRASHERDECLINE: {
+ /* Add the crasher to the ATTENDEE list with the
+ appropriate PARTSTAT */
+ break;
+ }
+ case ICAL_XLICCLASS_ADDINSTANCE: {
+ break;
+ }
+ case ICAL_XLICCLASS_CANCELEVENT: {
+ /* Remove the component */
+ break;
+ }
+ case ICAL_XLICCLASS_CANCELINSTANCE: {
+ break;
+ }
+ case ICAL_XLICCLASS_CANCELALL: {
+ /* Remove the component */
+ break;
+ }
+ case ICAL_XLICCLASS_REFRESH: {
+ /* Resend the latest copy of the request */
+ break;
+ }
+ case ICAL_XLICCLASS_COUNTER: {
+ break;
+ }
+ case ICAL_XLICCLASS_DECLINECOUNTER: {
+ break;
+ }
+ case ICAL_XLICCLASS_MALFORMED: {
+ /* Send back an error */
+ break;
+ }
+ case ICAL_XLICCLASS_OBSOLETE: {
+ printf(" ** Got an obsolete component:\n%s",
+ icalcomponent_as_ical_string(c));
+ /* Send back an error */
+ break;
+ }
+ case ICAL_XLICCLASS_MISSEQUENCED: {
+ printf(" ** Got a missequenced component:\n%s",
+ icalcomponent_as_ical_string(c));
+ /* Send back an error */
+ break;
+ }
+ case ICAL_XLICCLASS_UNKNOWN: {
+ printf(" ** Don't know what to do with this component:\n%s",
+ icalcomponent_as_ical_string(c));
+ /* Send back an error */
+ break;
+ }
+ case ICAL_XLICCLASS_X:
+ case ICAL_XLICCLASS_REPLYDELEGATE:
+ default: {
+ }
+ }
+
+#if(0)
+ if (reply != 0){
+
+ /* Don't send the reply if the RSVP parameter indicates not to*/
+ icalcomponent *reply_inner;
+ icalproperty *attendee;
+ icalparameter *rsvp;
+
+ reply_inner = icalcomponent_get_first_real_component(reply);
+ attendee = icalcomponent_get_first_property(reply_inner,
+ ICAL_ATTENDEE_PROPERTY);
+ rsvp = icalproperty_get_first_parameter(attendee,
+ ICAL_RSVP_PARAMETER);
+
+ if(rsvp == 0 || icalparameter_get_rsvp(rsvp) == 1){
+ icalrestriction_check(reply);
+ send_message(reply,this_user);
+ }
+
+ icalcomponent_free(reply);
+ }
+#endif
+
+ if(reply !=0){
+ printf("%s\n",icalcomponent_as_ical_string(reply));
+ }
+
+ next_c = icalset_get_next_component(f);
+
+ if(dont_remove == 0){
+ /*icalset_remove_component(f,c);
+ icalset_add_component(trash,c);*/
+ }
+ }
+
+#if (0)
+
+ for(c = icalset_get_first_component(out);
+ c!=0;
+ c = icalset_get_next_component(out)){
+
+ printf("%s",icalcomponent_as_ical_string(c));
+
+ }
+#endif
+
+ icalset_free(f);
+ icalset_free(trash);
+ icalset_free(cal);
+ icalset_free(out);
+
+ return 0;
+}
+
+
diff --git a/src/test/recur.c b/src/test/recur.c
new file mode 100644
index 00000000..bd1bf7ab
--- /dev/null
+++ b/src/test/recur.c
@@ -0,0 +1,163 @@
+/* -*- Mode: C -*-
+ ======================================================================
+ FILE: recur.c
+ CREATOR: ebusboom 8jun00
+
+ DESCRIPTION:
+
+ Test program for expanding recurrences. Run as:
+
+ ./recur ../../test-data/recur.txt
+
+
+ (C) COPYRIGHT 1999 Eric Busboom
+ http://www.softwarestudio.org
+
+ The contents of this file are subject to the Mozilla Public License
+ Version 1.0 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and
+ limitations under the License.
+
+ ======================================================================*/
+
+#include <assert.h>
+#include <string.h> /* for strdup */
+#include <stdlib.h> /* for malloc */
+#include <stdio.h> /* for printf */
+#include <time.h> /* for time() */
+#include <signal.h> /* for signal */
+#ifndef WIN32
+#include <unistd.h> /* for alarm */
+#endif
+
+#include <libical/ical.h>
+#include <libicalss/icalss.h>
+
+#ifdef WIN32
+#define snprintf _snprintf
+#endif
+#ifdef _MSC_VER
+#define strcasecmp stricmp
+#endif
+
+static void sig_alrm(int i){
+ fprintf(stderr,"Could not get lock on file\n");
+ exit(1);
+}
+
+static void recur_callback(icalcomponent *comp,
+ struct icaltime_span *span,
+ void *data)
+{
+ printf("cb: %s", ctime(&span->start));
+ printf(" %s\n", ctime(&span->end));
+
+}
+
+int main(int argc, char *argv[])
+{
+ icalset *cin;
+ struct icaltimetype next;
+ icalcomponent *itr;
+ icalproperty *desc, *dtstart, *rrule;
+ struct icalrecurrencetype recur;
+ icalrecur_iterator* ritr;
+ time_t tt;
+ char* file;
+
+ icalerror_set_error_state(ICAL_PARSE_ERROR, ICAL_ERROR_NONFATAL);
+
+#ifndef WIN32
+ signal(SIGALRM,sig_alrm);
+#endif
+
+ if (argc <= 1){
+ file = "../../test-data/recur.txt";
+ } else if (argc == 2){
+ file = argv[1];
+ } else {
+ fprintf(stderr,"usage: recur [input file]\n");
+ exit(1);
+ }
+
+#ifndef WIN32
+ alarm(300); /* to get file lock */
+#endif
+ cin = icalfileset_new(file);
+#ifndef WIN32
+ alarm(0);
+#endif
+
+ if(cin == 0){
+ fprintf(stderr,"recur: can't open file %s\n",file);
+ exit(1);
+ }
+
+
+ for (itr = icalfileset_get_first_component(cin);
+ itr != 0;
+ itr = icalfileset_get_next_component(cin)){
+
+ struct icaltimetype start = icaltime_from_timet(1,0);
+ struct icaltimetype end = icaltime_today();
+
+
+
+ desc = icalcomponent_get_first_property(itr,ICAL_DESCRIPTION_PROPERTY);
+ dtstart = icalcomponent_get_first_property(itr,ICAL_DTSTART_PROPERTY);
+ rrule = icalcomponent_get_first_property(itr,ICAL_RRULE_PROPERTY);
+
+ if (desc == 0 || dtstart == 0 || rrule == 0){
+ printf("\n******** Error in input component ********\n");
+ printf("The following component is malformed:\n %s\n",
+ icalcomponent_as_ical_string(itr));
+ continue;
+ }
+
+ printf("\n\n#### %s\n",icalproperty_get_description(desc));
+ printf("#### %s\n",icalvalue_as_ical_string(icalproperty_get_value(rrule)));
+ recur = icalproperty_get_rrule(rrule);
+ start = icalproperty_get_dtstart(dtstart);
+
+ ritr = icalrecur_iterator_new(recur,start);
+
+ tt = icaltime_as_timet(start);
+
+ printf("#### %s\n",ctime(&tt ));
+
+ icalrecur_iterator_free(ritr);
+
+ for(ritr = icalrecur_iterator_new(recur,start),
+ next = icalrecur_iterator_next(ritr);
+ !icaltime_is_null_time(next);
+ next = icalrecur_iterator_next(ritr)){
+
+ tt = icaltime_as_timet(next);
+
+ printf(" %s",ctime(&tt ));
+
+ }
+ icalrecur_iterator_free(ritr);
+
+ icalcomponent_foreach_recurrence(itr, start, end,
+ recur_callback, NULL);
+
+
+
+ }
+
+ icalset_free(cin);
+
+ icaltimezone_free_builtin_timezones();
+
+ icalmemory_free_ring();
+
+ free_zone_directory();
+
+ return 0;
+}
diff --git a/src/test/recur.dsp b/src/test/recur.dsp
new file mode 100644
index 00000000..866727b5
--- /dev/null
+++ b/src/test/recur.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="recur" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=recur - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "recur.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "recur.mak" CFG="recur - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "recur - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "recur - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "recur - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\libical" /I "..\libicalss" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "YY_NO_UNISTD_H" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "recur - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\libical" /I "..\libicalss" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "YY_NO_UNISTD_H" /FR /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libical.lib libicalss.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\libical\Debug" /libpath:"..\libicalss\Debug"
+
+!ENDIF
+
+# Begin Target
+
+# Name "recur - Win32 Release"
+# Name "recur - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\recur.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/src/test/regression-classify.c b/src/test/regression-classify.c
new file mode 100644
index 00000000..44dde6fa
--- /dev/null
+++ b/src/test/regression-classify.c
@@ -0,0 +1,193 @@
+/* -*- Mode: C -*-
+ ======================================================================
+ FILE: regression-classify.c
+ CREATOR: eric 11 February 2000
+
+ $Id: regression-classify.c,v 1.5 2008-01-02 20:07:46 dothebart Exp $
+ $Locker: $
+
+ (C) COPYRIGHT 2000 Eric Busboom
+ http://www.softwarestudio.org
+
+ The contents of this file are subject to the Mozilla Public License
+ Version 1.0 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and
+ limitations under the License.
+
+ The Original Code is eric. The Initial Developer of the Original
+ Code is Eric Busboom
+
+
+ ======================================================================*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h> /* for printf */
+#include <errno.h>
+#include <string.h> /* For strerror */
+
+#include <libical/ical.h>
+#include <libicalss/icalss.h>
+#include "regression.h"
+
+extern int VERBOSE;
+
+/* Get a note about the purpose of the property*/
+static const char* get_note(icalcomponent *c)
+{
+ icalproperty *p;
+ const char* note = 0;
+
+ if(c != 0){
+ for(p = icalcomponent_get_first_property(c,ICAL_X_PROPERTY);
+ p!= 0;
+ p = icalcomponent_get_next_property(c,ICAL_X_PROPERTY)){
+ if(strcmp(icalproperty_get_x_name(p),"X-LIC-NOTE")==0){
+ note = icalproperty_get_x(p);
+ }
+ }
+ }
+
+ if(note == 0){
+ note = "None";
+ }
+
+ return note;
+}
+
+/* Get the expected result about the purpose of the property*/
+
+static const char* get_expect(icalcomponent *c)
+{
+ icalproperty *p;
+ const char* note = 0;
+
+ if(c != 0){
+ for(p = icalcomponent_get_first_property(c,ICAL_X_PROPERTY);
+ p!= 0;
+ p = icalcomponent_get_next_property(c,ICAL_X_PROPERTY)){
+ if(strcmp(icalproperty_get_x_name(p),"X-LIC-EXPECT")==0){
+ note = icalproperty_get_x(p);
+ }
+ }
+ }
+
+ if(note == 0){
+ note = "None";
+ }
+
+ return note;
+}
+
+void test_classify(void)
+{
+ icalcomponent *c,*match;
+ int i=0;
+ int error_count = 0;
+ /* Open up the two storage files, one for the incomming components,
+ one for the calendar */
+ icalfileset_options options = {O_RDONLY, 0644, 0};
+ icalset* incoming = icalset_new(ICAL_FILE_SET, TEST_DATADIR "/incoming.ics", &options);
+ icalset* cal = icalset_new(ICAL_FILE_SET, TEST_DATADIR "/calendar.ics", &options);
+ icalset* f = icalset_new(ICAL_FILE_SET, TEST_DATADIR "/classify.ics", &options);
+
+ ok("opening file classify.ics", (f!=0));
+ ok("opening file calendar.ics", (cal!=0));
+ ok("opening file incoming.ics", (incoming!=0));
+
+ /* some basic tests.. */
+ if (f) {
+ c = icalset_get_first_component(f);
+ match = icalset_get_next_component(f);
+
+ ok("test two vcalendars for SEQUENCE with icalclassify()",
+ (icalclassify(c,match,"A@example.com") == ICAL_XLICCLASS_REQUESTRESCHEDULE));
+
+ icalset_free(f);
+ }
+
+ assert(incoming!= 0);
+ assert(cal!=0);
+
+ /* Iterate through all of the incoming components */
+ for(c=icalset_get_first_component(incoming);c!=0;
+ c=icalset_get_next_component(incoming)){
+
+ icalproperty_xlicclass class;
+ icalcomponent *match = 0;
+ const char* this_uid;
+ const char* this_note = get_note(c);
+ const char* expected_result = get_expect(c);
+ const char* actual_result;
+ const char* match_note;
+ char msg[128];
+
+ i++;
+
+ /* Check this component against the restrictions imposed by
+ iTIP. An errors will be inserted as X-LIC-ERROR properties
+ in the component. The Parser will also insert errors if it
+ cannot parse the component */
+ icalcomponent_check_restrictions(c);
+
+ /* If there are any errors, print out the component */
+
+ error_count = icalcomponent_count_errors(c);
+ sprintf(msg, "%s - parsing", this_note);
+ int_is(msg, error_count, 0);
+
+ if (error_count !=0) {
+ if (VERBOSE) printf("----- Component has errors ------- \n%s-----------------\n",
+ icalcomponent_as_ical_string(c));
+ }
+
+ /* Use one of the icalcomponent convenience routines to get
+ the UID. This routine will save you from having to use
+ icalcomponent_get_inner(),
+ icalcomponent_get_first_property(), checking the return
+ value, and then calling icalproperty_get_uid. There are
+ several other convenience routines for DTSTART, DTEND,
+ DURATION, SUMMARY, METHOD, and COMMENT */
+ this_uid = icalcomponent_get_uid(c);
+
+ if(this_uid != 0){
+ /* Look in the calendar for a component with the same UID
+ as the incomming component. We should reall also be
+ checking the RECURRENCE-ID. Another way to do this
+ operation is to us icalset_find_match(), which does use
+ the RECURRENCE-ID. */
+ match = icalset_fetch(cal,this_uid);
+ }
+
+
+ /* Classify the incoming component. The third argument is the
+ calid of the user who owns the calendar. In a real program,
+ you would probably switch() on the class.*/
+ class = icalclassify(c,match,"A@example.com");
+ /** eventually test this too.. **/
+ match_note = get_note(match);
+ actual_result = icalproperty_enum_to_string(class);
+ sprintf(msg, "expecting %s", expected_result);
+ is(msg, expected_result, actual_result);
+
+ if (VERBOSE) printf("Test %d\n\
+Incoming: %s\n\
+Matched: %s\n\
+Classification: %s\n\n",
+ i,this_note,get_note(match),
+ icalproperty_enum_to_string(class));
+ }
+
+ icalset_free(incoming);
+ icalset_free(cal);
+
+}
+
+
diff --git a/src/test/regression-component.c b/src/test/regression-component.c
new file mode 100644
index 00000000..b271e1fc
--- /dev/null
+++ b/src/test/regression-component.c
@@ -0,0 +1,570 @@
+#include <libical/ical.h>
+#include "regression.h"
+
+#include <string.h>
+extern int VERBOSE;
+
+void create_simple_component(void)
+{
+
+ icalcomponent* calendar;
+ icalproperty *version, *bogus;
+
+ /* Create calendar and add properties */
+ calendar = icalcomponent_new(ICAL_VCALENDAR_COMPONENT);
+
+ ok("create vcalendar component", (calendar!=NULL));
+
+ icalcomponent_add_property(
+ calendar,
+ icalproperty_new_version("2.0")
+ );
+
+ version = icalcomponent_get_first_property(calendar,ICAL_VERSION_PROPERTY);
+ ok("version property added", (version!=NULL));
+
+ bogus = icalcomponent_get_first_property(calendar,ICAL_DTSTART_PROPERTY);
+ ok("bogus dtstart not found", (bogus == NULL));
+
+ if (VERBOSE && calendar)
+ printf("%s\n",icalcomponent_as_ical_string(calendar));
+
+ icalcomponent_free(calendar);
+}
+
+
+static char* create_new_component_str =
+"BEGIN:VCALENDAR\r\n"
+"VERSION:2.0\r\n"
+"PRODID:-//RDU Software//NONSGML HandCal//EN\r\n"
+"BEGIN:VTIMEZONE\r\n"
+"TZID:America/New_York\r\n"
+"BEGIN:DAYLIGHT\r\n"
+"DTSTART:20020606T212449\r\n"
+"RDATE;VALUE=PERIOD:20020606T212449/20020607T012809\r\n"
+"TZOFFSETFROM:-0500\r\n"
+"TZOFFSETTO:-0400\r\n"
+"TZNAME:EST\r\n"
+"END:DAYLIGHT\r\n"
+"BEGIN:STANDARD\r\n"
+"DTSTART:20020606T212449\r\n"
+"RDATE;VALUE=PERIOD:20020606T212449/20020607T012809\r\n"
+"TZOFFSETFROM:-0400\r\n"
+"TZOFFSETTO:-0500\r\n"
+"TZNAME:EST\r\n"
+"END:STANDARD\r\n"
+"END:VTIMEZONE\r\n"
+"BEGIN:VEVENT\r\n"
+"DTSTAMP:20020606T212449\r\n"
+"UID:guid-1.host1.com\r\n"
+"ORGANIZER;ROLE=CHAIR:mrbig@host.com\r\n"
+"ATTENDEE;ROLE=REQ-PARTICIPANT;RSVP=TRUE;CUTYPE=GROUP:employee-A@host.com\r\n"
+"DESCRIPTION:Project XYZ Review Meeting\r\n"
+"CATEGORIES:MEETING\r\n"
+"CLASS:PRIVATE\r\n"
+"CREATED:20020606T212449\r\n"
+"SUMMARY:XYZ Project Review\r\n"
+"DTSTART;TZID=America/New_York:20020606T212449\r\n"
+"DTEND;TZID=America/New_York:20020606T212449\r\n"
+"LOCATION:1CP Conference Room 4350\r\n"
+"END:VEVENT\r\n"
+"END:VCALENDAR\r\n";
+
+
+/* Create a new component */
+void create_new_component()
+{
+ icalcomponent* calendar;
+ icalcomponent* timezone;
+ icalcomponent* tzc;
+ icalcomponent* event;
+ struct icaltimetype atime = icaltime_from_timet( 1023398689, 0);
+ struct icaldatetimeperiodtype rtime;
+ icalproperty* property;
+ char *calendar_as_string;
+
+ rtime.period.start = icaltime_from_timet( 1023398689,0);
+ rtime.period.end = icaltime_from_timet( 1023409689,0);
+ rtime.period.end.hour++;
+ rtime.time = icaltime_null_time();
+
+ /* Create calendar and add properties */
+ calendar = icalcomponent_new(ICAL_VCALENDAR_COMPONENT);
+
+
+ icalcomponent_add_property(
+ calendar,
+ icalproperty_new_version("2.0")
+ );
+
+ icalcomponent_add_property(
+ calendar,
+ icalproperty_new_prodid("-//RDU Software//NONSGML HandCal//EN")
+ );
+
+ /* Create a timezone object and add it to the calendar */
+
+ timezone = icalcomponent_new(ICAL_VTIMEZONE_COMPONENT);
+
+ icalcomponent_add_property(
+ timezone,
+ icalproperty_new_tzid("America/New_York")
+ );
+
+ /* Add a sub-component of the timezone */
+ tzc = icalcomponent_new(ICAL_XDAYLIGHT_COMPONENT);
+
+ icalcomponent_add_property(
+ tzc,
+ icalproperty_new_dtstart(atime)
+ );
+
+ icalcomponent_add_property(
+ tzc,
+ icalproperty_new_rdate(rtime)
+ );
+
+ icalcomponent_add_property(
+ tzc,
+ icalproperty_new_tzoffsetfrom(-5*3600)
+ );
+
+ icalcomponent_add_property(
+ tzc,
+ icalproperty_new_tzoffsetto(-4*3600)
+ );
+
+ icalcomponent_add_property(
+ tzc,
+ icalproperty_new_tzname("EST")
+ );
+
+ icalcomponent_add_component(timezone,tzc);
+
+ icalcomponent_add_component(calendar,timezone);
+
+ /* Add a second subcomponent */
+ tzc = icalcomponent_new(ICAL_XSTANDARD_COMPONENT);
+
+ icalcomponent_add_property(
+ tzc,
+ icalproperty_new_dtstart(atime)
+ );
+
+ icalcomponent_add_property(
+ tzc,
+ icalproperty_new_rdate(rtime)
+ );
+
+ icalcomponent_add_property(
+ tzc,
+ icalproperty_new_tzoffsetfrom(-4*3600)
+ );
+
+ icalcomponent_add_property(
+ tzc,
+ icalproperty_new_tzoffsetto(-5*3600)
+ );
+
+ icalcomponent_add_property(
+ tzc,
+ icalproperty_new_tzname("EST")
+ );
+
+ icalcomponent_add_component(timezone,tzc);
+
+ /* Add an event */
+
+ event = icalcomponent_new(ICAL_VEVENT_COMPONENT);
+
+ icalcomponent_add_property(
+ event,
+ icalproperty_new_dtstamp(atime)
+ );
+
+ icalcomponent_add_property(
+ event,
+ icalproperty_new_uid("guid-1.host1.com")
+ );
+
+ /* add a property that has parameters */
+ property = icalproperty_new_organizer("mrbig@host.com");
+
+ icalproperty_add_parameter(
+ property,
+ icalparameter_new_role(ICAL_ROLE_CHAIR)
+ );
+
+ icalcomponent_add_property(event,property);
+
+ /* add another property that has parameters */
+ property = icalproperty_new_attendee("employee-A@host.com");
+
+ icalproperty_add_parameter(
+ property,
+ icalparameter_new_role(ICAL_ROLE_REQPARTICIPANT)
+ );
+
+ icalproperty_add_parameter(
+ property,
+ icalparameter_new_rsvp(ICAL_RSVP_TRUE)
+ );
+
+ icalproperty_add_parameter(
+ property,
+ icalparameter_new_cutype(ICAL_CUTYPE_GROUP)
+ );
+
+ icalcomponent_add_property(event,property);
+
+
+ /* more properties */
+
+ icalcomponent_add_property(
+ event,
+ icalproperty_new_description("Project XYZ Review Meeting")
+ );
+
+ icalcomponent_add_property(
+ event,
+ icalproperty_new_categories("MEETING")
+ );
+
+ icalcomponent_add_property(
+ event,
+ icalproperty_new_class(ICAL_CLASS_PRIVATE)
+ );
+
+ icalcomponent_add_property(
+ event,
+ icalproperty_new_created(atime)
+ );
+
+ icalcomponent_add_property(
+ event,
+ icalproperty_new_summary("XYZ Project Review")
+ );
+
+
+ property = icalproperty_new_dtstart(atime);
+
+ icalproperty_add_parameter(
+ property,
+ icalparameter_new_tzid("America/New_York")
+ );
+
+ icalcomponent_add_property(event,property);
+
+
+ property = icalproperty_new_dtend(atime);
+
+ icalproperty_add_parameter(
+ property,
+ icalparameter_new_tzid("America/New_York")
+ );
+
+ icalcomponent_add_property(event,property);
+
+ icalcomponent_add_property(
+ event,
+ icalproperty_new_location("1CP Conference Room 4350")
+ );
+
+ icalcomponent_add_component(calendar,event);
+
+ calendar_as_string = icalcomponent_as_ical_string(calendar);
+
+ is("build large, complex component",
+ calendar_as_string,
+ create_new_component_str);
+
+ if (VERBOSE && calendar)
+ printf("%s\n",icalcomponent_as_ical_string(calendar));
+
+
+ if (calendar)
+ icalcomponent_free(calendar);
+
+}
+
+/* Create a new component, using the va_args list */
+
+void create_new_component_with_va_args()
+{
+
+ icalcomponent* calendar;
+ struct icaltimetype atime = icaltime_from_timet( time(0),0);
+ struct icaldatetimeperiodtype rtime;
+
+ rtime.period.start = icaltime_from_timet( time(0),0);
+ rtime.period.end = icaltime_from_timet( time(0),0);
+ rtime.period.end.hour++;
+ rtime.time = icaltime_null_time();
+
+ calendar =
+ icalcomponent_vanew(
+ ICAL_VCALENDAR_COMPONENT,
+ icalproperty_new_version("2.0"),
+ icalproperty_new_prodid("-//RDU Software//NONSGML HandCal//EN"),
+ icalcomponent_vanew(
+ ICAL_VTIMEZONE_COMPONENT,
+ icalproperty_new_tzid("America/New_York"),
+ icalcomponent_vanew(
+ ICAL_XDAYLIGHT_COMPONENT,
+ icalproperty_new_dtstart(atime),
+ icalproperty_new_rdate(rtime),
+ icalproperty_new_tzoffsetfrom(-4.0),
+ icalproperty_new_tzoffsetto(-5.0),
+ icalproperty_new_tzname("EST"),
+ (void *)0),
+ icalcomponent_vanew(
+ ICAL_XSTANDARD_COMPONENT,
+ icalproperty_new_dtstart(atime),
+ icalproperty_new_rdate(rtime),
+ icalproperty_new_tzoffsetfrom(-5.0),
+ icalproperty_new_tzoffsetto(-4.0),
+ icalproperty_new_tzname("EST"),
+ (void *)0),
+ (void *)0),
+ icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_new_dtstamp(atime),
+ icalproperty_new_uid("guid-1.host1.com"),
+ icalproperty_vanew_organizer(
+ "mrbig@host.com",
+ icalparameter_new_role(ICAL_ROLE_CHAIR),
+ (void *)0),
+ icalproperty_vanew_attendee(
+ "employee-A@host.com",
+ icalparameter_new_role(ICAL_ROLE_REQPARTICIPANT),
+ icalparameter_new_rsvp(ICAL_RSVP_TRUE),
+ icalparameter_new_cutype(ICAL_CUTYPE_GROUP),
+ (void *)0),
+ icalproperty_new_description("Project XYZ Review Meeting"),
+ icalproperty_new_categories("MEETING"),
+ icalproperty_new_class(ICAL_CLASS_PUBLIC),
+ icalproperty_new_created(atime),
+ icalproperty_new_summary("XYZ Project Review"),
+ icalproperty_vanew_dtstart(
+ atime,
+ icalparameter_new_tzid("America/New_York"),
+ (void *)0),
+ icalproperty_vanew_dtend(
+ atime,
+ icalparameter_new_tzid("America/New_York"),
+ (void *)0),
+ icalproperty_new_location("1CP Conference Room 4350"),
+ (void *)0),
+ (void *)0);
+
+ ok("creating a complex vcalendar", (calendar != NULL));
+ if (VERBOSE && calendar)
+ printf("%s\n",icalcomponent_as_ical_string(calendar));
+
+ icalcomponent_free(calendar);
+
+}
+
+static void print_span(int c, struct icaltime_span span ){
+ printf("span-->%d, %d\n", (int)span.start, (int)span.end);
+ if (span.start == 0)
+ printf("#%02d start: (empty)\n",c);
+ else
+ printf("#%02d start: %s\n",c,ical_timet_string(span.start));
+
+ if (span.end == 0)
+ printf(" end : (empty)\n");
+ else
+ printf(" end : %s\n",ical_timet_string(span.end));
+
+}
+
+/** Test icalcomponent_get_span()
+ *
+ */
+void test_icalcomponent_get_span()
+{
+ time_t tm1 = 973378800; /*Sat Nov 4 23:00:00 UTC 2000,
+ Sat Nov 4 15:00:00 PST 2000 */
+ time_t tm2 = 973382400; /*Sat Nov 5 00:00:00 UTC 2000
+ Sat Nov 4 16:00:00 PST 2000 */
+ struct icaldurationtype dur;
+ struct icaltime_span span;
+ icalcomponent *c;
+ icaltimezone *azone, *bzone;
+ int tnum = 0;
+
+ /** test 0
+ * Direct assigning time_t means they will be interpreted as UTC
+ */
+ span.start = tm1;
+ span.end = tm2;
+ if (VERBOSE) print_span(tnum++,span);
+
+ /** test 1
+ * We specify times in a timezone, the returned span is in UTC
+ */
+ azone = icaltimezone_get_builtin_timezone("America/Los_Angeles");
+ c = icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_vanew_dtstart(
+ icaltime_from_timet_with_zone(tm1,0,azone),
+ icalparameter_new_tzid("America/Los_Angeles"),0),
+ icalproperty_vanew_dtend(
+ icaltime_from_timet_with_zone(tm2,0,azone),
+ icalparameter_new_tzid("America/Los_Angeles"),0),
+ (void *)0);
+
+ span = icalcomponent_get_span(c);
+ if (VERBOSE) print_span(tnum++,span);
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ int_is("America/Los_Angeles", span.start, 973407600);
+#endif
+ icalcomponent_free(c);
+
+ /** test 2
+ * We specify times as floating, the returned span is in UTC
+ * with no conversion applied - so result should be as test 0
+ */
+ c = icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_vanew_dtstart(icaltime_from_timet(tm1,0),0),
+ icalproperty_vanew_dtend(icaltime_from_timet(tm2,0),0),
+ (void *)0);
+
+ span = icalcomponent_get_span(c);
+ if (VERBOSE) print_span(tnum++,span);
+ int_is("floating time", span.start, tm1);
+
+ icalcomponent_free(c);
+
+ /** test 3
+ * We specify times in a timezone, the returned span is in UTC
+ */
+ azone = icaltimezone_get_builtin_timezone("America/New_York");
+ c = icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_vanew_dtstart(
+ icaltime_from_timet_with_zone(tm1,0,azone),
+ icalparameter_new_tzid("America/New_York"),0),
+ icalproperty_vanew_dtend(
+ icaltime_from_timet_with_zone(tm2,0,azone),
+ icalparameter_new_tzid("America/New_York"),0),
+ (void *)0);
+
+ span = icalcomponent_get_span(c);
+ if (VERBOSE) print_span(tnum++,span);
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ int_is("America/New_York", span.start, 973396800);
+#endif
+
+ icalcomponent_free(c);
+
+ /** test 4
+ * We specify times in two different timezones, the returned span
+ * is in UTC
+ */
+ azone = icaltimezone_get_builtin_timezone("America/New_York");
+ bzone = icaltimezone_get_builtin_timezone("America/Los_Angeles");
+ c = icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_vanew_dtstart(
+ icaltime_from_timet_with_zone(tm1,0,azone),
+ icalparameter_new_tzid("America/New_York"),0),
+ icalproperty_vanew_dtend(
+ icaltime_from_timet_with_zone(tm2,0,bzone),
+ icalparameter_new_tzid("America/Los_Angeles"),0),
+ (void *)0);
+
+ span = icalcomponent_get_span(c);
+ if (VERBOSE) print_span(tnum++,span);
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ int_is("America/New_York", span.start, 973396800);
+#endif
+
+ icalcomponent_free(c);
+
+ /** test 5
+ * We specify start time in a timezone and a duration, the returned span
+ * is in UTC
+ */
+ azone = icaltimezone_get_builtin_timezone("America/Los_Angeles");
+ memset(&dur,0,sizeof(dur));
+ dur.minutes = 30;
+ c = icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_vanew_dtstart(
+ icaltime_from_timet_with_zone(tm1,0,azone),
+ icalparameter_new_tzid("America/Los_Angeles"),0),
+ icalproperty_new_duration(dur),
+
+ (void *)0);
+
+ span = icalcomponent_get_span(c);
+ if (VERBOSE) print_span(tnum++,span);
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ int_is("America/Los_Angeles w/ duration", span.end, 973409400);
+#endif
+
+ icalcomponent_free(c);
+
+ icalerror_errors_are_fatal = 0;
+ /** test 6
+ * We specify only start time, should return a null span with no error
+ */
+ c = icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_new_dtstart(icaltime_from_timet(tm1,0)),
+ (void *)0);
+
+ span = icalcomponent_get_span(c);
+ if (VERBOSE) print_span(tnum++,span);
+ int_is("null span", span.start, 0);
+ icalcomponent_free(c);
+
+ /** test 7
+ * We specify start and end date
+ */
+ c = icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_new_dtstart(icaltime_from_timet(tm1,1)),
+ icalproperty_new_dtend(icaltime_from_timet(tm1,1)),
+ (void *)0);
+
+ span = icalcomponent_get_span(c);
+ if (VERBOSE) print_span(tnum++,span);
+ int_is("UTC", span.start, 973296000);
+ icalcomponent_free(c);
+
+ /** test 8
+ * We specify start and end date
+ */
+ c = icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_new_dtstart(icaltime_from_timet(tm1,1)),
+ icalproperty_new_dtend(icaltime_from_timet(tm2,1)),
+ (void *)0);
+
+ span = icalcomponent_get_span(c);
+ int_is("UTC #2", span.start, 973296000);
+ if (VERBOSE) print_span(tnum++,span);
+
+ icalcomponent_free(c);
+
+ /** test 9
+ * We specify start date
+ */
+ c = icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_new_dtstart(icaltime_from_timet(tm1,1)),
+ (void *)0);
+
+ span = icalcomponent_get_span(c);
+ if (VERBOSE) print_span(tnum++,span);
+ int_is("start date only", span.end, 973382399);
+
+ icalcomponent_free(c);
+
+ /* assert(icalerrno == ICAL_MALFORMEDDATA_ERROR); */
+ icalerror_errors_are_fatal = 1;
+}
diff --git a/src/test/regression-cxx.cpp b/src/test/regression-cxx.cpp
new file mode 100644
index 00000000..e7605b85
--- /dev/null
+++ b/src/test/regression-cxx.cpp
@@ -0,0 +1,137 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "icalparameter_cxx.h"
+#include "icalproperty_cxx.h"
+#include "vcomponent.h"
+#include "regression.h"
+
+char content[] = "BEGIN:VCALENDAR\n\
+VERSION:2.1\n\
+BEGIN:VEVENT\n\
+UID:abcd12345\n\
+DTSTART:20020307T180000Z\n\
+DTEND:20020307T190000Z\n\
+SUMMARY:Important Meeting\n\
+END:VEVENT\n\
+END:VCALENDAR";
+
+void test_cxx(void)
+{
+ ICalProperty *summProp = new ICalProperty(ICAL_SUMMARY_PROPERTY);
+ ICalProperty *startProp = new ICalProperty(ICAL_DTSTART_PROPERTY);
+ ICalProperty *endProp = new ICalProperty(ICAL_DTEND_PROPERTY);
+ ICalProperty *locationProp = new ICalProperty(ICAL_LOCATION_PROPERTY);
+ ICalProperty *descProp = new ICalProperty(ICAL_DESCRIPTION_PROPERTY);
+
+ ok("Valid SUMMARY Property", (summProp != 0));
+ ok("Valid DTSTART Property", (startProp != 0));
+ ok("Valid DTEND Property", (endProp != 0));
+ ok("Valid LOCATION Property", (locationProp != 0));
+ ok("Valid DESCRIPTION Property", (descProp != 0));
+
+ struct icaltimetype starttime = icaltime_from_string("20011221T180000Z"); // UTC time ends in Z
+ struct icaltimetype endtime = icaltime_from_string("20020101T080000Z"); // UTC time ends in Z
+
+ summProp->set_summary("jon said: change dir to c:\\rest\\test\\nest to get the file called <foo.dat>\nthis should be in the next line.");
+ startProp->set_dtstart(starttime);
+ endProp->set_dtend(endtime);
+ locationProp->set_location("SF, California; Seattle, Washington");
+ descProp->set_description("The best cities on the west coast, hit 'NO' if you don't agree!\n");
+
+ VEvent *vEvent = new VEvent();
+
+ ok("Create a new VEvent", (vEvent!=0));
+
+ vEvent->add_property(summProp);
+ vEvent->add_property(startProp);
+ vEvent->add_property(endProp);
+ vEvent->add_property(locationProp);
+ vEvent->add_property(descProp);
+
+ //
+ is ("vEvent->get_summary()",
+ vEvent->get_summary(),
+ "jon said: change dir to c:\\rest\\test\\nest to get the file called <foo.dat>\nthis should be in the next line.");
+
+ is ("vEvent->get_dtstart()",
+ icaltime_as_ical_string(vEvent->get_dtstart()),
+ "20011221T180000Z");
+
+ is ("vEvent->get_dtend()",
+ icaltime_as_ical_string(vEvent->get_dtend()),
+ "20020101T080000Z");
+
+ ok ("vEvent->as_ical_string()",
+ (vEvent->as_ical_string() != 0));
+
+ if (VERBOSE) {
+ printf("Summary: %s\n", vEvent->get_summary());
+ printf("DTSTART: %s\n", icaltime_as_ical_string(vEvent->get_dtstart()));
+ printf("DTEND: %s\n", icaltime_as_ical_string(vEvent->get_dtend()));
+ printf("LOCATION: %s\n", vEvent->get_location());
+ printf("DESCRIPTION: %s\n", vEvent->get_description());
+
+ printf("vcomponent: %s", vEvent->as_ical_string());
+ }
+
+ VComponent ic(icalparser_parse_string((const char*)content));
+ ok("Parsing component", (ic.is_valid()));
+
+ if (VERBOSE)
+ printf("%s\n", ic.as_ical_string());
+
+ // component is wrapped within BEGIN:VCALENDAR END:VCALENDAR
+ // we need to unwrap it.
+
+ VEvent* sub_ic = dynamic_cast<VEvent*>(ic.get_first_component(ICAL_VEVENT_COMPONENT));
+
+ int_is("Getting VEvent subcomponent",
+ sub_ic->isa(),
+ ICAL_VEVENT_COMPONENT);
+
+ while (sub_ic != NULL) {
+ if (VERBOSE)
+ printf("subcomponent: %s\n", sub_ic->as_ical_string());
+
+ sub_ic = dynamic_cast<VEvent*>(ic.get_next_component(ICAL_VEVENT_COMPONENT));
+ }
+
+ VCalendar* cal = new VCalendar();
+ VAgenda* vAgenda = new VAgenda();
+
+ ok("Create a new VCalendar object", (cal != 0));
+ ok("Create a new VAgenda object", (vAgenda != 0));
+
+ ICalProperty* prop = new ICalProperty(ICAL_OWNER_PROPERTY);
+ prop->set_owner("fred@flintstone.net");
+ vAgenda->add_property(prop);
+
+ prop = new ICalProperty(ICAL_SUMMARY_PROPERTY);
+ prop->set_summary("CPMain");
+ vAgenda->add_property(prop);
+
+ prop = new ICalProperty(ICAL_TZID_PROPERTY);
+ prop->set_tzid("America/Los_Angeles");
+ vAgenda->add_property(prop);
+
+ cal->add_component(vAgenda);
+
+ ok("Complex VCALENDAR/VAGENDA", (cal->as_ical_string() != 0));
+
+ if (VERBOSE)
+ printf("vAgenda: %s\n", cal->as_ical_string());
+
+ int caughtException = 0;
+ try {
+ string foo = "HFHFHFHF";
+ VComponent v = VComponent(foo);
+ } catch (icalerrorenum err) {
+ if (err == ICAL_BADARG_ERROR) {
+ caughtException = 1;
+ }
+ }
+ int_is("Testing exception handling", caughtException, 1);
+
+}
+
diff --git a/src/test/regression-recur.c b/src/test/regression-recur.c
new file mode 100644
index 00000000..6590978a
--- /dev/null
+++ b/src/test/regression-recur.c
@@ -0,0 +1,199 @@
+/* -*- Mode: C -*-
+ ======================================================================
+ FILE: regression-recur.c
+ CREATOR: ebusboom 8jun00
+
+ DESCRIPTION:
+
+ (C) COPYRIGHT 1999 Eric Busboom
+ http://www.softwarestudio.org
+
+ The contents of this file are subject to the Mozilla Public License
+ Version 1.0 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and
+ limitations under the License.
+
+ ======================================================================*/
+
+#include <assert.h>
+#include <string.h> /* for strdup */
+#include <stdlib.h> /* for malloc */
+#include <stdio.h> /* for printf */
+#include <time.h> /* for time() */
+#include <signal.h> /* for signal */
+#ifndef WIN32
+#include <unistd.h> /* for alarm */
+#endif
+
+#include <libical/ical.h>
+#include <libicalss/icalss.h>
+#include "regression.h"
+
+extern int VERBOSE;
+
+#ifdef WIN32
+#define snprintf _snprintf
+#endif
+#ifdef _MSC_VER
+#define strcasecmp stricmp
+#endif
+
+
+static void sig_alrm(int i){
+ fprintf(stderr,"Could not get lock on file\n");
+ exit(1);
+}
+
+/* Get the expected result about the purpose of the property*/
+
+static int get_expected_numevents(icalcomponent *c)
+{
+ icalproperty *p;
+ const char* note = 0;
+ int num_events = 0;
+
+ if(c != 0){
+ for(p = icalcomponent_get_first_property(c,ICAL_X_PROPERTY);
+ p!= 0;
+ p = icalcomponent_get_next_property(c,ICAL_X_PROPERTY)){
+ if(strcmp(icalproperty_get_x_name(p),"X-EXPECT-NUMEVENTS")==0){
+ note = icalproperty_get_x(p);
+ }
+ }
+ }
+
+ if(note != 0){
+ num_events = atoi(note);
+ }
+
+
+ return num_events;
+}
+
+
+
+static void recur_callback(icalcomponent *comp,
+ struct icaltime_span *span,
+ void *data)
+{
+ int *num_recurs = data;
+
+ if (VERBOSE) {
+ printf("recur: %s", ctime(&span->start));
+ printf(" %s", ctime(&span->end));
+ }
+ *num_recurs = *num_recurs + 1;
+}
+
+void test_recur_file()
+{
+ icalset *cin = 0;
+ struct icaltimetype next;
+ icalcomponent *itr;
+ icalproperty *desc, *dtstart, *rrule;
+ struct icalrecurrencetype recur;
+ icalrecur_iterator* ritr;
+ time_t tt;
+ char* file;
+ int num_recurs_found = 0;
+ icalfileset_options options = {O_RDONLY, 0644, 0};
+
+ icalerror_set_error_state(ICAL_PARSE_ERROR, ICAL_ERROR_NONFATAL);
+
+#ifndef WIN32
+ signal(SIGALRM,sig_alrm);
+#endif
+ file = getenv("ICAL_RECUR_FILE");
+ if (!file)
+ file = TEST_DATADIR "/recur.txt";
+
+#ifndef WIN32
+ alarm(15); /* to get file lock */
+#endif
+ cin = icalset_new(ICAL_FILE_SET, file, &options);
+#ifndef WIN32
+ alarm(0);
+#endif
+
+ ok("opening file with recurring events", (cin!=NULL));
+ assert(cin!=NULL);
+
+ for (itr = icalfileset_get_first_component(cin);
+ itr != 0;
+ itr = icalfileset_get_next_component(cin)){
+ int badcomp = 0;
+ int expected_events = 0;
+ char msg[128];
+
+
+ struct icaltimetype start = icaltime_null_time();
+ struct icaltimetype startmin = icaltime_from_timet(1,0);
+ struct icaltimetype endmax = icaltime_null_time();
+ const char *desc_str = "malformed component";
+
+ desc = icalcomponent_get_first_property(itr,ICAL_DESCRIPTION_PROPERTY);
+ dtstart = icalcomponent_get_first_property(itr,ICAL_DTSTART_PROPERTY);
+ rrule = icalcomponent_get_first_property(itr,ICAL_RRULE_PROPERTY);
+ if (desc) {
+ desc_str = icalproperty_get_description(desc);
+ }
+
+ ok((char*)desc_str, !(desc == 0 || dtstart == 0 || rrule == 0));
+
+ if (desc == 0 || dtstart == 0 || rrule == 0) {
+ badcomp = 1;
+ if (VERBOSE) {
+ printf("\n******** Error in input component ********\n");
+ printf("The following component is malformed:\n %s\n", desc_str);
+ }
+ continue;
+ }
+ if (VERBOSE) {
+ printf("\n\n#### %s\n",desc_str);
+ printf("#### %s\n",icalvalue_as_ical_string(icalproperty_get_value(rrule)));
+ }
+
+ recur = icalproperty_get_rrule(rrule);
+ start = icalproperty_get_dtstart(dtstart);
+
+ ritr = icalrecur_iterator_new(recur,start);
+
+ tt = icaltime_as_timet(start);
+
+ if (VERBOSE)
+ printf("#### %s\n",ctime(&tt ));
+
+ icalrecur_iterator_free(ritr);
+
+ for(ritr = icalrecur_iterator_new(recur,start),
+ next = icalrecur_iterator_next(ritr);
+ !icaltime_is_null_time(next);
+ next = icalrecur_iterator_next(ritr)){
+
+ tt = icaltime_as_timet(next);
+
+ if (VERBOSE)
+ printf(" %s",ctime(&tt ));
+
+ }
+
+ icalrecur_iterator_free(ritr);
+ num_recurs_found = 0;
+ expected_events = get_expected_numevents(itr);
+
+ icalcomponent_foreach_recurrence(itr, startmin, endmax,
+ recur_callback, &num_recurs_found);
+
+ sprintf(msg," expecting total of %d events", expected_events);
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ int_is(msg, num_recurs_found, expected_events);
+#endif
+ }
+
+ icalset_free(cin);
+}
diff --git a/src/test/regression-storage.c b/src/test/regression-storage.c
new file mode 100644
index 00000000..15724528
--- /dev/null
+++ b/src/test/regression-storage.c
@@ -0,0 +1,808 @@
+/* -*- Mode: C -*-
+ ======================================================================
+ FILE: regression-storage.c
+ CREATOR: eric 03 April 1999
+
+ DESCRIPTION:
+
+ $Id: regression-storage.c,v 1.6 2008-02-03 16:10:47 dothebart Exp $
+ $Locker: $
+
+ (C) COPYRIGHT 1999 Eric Busboom
+ http://www.softwarestudio.org
+
+ The contents of this file are subject to the Mozilla Public License
+ Version 1.0 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and
+ limitations under the License.
+
+ The original author is Eric Busboom
+ The original code is usecases.c
+
+
+ ======================================================================*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <string.h> /* for strdup */
+#include <stdlib.h> /* for malloc */
+#include <stdio.h> /* for printf */
+#include <time.h> /* for time() */
+
+#include <libical/ical.h>
+#include <libicalss/icalss.h>
+#include "regression.h"
+
+#define OUTPUT_FILE "filesetout.ics"
+
+/* define sample calendar struct */
+struct calendar {
+ int ID;
+ size_t total_size;
+
+ /* offsets */
+ size_t total_size_offset;
+ size_t vcalendar_size_offset;
+ size_t vcalendar_offset;
+ size_t title_size_offset;
+ size_t title_offset;
+
+ /* data */
+ size_t vcalendar_size;
+ char *vcalendar;
+
+ size_t title_size;
+ char *title;
+
+};
+
+int vcalendar_init(struct calendar **cal, char *vcalendar, char *title);
+
+#ifdef WITH_BDB
+#include <db.h>
+
+int get_title(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey);
+char * parse_vcalendar(const DBT *dbt) ;
+char * pack_calendar(struct calendar *cal, int size);
+struct calendar * unpack_calendar(char *str, int size);
+#endif
+/*
+static char str[] = "BEGIN:VCALENDAR\n\
+PRODID:\"-//RDU Software//NONSGML HandCal//EN\"\n\
+VERSION:2.0\n\
+BEGIN:VTIMEZONE\n\
+TZID:US-Eastern\n\
+BEGIN:STANDARD\n\
+DTSTART:19981025T020000\n\
+RDATE:19981025T020000\n\
+TZOFFSETFROM:-0400\n\
+TZOFFSETTO:-0500\n\
+TZNAME:EST\n\
+END:STANDARD\n\
+BEGIN:DAYLIGHT\n\
+DTSTART:19990404T020000\n\
+RDATE:19990404T020000\n\
+TZOFFSETFROM:-0500\n\
+TZOFFSETTO:-0400\n\
+TZNAME:EDT\n\
+END:DAYLIGHT\n\
+END:VTIMEZONE\n\
+BEGIN:VEVENT\n\
+DTSTAMP:19980309T231000Z\n\
+UID:guid-1.host1.com\n\
+ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com\n\
+ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:MAILTO:employee-A@host.com\n\
+DESCRIPTION:Project XYZ Review Meeting\n\
+CATEGORIES:MEETING\n\
+CLASS:PUBLIC\n\
+CREATED:19980309T130000Z\n\
+SUMMARY:XYZ Project Review\n\
+DTSTART;TZID=US-Eastern:19980312T083000\n\
+DTEND;TZID=US-Eastern:19980312T093000\n\
+LOCATION:1CP Conference Room 4350\n\
+END:VEVENT\n\
+BEGIN:BOOGA\n\
+DTSTAMP:19980309T231000Z\n\
+X-LIC-FOO:Booga\n\
+DTSTOMP:19980309T231000Z\n\
+UID:guid-1.host1.com\n\
+END:BOOGA\n\
+END:VCALENDAR";
+*/
+char str2[] = "BEGIN:VCALENDAR\n\
+PRODID:\"-//RDU Software//NONSGML HandCal//EN\"\n\
+VERSION:2.0\n\
+BEGIN:VEVENT\n\
+DTSTAMP:19980309T231000Z\n\
+UID:guid-1.host1.com\n\
+ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com\n\
+ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:MAILTO:employee-A@host.com\n\
+DESCRIPTION:Project XYZ Review Meeting\n\
+CATEGORIES:MEETING\n\
+CLASS:PUBLIC\n\
+CREATED:19980309T130000Z\n\
+SUMMARY:XYZ Project Review\n\
+DTSTART;TZID=US-Eastern:19980312T083000\n\
+DTEND;TZID=US-Eastern:19980312T093000\n\
+LOCATION:1CP Conference Room 4350\n\
+END:VEVENT\n\
+END:VCALENDAR\n\
+";
+
+
+void test_fileset_extended(void)
+{
+ icalset *cout;
+ int month = 0;
+ int count=0;
+ struct icaltimetype start, end;
+ icalcomponent *c,*clone, *itr;
+ icalsetiter iter;
+
+ start = icaltime_from_timet( time(0),0);
+ end = start;
+ end.hour++;
+
+ cout = icalfileset_new(OUTPUT_FILE);
+ ok("Opening output file", (cout != 0));
+ assert(cout!=0);
+
+ c = icalparser_parse_string(str2);
+ ok("Parsing str2", (c!=0));
+ assert(c != 0);
+
+ icalset_free(cout);
+
+ /* Add data to the file */
+
+ for(month = 1; month < 10; month++){
+ icalcomponent *event;
+ icalproperty *dtstart, *dtend;
+
+ cout = icalfileset_new(OUTPUT_FILE);
+ ok("Opening output file", (cout != 0));
+ assert(cout != 0);
+
+ start.month = month;
+ end.month = month;
+
+ clone = icalcomponent_new_clone(c);
+ ok("Making clone of output file", (clone!=0));
+ assert(clone !=0);
+
+ event = icalcomponent_get_first_component(clone,ICAL_VEVENT_COMPONENT);
+ ok("Getting first event from clone", (event!=0));
+ assert(event != 0);
+
+ dtstart = icalcomponent_get_first_property(event,ICAL_DTSTART_PROPERTY);
+ ok("find DTSTART", (dtstart !=0));
+ assert(dtstart!=0);
+
+ icalproperty_set_dtstart(dtstart,start);
+
+ dtend = icalcomponent_get_first_property(event,ICAL_DTEND_PROPERTY);
+ ok("find DTEND", (dtend !=0));
+
+ assert(dtend!=0);
+
+ icalproperty_set_dtend(dtend,end);
+
+ icalfileset_add_component(cout,clone);
+ icalfileset_commit(cout);
+
+ icalset_free(cout);
+ }
+
+ /* Print them out */
+
+ cout = icalfileset_new(OUTPUT_FILE);
+
+ ok("Opening output file", (cout != 0));
+ assert(cout != 0);
+
+ for (iter = icalfileset_begin_component(cout, ICAL_ANY_COMPONENT, 0);
+ icalsetiter_deref(&iter) != 0; icalsetiter_next(&iter)) {
+ icalcomponent *event;
+ icalproperty *dtstart, *dtend;
+
+ itr = icalsetiter_deref(&iter);
+ count++;
+
+ event = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT);
+
+ dtstart = icalcomponent_get_first_property(event,ICAL_DTSTART_PROPERTY);
+ dtend = icalcomponent_get_first_property(event,ICAL_DTEND_PROPERTY);
+
+ if (VERBOSE)
+ printf("%d %s %s\n",count, icalproperty_as_ical_string(dtstart),
+ icalproperty_as_ical_string(dtend));
+
+ }
+
+ /* Remove all of them */
+
+ icalset_free(cout);
+
+ cout = icalfileset_new(OUTPUT_FILE);
+ ok("Opening output file", (cout!=0));
+ assert(cout != 0);
+
+ /* need to advance the iterator first before calling remove_componenet() */
+ /* otherwise, iter will contain a "removed" component and icalsetiter_next(&iter) */
+ /* will fail. */
+
+ iter = icalfileset_begin_component(cout, ICAL_ANY_COMPONENT, 0);
+ itr = icalsetiter_deref(&iter);
+ while (itr != 0) {
+ icalsetiter_next(&iter);
+ icalfileset_remove_component(cout, itr);
+ icalcomponent_free(itr);
+ itr = icalsetiter_deref(&iter);
+ }
+
+ icalset_free(cout);
+
+ /* Print them out again */
+
+ cout = icalfileset_new(OUTPUT_FILE);
+ ok("Opening output file", (cout != 0));
+ assert(cout != 0);
+ count =0;
+
+ for (itr = icalfileset_get_first_component(cout);
+ itr != 0;
+ itr = icalfileset_get_next_component(cout)){
+
+ icalcomponent *event;
+ icalproperty *dtstart, *dtend;
+
+ count++;
+
+ event = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT);
+
+ dtstart = icalcomponent_get_first_property(event,ICAL_DTSTART_PROPERTY);
+ dtend = icalcomponent_get_first_property(event,ICAL_DTEND_PROPERTY);
+
+ printf("%d %s %s\n",count, icalproperty_as_ical_string(dtstart),
+ icalproperty_as_ical_string(dtend));
+
+ }
+
+ icalset_free(cout);
+ icalcomponent_free(c);
+}
+
+
+#ifdef WITH_BDB
+
+/*
+ In this example, we're storing a calendar with several components
+ under the reference id "calendar_7286" and retrieving records based
+ on title, "month_1" through "month_10". We use a number of the
+ "optional" arguments to specify secondary indices, sub-databases
+ (i.e. having multiple databases residing within a single Berkeley
+ DB file), and keys for storage and retrieval.
+*/
+
+void test_bdbset()
+{
+ icalset *cout;
+ int month = 0;
+ int count=0;
+ int num_components=0;
+ int szdata_len=0;
+ int ret=0;
+ char *subdb, *szdata, *szpacked_data;
+ char uid[255];
+ struct icaltimetype start, end;
+ icalcomponent *c,*clone, *itr;
+ DBT key, data;
+ DBC *dbcp;
+
+ struct calendar *cal;
+ int cal_size;
+
+ return; // for now... TODO fix these broken tests..
+
+
+
+ start = icaltime_from_timet( time(0),0);
+ end = start;
+ end.hour++;
+
+ /* Note: as per the Berkeley DB ref pages:
+ *
+ * The database argument is optional, and allows applications to
+ * have multiple databases in a single file. Although no database
+ * argument needs to be specified, it is an error to attempt to
+ * open a second database in a file that was not initially created
+ * using a database name.
+ *
+ */
+
+ subdb = "calendar_id";
+
+ /* open database, using subdb */
+ cout = icalbdbset_new("calendar.db", ICALBDB_EVENTS, DB_HASH, 0);
+ /*
+ sdbp = icalbdbset_secondary_open(dbp,
+ DATABASE,
+ "title",
+ get_title,
+ DB_HASH);
+ */
+
+ c = icalparser_parse_string(str2);
+
+ assert(c != 0);
+
+ /* Add data to the file */
+
+ for(month = 1; month < 10; month++){
+ icalcomponent *event;
+ icalproperty *dtstart, *dtend, *location;
+
+ /* retrieve data */
+ // cout = icalbdbset_new(dbp, sdbp, NULL);
+ // assert(cout != 0);
+
+ start.month = month;
+ end.month = month;
+
+ clone = icalcomponent_new_clone(c);
+ assert(clone !=0);
+ event = icalcomponent_get_first_component(clone,
+ ICAL_VEVENT_COMPONENT);
+ assert(event != 0);
+
+ dtstart = icalcomponent_get_first_property(event,
+ ICAL_DTSTART_PROPERTY);
+ assert(dtstart!=0);
+ icalproperty_set_dtstart(dtstart,start);
+
+ dtend = icalcomponent_get_first_property(event,ICAL_DTEND_PROPERTY);
+ assert(dtend!=0);
+ icalproperty_set_dtend(dtend,end);
+
+ location = icalcomponent_get_first_property(event, ICAL_LOCATION_PROPERTY);
+ assert(location!=0);
+
+#if 0
+ /* change the uid to include the month */
+ sprintf(uid, "%s_%d", icalcomponent_get_uid(clone), month);
+ icalcomponent_set_uid(clone, uid);
+#endif
+
+ icalbdbset_add_component(cout,clone);
+
+ /* commit changes */
+ icalbdbset_commit(cout);
+
+ num_components = icalcomponent_count_components(clone, ICAL_ANY_COMPONENT);
+
+ icalset_free(cout);
+
+ }
+
+ /* try out the cursor operations */
+ memset(&key, 0, sizeof(DBT));
+ memset(&data, 0, sizeof(DBT));
+
+#if 0
+ ret = icalbdbset_acquire_cursor(dbp, &dbcp);
+ ret = icalbdbset_get_first(dbcp, &key, &data);
+ ret = icalbdbset_get_next(dbcp, &key, &data);
+ ret = icalbdbset_get_last(dbcp, &key, &data);
+#endif
+ /* Print them out */
+
+ for(month = 1, count=0; month < 10; month++){
+ char *title;
+
+ icalcomponent *event;
+ icalproperty *dtstart, *dtend;
+
+ for (itr = icalbdbset_get_first_component(cout);
+ itr != 0;
+ itr = icalbdbset_get_next_component(cout)){
+
+ icalcomponent *event;
+ icalproperty *dtstart, *dtend;
+
+ count++;
+
+ event = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT);
+
+ dtstart = icalcomponent_get_first_property(event,ICAL_DTSTART_PROPERTY);
+ dtend = icalcomponent_get_first_property(event,ICAL_DTEND_PROPERTY);
+
+ printf("%d %s %s\n",count, icalproperty_as_ical_string(dtstart),
+ icalproperty_as_ical_string(dtend));
+
+ }
+ icalset_free(cout);
+ }
+
+ /* open database */
+ // cout = icalbdbset_bdb_open("calendar.db", "title", DB_HASH, 0644);
+ /* sdbp = icalbdbset_secondary_open(dbp,
+ DATABASE,
+ "title",
+ get_title,
+ DB_HASH);
+ */
+ /* Remove all of them */
+ for(month = 1; month < 10; month++){
+ for (itr = icalbdbset_get_first_component(cout);
+ itr != 0;
+ itr = icalbdbset_get_next_component(cout)){
+
+ icalbdbset_remove_component(cout, itr);
+ }
+
+ icalbdbset_commit(cout);
+ icalset_free(cout);
+
+ }
+
+ /* Print them out again */
+
+ for(month = 1, count=0; month < 10; month++){
+ char *title;
+
+ icalcomponent *event;
+ icalproperty *dtstart, *dtend;
+
+ for (itr = icalbdbset_get_first_component(cout);
+ itr != 0;
+ itr = icalbdbset_get_next_component(cout)){
+
+ icalcomponent *event;
+ icalproperty *dtstart, *dtend;
+
+ count++;
+
+ event = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT);
+
+ dtstart = icalcomponent_get_first_property(event,ICAL_DTSTART_PROPERTY);
+ dtend = icalcomponent_get_first_property(event,ICAL_DTEND_PROPERTY);
+
+ printf("%d %s %s\n",count, icalproperty_as_ical_string(dtstart),
+ icalproperty_as_ical_string(dtend));
+
+ }
+ icalset_free(cout);
+ }
+}
+#endif
+
+int vcalendar_init(struct calendar **rcal, char *vcalendar, char *title)
+{
+ size_t vcalendar_size, title_size, total_size;
+ struct calendar *cal;
+
+ if(vcalendar)
+ vcalendar_size = strlen(vcalendar);
+ else {
+ vcalendar = "";
+ vcalendar_size = strlen(vcalendar);
+ }
+
+ if(title)
+ title_size = strlen(title);
+ else {
+ title = "";
+ title_size = strlen(title);
+ }
+
+ total_size = sizeof(struct calendar) + vcalendar_size + title_size;
+
+ if((cal = (struct calendar *)malloc(total_size))==NULL)
+ return 0;
+ memset(cal, 0, total_size);
+
+ /* offsets */
+ cal->total_size_offset = sizeof(int);
+ cal->vcalendar_size_offset = (sizeof(int) * 7);
+ cal->vcalendar_offset = cal->vcalendar_size_offset + sizeof(int);
+ cal->title_size_offset = cal->vcalendar_offset + vcalendar_size;
+ cal->title_offset = cal->title_size_offset + sizeof(int);
+
+ /* sizes */
+ cal->total_size = total_size;
+ cal->vcalendar_size = vcalendar_size;
+ cal->title_size = title_size;
+
+ if (vcalendar && *vcalendar)
+ cal->vcalendar = strdup(vcalendar);
+
+ if (title && *title)
+ cal->title = strdup(title);
+
+ *rcal = cal;
+
+ return 0;
+}
+
+/* get_title -- extracts a secondary key (the vcalendar)
+ * from a primary key/data pair */
+
+/* just create a random title for now */
+#ifdef WITH_BDB
+
+int get_title(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey)
+{
+ icalcomponent *cl;
+ char title[255];
+
+ memset(skey, 0, sizeof(DBT));
+
+ cl = icalparser_parse_string((char *)pdata->data);
+ sprintf(title, "title_%s", icalcomponent_get_uid(cl));
+
+ skey->data = strdup(title);
+ skey->size = strlen(skey->data);
+ return (0);
+}
+
+char * pack_calendar(struct calendar *cal, int size)
+{
+ char *str;
+
+ if((str = (char *)malloc(sizeof(char) * size))==NULL)
+ return 0;
+
+ /* ID */
+ memcpy(str, &cal->ID, sizeof(cal->ID));
+
+ /* total_size */
+ memcpy(str + cal->total_size_offset,
+ &cal->total_size,
+ sizeof(cal->total_size));
+
+ /* vcalendar_size */
+ memcpy(str + cal->vcalendar_size_offset,
+ &cal->vcalendar_size,
+ sizeof(cal->vcalendar_size));
+
+ /* vcalendar */
+ memcpy(str + cal->vcalendar_offset,
+ cal->vcalendar,
+ cal->vcalendar_size);
+
+ /* title_size */
+ memcpy(str + cal->title_size_offset,
+ &cal->title_size,
+ sizeof(cal->title_size));
+
+ /* title */
+ memcpy(str + cal->title_offset,
+ cal->title,
+ cal->title_size);
+
+ return str;
+}
+
+struct calendar * unpack_calendar(char *str, int size)
+{
+ struct calendar *cal;
+ if((cal = (struct calendar *) malloc(size))==NULL)
+ return 0;
+ memset(cal, 0, size);
+
+ /* offsets */
+ cal->total_size_offset = sizeof(int);
+ cal->vcalendar_size_offset = (sizeof(int) * 7);
+ cal->vcalendar_offset = cal->vcalendar_size_offset + sizeof(int);
+
+ /* ID */
+ memcpy(&cal->ID, str, sizeof(cal->ID));
+
+ /* total_size */
+ memcpy(&cal->total_size,
+ str + cal->total_size_offset,
+ sizeof(cal->total_size));
+
+ /* vcalendar_size */
+ memcpy(&cal->vcalendar_size,
+ str + cal->vcalendar_size_offset,
+ sizeof(cal->vcalendar_size));
+
+ if((cal->vcalendar = (char *)malloc(sizeof(char) *
+ cal->vcalendar_size))==NULL)
+ return 0;
+
+ /* vcalendar */
+ memcpy(cal->vcalendar,
+ (char *)(str + cal->vcalendar_offset),
+ cal->vcalendar_size);
+
+ cal->title_size_offset = cal->vcalendar_offset + cal->vcalendar_size;
+ cal->title_offset = cal->title_size_offset + sizeof(int);
+
+ /* title_size */
+ memcpy(&cal->title_size,
+ str + cal->title_size_offset,
+ sizeof(cal->title_size));
+
+ if((cal->title = (char *)malloc(sizeof(char) *
+ cal->title_size))==NULL)
+ return 0;
+
+ /* title*/
+ memcpy(cal->title,
+ (char *)(str + cal->title_offset),
+ cal->title_size);
+
+ return cal;
+}
+
+char * parse_vcalendar(const DBT *dbt)
+{
+ char *str;
+ struct calendar *cal;
+
+ str = (char *)dbt->data;
+ cal = unpack_calendar(str, dbt->size);
+
+ return cal->vcalendar;
+}
+#endif
+
+void test_dirset_extended(void)
+{
+
+ icalcomponent *c;
+ icalgauge *gauge;
+ icalerrorenum error;
+ icalcomponent *itr;
+ icalset* cluster;
+ struct icalperiodtype rtime;
+ icalset *s = icaldirset_new("store");
+ icalset *s2 = icaldirset_new("store-new");
+ int i, count = 0;
+
+ ok("Open dirset 'store'", (s!=0));
+ assert(s != 0);
+
+ rtime.start = icaltime_from_timet( time(0),0);
+
+ cluster = icalfileset_new(OUTPUT_FILE);
+
+ ok("Open fileset to duplicate 4 times", (cluster != 0));
+ assert(cluster != 0);
+
+#define NUMCOMP 4
+
+ /* Duplicate every component in the cluster NUMCOMP times */
+
+ icalerror_clear_errno();
+
+ for (i = 1; i<NUMCOMP+1; i++){
+
+ /*rtime.start.month = i%12;*/
+ rtime.start.month = i;
+ rtime.end = rtime.start;
+ rtime.end.hour++;
+
+ for (itr = icalfileset_get_first_component(cluster);
+ itr != 0;
+ itr = icalfileset_get_next_component(cluster)){
+ icalcomponent *clone, *inner;
+ icalproperty *p;
+
+ inner = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT);
+ if (inner == 0){
+ continue;
+ }
+
+ /* Change the dtstart and dtend times in the component
+ pointed to by Itr*/
+
+ clone = icalcomponent_new_clone(itr);
+ inner = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT);
+
+ ok("Duplicating component...",
+ (icalerrno == ICAL_NO_ERROR)&&(inner!=0));
+
+ assert(icalerrno == ICAL_NO_ERROR);
+ assert(inner !=0);
+
+ /* DTSTART*/
+ p = icalcomponent_get_first_property(inner,ICAL_DTSTART_PROPERTY);
+ ok("Fetching DTSTART", (icalerrno == ICAL_NO_ERROR));
+ assert(icalerrno == ICAL_NO_ERROR);
+
+ if (p == 0){
+ p = icalproperty_new_dtstart(rtime.start);
+ icalcomponent_add_property(inner,p);
+ } else {
+ icalproperty_set_dtstart(p,rtime.start);
+ }
+
+ ok("Adding DTSTART property", (icalerrno == ICAL_NO_ERROR));
+ assert(icalerrno == ICAL_NO_ERROR);
+
+ /* DTEND*/
+ p = icalcomponent_get_first_property(inner,ICAL_DTEND_PROPERTY);
+ ok("Fetching DTEND property", (icalerrno == ICAL_NO_ERROR));
+ assert(icalerrno == ICAL_NO_ERROR);
+
+ if (p == 0){
+ p = icalproperty_new_dtstart(rtime.end);
+ icalcomponent_add_property(inner,p);
+ } else {
+ icalproperty_set_dtstart(p,rtime.end);
+ }
+ ok("Setting DTEND property", (icalerrno == ICAL_NO_ERROR));
+ assert(icalerrno == ICAL_NO_ERROR);
+
+ if (VERBOSE)
+ printf("\n----------\n%s\n---------\n",icalcomponent_as_ical_string(inner));
+
+ error = icaldirset_add_component(s,
+ icalcomponent_new_clone(itr));
+
+ ok("Adding component to dirset", (icalerrno == ICAL_NO_ERROR));
+ assert(icalerrno == ICAL_NO_ERROR);
+ }
+
+ }
+
+ gauge = icalgauge_new_from_sql("SELECT * FROM VEVENT WHERE VEVENT.SUMMARY = 'Submit Income Taxes' OR VEVENT.SUMMARY = 'Bastille Day Party'", 0);
+
+ ok("Creating complex Gauge", (gauge!=0));
+
+ icaldirset_select(s,gauge);
+
+ for(c = icaldirset_get_first_component(s); c != 0;
+ c = icaldirset_get_next_component(s)){
+
+ printf("Got one! (%d)\n", count++);
+
+ if (c != 0){
+ printf("%s", icalcomponent_as_ical_string(c));;
+ if (icaldirset_add_component(s2,c) == 0){
+ printf("Failed to write!\n");
+ }
+ icalcomponent_free(c);
+ } else {
+ printf("Failed to get component\n");
+ }
+ }
+
+ icalset_free(s2);
+
+ for(c = icaldirset_get_first_component(s);
+ c != 0;
+ c = icaldirset_get_next_component(s)){
+
+ if (c != 0){
+ printf("%s", icalcomponent_as_ical_string(c));;
+ } else {
+ printf("Failed to get component\n");
+ }
+
+ }
+
+ /* Remove all of the components */
+ i=0;
+ while((c=icaldirset_get_current_component(s)) != 0 ){
+ i++;
+
+ icaldirset_remove_component(s,c);
+ }
+
+
+ icalset_free(s);
+ icalset_free(cluster);
+}
+
diff --git a/src/test/regression-utils.c b/src/test/regression-utils.c
new file mode 100644
index 00000000..c7bc2fe3
--- /dev/null
+++ b/src/test/regression-utils.c
@@ -0,0 +1,180 @@
+#include <libical/ical.h>
+
+#include <stdlib.h> /* abort() */
+#include <string.h> /* strcmp() */
+
+static char ictt_str[1024];
+int VERBOSE = 1;
+int QUIET = 0;
+
+const char* ical_timet_string(const time_t t)
+{
+ struct tm stm;
+ struct tm *tmp = gmtime(&t);
+
+ if (tmp)
+ stm = *tmp;
+ else
+ memset(&stm, 0, sizeof(stm));
+
+ sprintf(ictt_str,"%02d-%02d-%02d %02d:%02d:%02d Z",stm.tm_year+1900,
+ stm.tm_mon+1,stm.tm_mday,stm.tm_hour,stm.tm_min,stm.tm_sec);
+
+ return ictt_str;
+
+}
+
+const char* ictt_as_string(struct icaltimetype t)
+{
+ const char *zone = icaltimezone_get_tzid((icaltimezone *)t.zone);
+
+ if (icaltime_is_utc(t))
+ sprintf(ictt_str,"%02d-%02d-%02d %02d:%02d:%02d Z UTC",
+ t.year,t.month,t.day, t.hour,t.minute,t.second);
+ else
+ sprintf(ictt_str,"%02d-%02d-%02d %02d:%02d:%02d %s",
+ t.year,t.month,t.day, t.hour,t.minute,t.second,
+ zone == NULL? "(floating)": zone);
+
+ return ictt_str;
+}
+
+char* icaltime_as_ctime(struct icaltimetype t)
+{
+ time_t tt;
+
+ tt = icaltime_as_timet(t);
+ sprintf(ictt_str,"%s",ctime(&tt));
+
+ return ictt_str;
+}
+
+
+/** This variable is used to control whether we core dump on errors **/
+static int die_on_errors = 0;
+static int testnumber = 0;
+static int failed = 0;
+static int current_set = 0;
+
+static struct {int set; int test;} failed_tests[1024];
+
+void die_on_errors_set(int val) {
+ die_on_errors = 1;
+}
+
+void _ok(char* test_name, int success, char *file, int linenum, char *test) {
+ testnumber++;
+
+ if (!QUIET || (QUIET && !success))
+ printf("%sok %d - %s\n", (success)?"" : "not ", testnumber, test_name);
+ if (!success) {
+ failed_tests[failed].set = current_set;
+ failed_tests[failed].test = testnumber;
+ failed++;
+
+ printf("# test failed: \"%s\"\n", test);
+ printf("# at: %s:%-d\n", file, linenum);
+ }
+
+ if (die_on_errors == 1 && !success) {
+ abort();
+ }
+}
+
+void _is(char* test_name, const char* str1, const char* str2, char *file, int linenum) {
+ int diff;
+
+ if (str1 == NULL || str2 == NULL) {
+ diff = 1;
+ } else {
+ diff = strcmp(str1, str2);
+ }
+
+ if (!test_name) test_name = "()";
+
+ _ok(test_name, (diff==0), file, linenum, "");
+
+ if (diff) {
+ printf("# got: %s\n", str1 ? str1 : "(null)");
+ printf("# expected: %s\n", str2 ? str2 : "(null)");
+ }
+}
+
+void _int_is(char* test_name, int i1, int i2, char *file, int linenum) {
+ _ok(test_name, (i1==i2), file, linenum, "");
+
+ if (i1!=i2) {
+ printf("# got: %d\n", i1);
+ printf("# expected: %d\n", i2);
+ }
+}
+
+
+void verbose(int newval) {
+ VERBOSE = newval;
+}
+
+void test_start(int numtests) {
+ if (numtests) {
+ if (!QUIET)
+ printf("1..%-d\n", numtests);
+ } else {
+ if (!QUIET)
+ printf("1..\n");
+ }
+}
+
+void test_header(char *header, int set) {
+ if (!QUIET)
+ printf("########## %-40s (%d) ##########\n", header, set);
+ current_set = set;
+}
+
+void test_end(void) {
+ int pct;
+
+ if (testnumber < 1) {
+ printf("\n No Tests Run.\n");
+ return;
+ }
+
+ if (failed) {
+ int i, oldset = 0;
+
+ pct = ((testnumber - failed)*100)/testnumber;
+ printf("\n Failed %d/%d tests, %2d%% okay\n", failed, testnumber, pct);
+ printf("\n Failed tests:\n ");
+ for (i = 0; i < failed; i++) {
+ int this_set = failed_tests[i].set;
+ char *prefix = "";
+ if (this_set != oldset) {
+ prefix = "\n ";
+ oldset = this_set;
+ }
+
+ printf("%s%d/%d ", prefix, this_set, failed_tests[i].test);
+ }
+ printf("\n");
+
+ } else {
+ printf("\n All Tests Successful.\n");
+ }
+}
+
+
+void test_run(char *test_name,
+ void (*test_fcn)(void),
+ int do_test, int headeronly)
+{
+ static int test_set = 1;
+
+ if (headeronly || do_test == 0 || do_test == test_set)
+ test_header(test_name, test_set);
+
+ if (!headeronly && (do_test==0 || do_test == test_set)) {
+ (*test_fcn)();
+ if (!QUIET)
+ printf("\n");
+ }
+ test_set++;
+}
diff --git a/src/test/regression.c b/src/test/regression.c
new file mode 100644
index 00000000..3397ea04
--- /dev/null
+++ b/src/test/regression.c
@@ -0,0 +1,3907 @@
+/* -*- Mode: C -*-
+ ======================================================================
+ FILE: regression.c
+ CREATOR: eric 03 April 1999
+
+ DESCRIPTION:
+
+ $Id: regression.c,v 1.67 2008-02-03 16:10:48 dothebart Exp $
+ $Locker: $
+
+ (C) COPYRIGHT 1999 Eric Busboom
+ http://www.softwarestudio.org
+
+ The contents of this file are subject to the Mozilla Public License
+ Version 1.0 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and
+ limitations under the License.
+
+ The original author is Eric Busboom
+ The original code is regression.c
+
+
+ ======================================================================*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <libical/ical.h>
+#include <libicalss/icalss.h>
+#include <libicalvcal/vobject.h>
+#include <libicalvcal/icalvcal.h>
+#include <libicalvcal/vcc.h>
+
+#include "regression.h"
+
+#include <assert.h>
+#include <string.h> /* for strdup */
+#include <stdlib.h> /* for malloc */
+#include <stdio.h> /* for printf */
+#include <time.h> /* for time() */
+#ifndef WIN32
+#include <unistd.h> /* for unlink, fork */
+#include <sys/wait.h> /* For waitpid */
+#include <sys/time.h> /* for select */
+#else
+#include <direct.h> /* for mkdir */
+#include <windows.h>
+#endif
+#include <sys/types.h> /* For wait pid */
+
+
+/* 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 */
+/*
+static char str[] = "BEGIN:VCALENDAR\
+PRODID:\"-//RDU Software//NONSGML HandCal//EN\"\
+VERSION:2.0\
+BEGIN:VTIMEZONE\
+TZID:America/New_York\
+BEGIN:STANDARD\
+DTSTART:19981025T020000\
+RDATE:19981025T020000\
+TZOFFSETFROM:-0400\
+TZOFFSETTO:-0500\
+TZNAME:EST\
+END:STANDARD\
+BEGIN:DAYLIGHT\
+DTSTART:19990404T020000\
+RDATE:19990404T020000\
+TZOFFSETFROM:-0500\
+TZOFFSETTO:-0400\
+TZNAME:EDT\
+END:DAYLIGHT\
+END:VTIMEZONE\
+BEGIN:VEVENT\
+DTSTAMP:19980309T231000Z\
+UID:guid-1.host1.com\
+ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com\
+ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:MAILTO:employee-A@host.com\
+DESCRIPTION:Project XYZ Review Meeting\
+CATEGORIES:MEETING\
+CLASS:PUBLIC\
+CREATED:19980309T130000Z\
+SUMMARY:XYZ Project Review\
+DTSTART;TZID=America/New_York:19980312T083000\
+DTEND;TZID=America/New_York:19980312T093000\
+LOCATION:1CP Conference Room 4350\
+END:VEVENT\
+BEGIN:BOOGA\
+DTSTAMP:19980309T231000Z\
+X-LIC-FOO:Booga\
+DTSTOMP:19980309T231000Z\
+UID:guid-1.host1.com\
+END:BOOGA\
+END:VCALENDAR";
+*/
+
+
+/* Return a list of all attendees who are required. */
+/*
+static char** get_required_attendees(icalcomponent* event)
+{
+ icalproperty* p;
+ icalparameter* parameter;
+
+ char **attendees;
+ int max = 10;
+ int c = 0;
+
+ attendees = malloc(max * (sizeof (char *)));
+
+ ok("event is non null", (event != 0));
+ int_is("event is a VEVENT", icalcomponent_isa(event), ICAL_VEVENT_COMPONENT);
+
+ for(
+ p = icalcomponent_get_first_property(event,ICAL_ATTENDEE_PROPERTY);
+ p != 0;
+ p = icalcomponent_get_next_property(event,ICAL_ATTENDEE_PROPERTY)
+ ) {
+
+ parameter = icalproperty_get_first_parameter(p,ICAL_ROLE_PARAMETER);
+
+ if ( icalparameter_get_role(parameter) == ICAL_ROLE_REQPARTICIPANT)
+ {
+ attendees[c++] = icalmemory_strdup(icalproperty_get_attendee(p));
+
+ if (c >= max) {
+ max *= 2;
+ attendees = realloc(attendees, max * (sizeof (char *)));
+ }
+
+ }
+ }
+
+ return attendees;
+}
+*/
+
+/* If an attendee has a PARTSTAT of NEEDSACTION or has no PARTSTAT
+ parameter, change it to TENTATIVE. */
+ /*
+static void update_attendees(icalcomponent* event)
+{
+ icalproperty* p;
+ icalparameter* parameter;
+
+
+ assert(event != 0);
+ assert(icalcomponent_isa(event) == ICAL_VEVENT_COMPONENT);
+
+ for(
+ p = icalcomponent_get_first_property(event,ICAL_ATTENDEE_PROPERTY);
+ p != 0;
+ p = icalcomponent_get_next_property(event,ICAL_ATTENDEE_PROPERTY)
+ ) {
+
+ parameter = icalproperty_get_first_parameter(p,ICAL_PARTSTAT_PARAMETER);
+
+ if (parameter == 0) {
+
+ icalproperty_add_parameter(
+ p,
+ icalparameter_new_partstat(ICAL_PARTSTAT_TENTATIVE)
+ );
+
+ } else if (icalparameter_get_partstat(parameter) == ICAL_PARTSTAT_NEEDSACTION) {
+
+ icalproperty_remove_parameter_by_ref(p,parameter);
+
+ icalparameter_free(parameter);
+
+ icalproperty_add_parameter(
+ p,
+ icalparameter_new_partstat(ICAL_PARTSTAT_TENTATIVE)
+ );
+ }
+
+ }
+}
+ */
+
+void test_values()
+{
+ icalvalue *v;
+ icalvalue *copy;
+
+ v = icalvalue_new_caladdress("cap://value/1");
+
+ is("icalvalue_new_caladdress()",
+ icalvalue_get_caladdress(v), "cap://value/1");
+
+ icalvalue_set_caladdress(v,"cap://value/2");
+
+ is("icalvalue_set_caladdress()",
+ icalvalue_get_caladdress(v), "cap://value/2");
+
+ is("icalvalue_as_ical_string()",
+ icalvalue_as_ical_string(v), "cap://value/2");
+
+ copy = icalvalue_new_clone(v);
+
+ is("icalvalue_new_clone()",
+ icalvalue_as_ical_string(copy), "cap://value/2");
+ icalvalue_free(v);
+ icalvalue_free(copy);
+
+
+ v = icalvalue_new_boolean(1);
+ int_is("icalvalue_new_boolean(1)", icalvalue_get_boolean(v), 1);
+ icalvalue_set_boolean(v,2);
+ ok("icalvalue_set_boolean(2)", (2 == icalvalue_get_boolean(v)));
+ is("icalvalue_as_ical_string()", icalvalue_as_ical_string(v), "2");
+
+ copy = icalvalue_new_clone(v);
+ is("icalvalue_new_clone()", icalvalue_as_ical_string(copy), "2");
+
+ icalvalue_free(v);
+ icalvalue_free(copy);
+
+
+ v = icalvalue_new_x("test");
+ is("icalvalue_new_x(test)", icalvalue_get_x(v), "test");
+ icalvalue_set_x(v, "test2");
+ is("icalvalue_set_x(test2)", icalvalue_get_x(v), "test2");
+ is("icalvalue_as_ical_string()", icalvalue_as_ical_string(v), "test2");
+
+ copy = icalvalue_new_clone(v);
+ is("icalvalue_new_clone()", icalvalue_as_ical_string(copy), "test2");
+
+ icalvalue_free(v);
+ icalvalue_free(copy);
+
+
+ v = icalvalue_new_date(icaltime_from_timet( 1023404802,0));
+ is("icalvalue_new_date()", icalvalue_as_ical_string(v), "20020606T230642");
+ icalvalue_set_date(v,icaltime_from_timet( 1023404802-3600,0));
+ is("icalvalue_set_date()",icalvalue_as_ical_string(v), "20020606T220642");
+
+ copy = icalvalue_new_clone(v);
+ is("icalvalue_new_clone()",icalvalue_as_ical_string(v), "20020606T220642");
+
+ icalvalue_free(v);
+ icalvalue_free(copy);
+
+
+ v = icalvalue_new(-1);
+
+ ok("icalvalue_new(-1), Invalid type", (v == NULL));
+
+ if (v!=0) icalvalue_free(v);
+
+ ok("ICAL_BOOLEAN_VALUE",(ICAL_BOOLEAN_VALUE ==
+ icalparameter_value_to_value_kind(ICAL_VALUE_BOOLEAN)));
+ ok("ICAL_UTCOFFSET_VALUE",(ICAL_UTCOFFSET_VALUE ==
+ icalparameter_value_to_value_kind(ICAL_VALUE_UTCOFFSET)));
+ ok("ICAL_RECUR_VALUE", (ICAL_RECUR_VALUE ==
+ icalparameter_value_to_value_kind(ICAL_VALUE_RECUR)));
+ ok("ICAL_CALADDRESS_VALUE",(ICAL_CALADDRESS_VALUE ==
+ icalparameter_value_to_value_kind(ICAL_VALUE_CALADDRESS)));
+ ok("ICAL_PERIOD_VALUE", (ICAL_PERIOD_VALUE ==
+ icalparameter_value_to_value_kind(ICAL_VALUE_PERIOD)));
+ ok("ICAL_BINARY_VALUE",(ICAL_BINARY_VALUE ==
+ icalparameter_value_to_value_kind(ICAL_VALUE_BINARY)));
+ ok("ICAL_TEXT_VALUE",(ICAL_TEXT_VALUE ==
+ icalparameter_value_to_value_kind(ICAL_VALUE_TEXT)));
+ ok("ICAL_DURATION_VALUE",(ICAL_DURATION_VALUE ==
+ icalparameter_value_to_value_kind(ICAL_VALUE_DURATION)));
+ ok("ICAL_INTEGER_VALUE",
+ (ICAL_INTEGER_VALUE == icalparameter_value_to_value_kind(ICAL_VALUE_INTEGER)));
+
+ ok("ICAL_URI_VALUE",
+ (ICAL_URI_VALUE == icalparameter_value_to_value_kind(ICAL_VALUE_URI)));
+ ok("ICAL_FLOAT_VALUE",(ICAL_FLOAT_VALUE ==
+ icalparameter_value_to_value_kind(ICAL_VALUE_FLOAT)));
+ ok("ICAL_X_VALUE",(ICAL_X_VALUE ==
+ icalparameter_value_to_value_kind(ICAL_VALUE_X)));
+ ok("ICAL_DATETIME_VALUE",(ICAL_DATETIME_VALUE ==
+ icalparameter_value_to_value_kind(ICAL_VALUE_DATETIME)));
+ ok("ICAL_DATE_TIME",(ICAL_DATE_VALUE ==
+ icalparameter_value_to_value_kind(ICAL_VALUE_DATE)));
+
+ /* v = icalvalue_new_caladdress(0);
+
+ printf("Bad string: %p\n",v);
+
+ if (v!=0) icalvalue_free(v); */
+
+ icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR, ICAL_ERROR_NONFATAL);
+ v = icalvalue_new_from_string(ICAL_RECUR_VALUE,"D2 #0");
+ ok("illegal recur value", (v == 0));
+
+ v = icalvalue_new_from_string(ICAL_TRIGGER_VALUE,"Gonk");
+ ok("illegal trigger value", (v == 0));
+
+ v = icalvalue_new_from_string(ICAL_REQUESTSTATUS_VALUE,"Gonk");
+ ok("illegal requeststatus value", (v == 0));
+
+ icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR, ICAL_ERROR_DEFAULT);
+}
+
+
+void test_properties()
+{
+ icalproperty *prop;
+ icalparameter *param;
+
+ icalproperty *clone;
+ char test_cn_str[128] = "";
+ char *test_cn_str_good = "A Common Name 1A Common Name 2A Common Name 3A Common Name 4";
+ char *test_ical_str_good = "COMMENT;CN=A Common Name 1;CN=A Common Name 2;CN=A Common Name 3;CN=A \r\n Common Name 4:Another Comment\r\n";
+
+ prop = icalproperty_vanew_comment(
+ "Another Comment",
+ icalparameter_new_cn("A Common Name 1"),
+ icalparameter_new_cn("A Common Name 2"),
+ icalparameter_new_cn("A Common Name 3"),
+ icalparameter_new_cn("A Common Name 4"),
+ (void *)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_get_cn(param);
+ if (VERBOSE) printf("Prop parameter: %s\n",icalparameter_get_cn(param));
+ strcat(test_cn_str, str);
+ }
+ is("fetching parameters", test_cn_str, test_cn_str_good);
+
+ if (VERBOSE) printf("Prop value: %s\n",icalproperty_get_comment(prop));
+ is("icalproperty_get_comment()",
+ icalproperty_get_comment(prop), "Another Comment");
+
+ if (VERBOSE) printf("As iCAL string:\n %s\n",icalproperty_as_ical_string(prop));
+
+ is("icalproperty_as_ical_string()",
+ icalproperty_as_ical_string(prop), test_ical_str_good);
+
+ clone = icalproperty_new_clone(prop);
+
+ if (VERBOSE) printf("Clone:\n %s\n",icalproperty_as_ical_string(prop));
+ is("icalproperty_new_clone()",
+ icalproperty_as_ical_string(prop), test_ical_str_good);
+
+ icalproperty_free(clone);
+ icalproperty_free(prop);
+
+ prop = icalproperty_new(-1);
+
+ ok("test icalproperty_new() with invalid type (-1)",
+ (prop == NULL));
+
+ if (prop!=0) icalproperty_free(prop);
+}
+
+void test_utf8()
+{
+ icalproperty *prop;
+ char *utf8text = "aáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaá";
+ char *test_ical_str_good = "DESCRIPTION:\r\n"
+" aáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaá\r\n"
+" óaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóaáóa\r\n"
+" áóaáóaáóaáóaáóaáóaáóaáóaáóaá\r\n";
+
+ prop = icalproperty_new_description(utf8text);
+
+ is("icalproperty_as_ical_string()",
+ icalproperty_as_ical_string(prop), test_ical_str_good);
+ icalproperty_free(prop);
+}
+
+
+
+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(str1);
+
+ is("icalparameter_new_cn()", icalparameter_get_cn(p), str1);
+ is("icalparameter_as_ical_string()" ,icalparameter_as_ical_string(p),"CN=A Common Name");
+
+ icalparameter_free(p);
+
+ p = icalparameter_new_from_string("PARTSTAT=ACCEPTED");
+ ok("PARTSTAT_PARAMETER", (icalparameter_isa(p) == ICAL_PARTSTAT_PARAMETER));
+ ok("PARTSTAT_ACCEPTED", (icalparameter_get_partstat(p) == ICAL_PARTSTAT_ACCEPTED));
+
+ icalparameter_free(p);
+
+ p = icalparameter_new_from_string("ROLE=CHAIR");
+
+ ok("ROLE_PARAMETER", (icalparameter_isa(p) == ICAL_ROLE_PARAMETER));
+ ok("ROLE_CHAIR", (icalparameter_get_partstat(p) == ICAL_ROLE_CHAIR));
+
+ icalparameter_free(p);
+
+ p = icalparameter_new_from_string("PARTSTAT=X-FOO");
+ ok("PARTSTAT_PARAMETER", (icalparameter_isa(p) == ICAL_PARTSTAT_PARAMETER));
+ ok("PARTSTAT_X", (icalparameter_get_partstat(p) == ICAL_PARTSTAT_X));
+
+ icalparameter_free(p);
+
+ p = icalparameter_new_from_string("X-PARAM=X-FOO");
+ ok("X_PARAMETER", (icalparameter_isa(p) == ICAL_X_PARAMETER));
+
+ icalparameter_free(p);
+
+
+ for (i=0;enums[i] != -1; i++){
+ if (VERBOSE) printf("%s\n",icalparameter_enum_to_string(enums[i]));
+ ok("test paramter enums",
+ (icalparameter_string_to_enum(icalparameter_enum_to_string(enums[i]))==enums[i]));
+ }
+}
+
+
+char *good_child =
+"BEGIN:VEVENT\r\n"
+"VERSION:2.0\r\n"
+"DESCRIPTION:This is an event\r\n"
+"COMMENT;CN=A Common Name 1;CN=A Common Name 2;CN=A Common Name 3;CN=A \r\n"
+" Common Name 4:Another Comment\r\n"
+"X-LIC-ERROR;X-LIC-ERRORTYPE=COMPONENT-PARSE-ERROR:This is only a test\r\n"
+"END:VEVENT\r\n";
+
+void test_components()
+{
+ icalcomponent* c;
+ icalcomponent* child;
+
+ c = icalcomponent_vanew(
+ ICAL_VCALENDAR_COMPONENT,
+ icalproperty_new_version("2.0"),
+ icalproperty_new_prodid("-//RDU Software//NONSGML HandCal//EN"),
+ icalproperty_vanew_comment(
+ "A Comment",
+ icalparameter_new_cn("A Common Name 1"),
+ (void *)0),
+ icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_new_version("2.0"),
+ icalproperty_new_description("This is an event"),
+ icalproperty_vanew_comment(
+ "Another Comment",
+ icalparameter_new_cn("A Common Name 1"),
+ icalparameter_new_cn("A Common Name 2"),
+ icalparameter_new_cn("A Common Name 3"),
+ icalparameter_new_cn("A Common Name 4"),
+ (void *)0),
+ icalproperty_vanew_xlicerror(
+ "This is only a test",
+ icalparameter_new_xlicerrortype(ICAL_XLICERRORTYPE_COMPONENTPARSEERROR),
+ (void *)0),
+
+ 0
+ ),
+ 0
+ );
+
+ if (VERBOSE)
+ printf("Original Component:\n%s\n\n",icalcomponent_as_ical_string(c));
+
+ child = icalcomponent_get_first_component(c,ICAL_VEVENT_COMPONENT);
+
+ ok("test icalcomponent_get_first_component()",
+ (child != NULL));
+
+ if (VERBOSE)
+ printf("Child Component:\n%s\n\n",icalcomponent_as_ical_string(child));
+
+ is("test results of child component",
+ icalcomponent_as_ical_string(child), good_child);
+
+ icalcomponent_free(c);
+}
+
+
+void test_memory()
+{
+ size_t bufsize = 256;
+ int i;
+ char *p;
+
+ char S1[] = "1) When in the Course of human events, ";
+ char S2[] = "2) it becomes necessary for one people to dissolve the political bands which have connected them with another, ";
+ char S3[] = "3) and to assume among the powers of the earth, ";
+ char S4[] = "4) the separate and equal station to which the Laws of Nature and of Nature's God entitle them, ";
+ char S5[] = "5) a decent respect to the opinions of mankind requires that they ";
+ char S6[] = "6) should declare the causes which impel them to the separation. ";
+ char S7[] = "7) We hold these truths to be self-evident, ";
+ char S8[] = "8) that all men are created equal, ";
+
+/* char S9[] = "9) that they are endowed by their Creator with certain unalienable Rights, ";
+ char S10[] = "10) that among these are Life, Liberty, and the pursuit of Happiness. ";
+ char S11[] = "11) That to secure these rights, Governments are instituted among Men, ";
+ char S12[] = "12) deriving their just powers from the consent of the governed. ";
+*/
+
+
+ char *f, *b1, *b2, *b3, *b4, *b5, *b6, *b7, *b8;
+
+#define BUFSIZE 1024
+
+ f = icalmemory_new_buffer(bufsize);
+ p = f;
+ b1 = icalmemory_tmp_buffer(BUFSIZE);
+ strcpy(b1, S1);
+ icalmemory_append_string(&f, &p, &bufsize, b1);
+
+ b2 = icalmemory_tmp_buffer(BUFSIZE);
+ strcpy(b2, S2);
+ icalmemory_append_string(&f, &p, &bufsize, b2);
+
+ b3 = icalmemory_tmp_buffer(BUFSIZE);
+ strcpy(b3, S3);
+ icalmemory_append_string(&f, &p, &bufsize, b3);
+
+ b4 = icalmemory_tmp_buffer(BUFSIZE);
+ strcpy(b4, S4);
+ icalmemory_append_string(&f, &p, &bufsize, b4);
+
+ b5 = icalmemory_tmp_buffer(BUFSIZE);
+ strcpy(b5, S5);
+ icalmemory_append_string(&f, &p, &bufsize, b5);
+
+ b6 = icalmemory_tmp_buffer(BUFSIZE);
+ strcpy(b6, S6);
+ icalmemory_append_string(&f, &p, &bufsize, b6);
+
+ b7 = icalmemory_tmp_buffer(BUFSIZE);
+ strcpy(b7, S7);
+ icalmemory_append_string(&f, &p, &bufsize, b7);
+
+ b8 = icalmemory_tmp_buffer(BUFSIZE);
+ strcpy(b8, S8);
+ icalmemory_append_string(&f, &p, &bufsize, b8);
+
+
+ if (VERBOSE) {
+ printf("1: %p %s \n",b1,b1);
+ printf("2: %p %s\n",b2,b2);
+ printf("3: %p %s\n",b3,b3);
+ printf("4: %p %s\n",b4,b4);
+ printf("5: %p %s\n",b5,b5);
+ printf("6: %p %s\n",b6,b6);
+ printf("7: %p %s\n",b7,b7);
+ printf("8: %p %s\n",b8,b8);
+
+
+ printf("Final: %s\n", f);
+
+ printf("Final buffer size: %zd\n",bufsize);
+ }
+
+ ok("final buffer size == 806", (bufsize == 806));
+
+ free(f);
+
+ bufsize = 4;
+
+ f = icalmemory_new_buffer(bufsize);
+
+ memset(f,0,bufsize);
+ p = f;
+
+ icalmemory_append_char(&f, &p, &bufsize, 'a');
+ if (VERBOSE) printf("Char-by-Char buffer: %s\n", f);
+
+ icalmemory_append_char(&f, &p, &bufsize, 'b');
+ if (VERBOSE) printf("Char-by-Char buffer: %s\n", f);
+ icalmemory_append_char(&f, &p, &bufsize, 'c');
+ if (VERBOSE) printf("Char-by-Char buffer: %s\n", f);
+ icalmemory_append_char(&f, &p, &bufsize, 'd');
+ if (VERBOSE) printf("Char-by-Char buffer: %s\n", f);
+ icalmemory_append_char(&f, &p, &bufsize, 'e');
+ if (VERBOSE) printf("Char-by-Char buffer: %s\n", f);
+ icalmemory_append_char(&f, &p, &bufsize, 'f');
+ if (VERBOSE) printf("Char-by-Char buffer: %s\n", f);
+ icalmemory_append_char(&f, &p, &bufsize, 'g');
+ if (VERBOSE) printf("Char-by-Char buffer: %s\n", f);
+ icalmemory_append_char(&f, &p, &bufsize, 'h');
+ if (VERBOSE) printf("Char-by-Char buffer: %s\n", f);
+ icalmemory_append_char(&f, &p, &bufsize, 'i');
+ if (VERBOSE) printf("Char-by-Char buffer: %s\n", f);
+ icalmemory_append_char(&f, &p, &bufsize, 'j');
+ if (VERBOSE) printf("Char-by-Char buffer: %s\n", f);
+ icalmemory_append_char(&f, &p, &bufsize, 'a');
+ if (VERBOSE) printf("Char-by-Char buffer: %s\n", f);
+ icalmemory_append_char(&f, &p, &bufsize, 'b');
+ if (VERBOSE) printf("Char-by-Char buffer: %s\n", f);
+ icalmemory_append_char(&f, &p, &bufsize, 'c');
+ if (VERBOSE) printf("Char-by-Char buffer: %s\n", f);
+ icalmemory_append_char(&f, &p, &bufsize, 'd');
+ if (VERBOSE) printf("Char-by-Char buffer: %s\n", f);
+ icalmemory_append_char(&f, &p, &bufsize, 'e');
+ if (VERBOSE) printf("Char-by-Char buffer: %s\n", f);
+ icalmemory_append_char(&f, &p, &bufsize, 'f');
+ if (VERBOSE) printf("Char-by-Char buffer: %s\n", f);
+ icalmemory_append_char(&f, &p, &bufsize, 'g');
+ if (VERBOSE) printf("Char-by-Char buffer: %s\n", f);
+ icalmemory_append_char(&f, &p, &bufsize, 'h');
+ if (VERBOSE) printf("Char-by-Char buffer: %s\n", f);
+ icalmemory_append_char(&f, &p, &bufsize, 'i');
+ if (VERBOSE) printf("Char-by-Char buffer: %s\n", f);
+ icalmemory_append_char(&f, &p, &bufsize, 'j');
+ if (VERBOSE) printf("Char-by-Char buffer: %s\n", f);
+
+ free(f);
+
+ for(i=0; i<100; i++){
+ f = icalmemory_tmp_buffer(bufsize);
+
+ assert(f!=0);
+
+ memset(f,0,bufsize);
+ sprintf(f,"%d",i);
+ }
+}
+
+
+void test_dirset()
+{
+ icalcomponent *c;
+ icalgauge *gauge;
+ icalerrorenum error;
+ icalcomponent *next, *itr;
+ icalset* cluster;
+ icalset *s, *s2;
+ struct icalperiodtype rtime;
+ int i;
+ int count = 0;
+
+#ifndef _WIN32
+ mkdir("store", 0755);
+ mkdir("store-new", 0755);
+#else
+ mkdir("store");
+ mkdir("store-new");
+#endif
+
+ s = icaldirset_new("store");
+ s2 = icaldirset_new("store-new");
+
+ ok("opening 'store' dirset", s!=NULL);
+ ok("opening 'store-new' dirset", s2!=NULL);
+
+ rtime.start = icaltime_from_timet( time(0),0);
+
+ cluster = icalfileset_new("clusterin.vcd");
+
+ if (cluster == 0){
+ printf("Failed to create cluster: %s\n",icalerror_strerror(icalerrno));
+ }
+
+#define NUMCOMP 4
+
+ /* Duplicate every component in the cluster NUMCOMP times */
+
+ icalerror_clear_errno();
+
+ for (i = 1; i<NUMCOMP+1; i++){
+
+ /*rtime.start.month = i%12;*/
+ rtime.start.month = i;
+ rtime.end = rtime.start;
+ rtime.end.hour++;
+
+ for (itr = icalfileset_get_first_component(cluster);
+ itr != 0;
+ itr = icalfileset_get_next_component(cluster)){
+ icalcomponent *clone;
+ icalproperty *p;
+
+
+ if(icalcomponent_isa(itr) != ICAL_VEVENT_COMPONENT){
+ continue;
+ }
+
+
+ /* Change the dtstart and dtend times in the component
+ pointed to by Itr*/
+
+ clone = icalcomponent_new_clone(itr);
+ assert(icalerrno == ICAL_NO_ERROR);
+ assert(clone !=0);
+
+ /* DTSTART*/
+ p = icalcomponent_get_first_property(clone,ICAL_DTSTART_PROPERTY);
+ assert(icalerrno == ICAL_NO_ERROR);
+
+ if (p == 0){
+ p = icalproperty_new_dtstart(rtime.start);
+ icalcomponent_add_property(clone,p);
+ } else {
+ icalproperty_set_dtstart(p,rtime.start);
+ }
+ assert(icalerrno == ICAL_NO_ERROR);
+
+ /* DTEND*/
+ p = icalcomponent_get_first_property(clone,ICAL_DTEND_PROPERTY);
+ assert(icalerrno == ICAL_NO_ERROR);
+
+ if (p == 0){
+ p = icalproperty_new_dtstart(rtime.end);
+ icalcomponent_add_property(clone,p);
+ } else {
+ icalproperty_set_dtstart(p,rtime.end);
+ }
+ assert(icalerrno == ICAL_NO_ERROR);
+
+ printf("\n----------\n%s\n---------\n",icalcomponent_as_ical_string(clone));
+
+ error = icaldirset_add_component(s,clone);
+
+ assert(icalerrno == ICAL_NO_ERROR);
+ }
+ }
+
+ gauge = icalgauge_new_from_sql("SELECT * FROM VEVENT WHERE VEVENT.SUMMARY = 'Submit Income Taxes' OR VEVENT.SUMMARY = 'Bastille Day Party'", 0);
+
+ icaldirset_select(s,gauge);
+
+ for(c = icaldirset_get_first_component(s); c != 0; c = icaldirset_get_next_component(s)){
+ printf("Got one! (%d)\n", count++);
+
+ if (c != 0){
+ printf("%s", icalcomponent_as_ical_string(c));;
+ if (icaldirset_add_component(s2,c) == 0){
+ printf("Failed to write!\n");
+ }
+ icalcomponent_free(c);
+ } else {
+ printf("Failed to get component\n");
+ }
+ }
+
+
+ icalset_free(s2);
+
+ for(c = icaldirset_get_first_component(s);
+ c != 0;
+ c = next){
+
+ next = icaldirset_get_next_component(s);
+
+ if (c != 0){
+ /*icaldirset_remove_component(s,c);*/
+ printf("%s", icalcomponent_as_ical_string(c));;
+ } else {
+ printf("Failed to get component\n");
+ }
+ }
+
+ icalset_free(s);
+ icalset_free(cluster);
+}
+
+
+void test_compare()
+{
+ icalvalue *v1, *v2;
+
+ v1 = icalvalue_new_caladdress("cap://value/1");
+ v2 = icalvalue_new_clone(v1);
+
+ ok("compare value and clone",
+ (icalvalue_compare(v1,v2) == ICAL_XLICCOMPARETYPE_EQUAL));
+
+ icalvalue_free(v1);
+ icalvalue_free(v2);
+
+ v1 = icalvalue_new_caladdress("A");
+ v2 = icalvalue_new_caladdress("B");
+
+ ok("test compare of A and B results in LESS",
+ (icalvalue_compare(v1,v2) == ICAL_XLICCOMPARETYPE_LESS));
+
+ ok("test compare of B and A results in GREATER",
+ (icalvalue_compare(v2,v1) == ICAL_XLICCOMPARETYPE_GREATER));
+
+ icalvalue_free(v1);
+ icalvalue_free(v2);
+
+ v1 = icalvalue_new_caladdress("B");
+ v2 = icalvalue_new_caladdress("A");
+
+ ok("test compare of caladdress A and B results in GREATER",
+ (icalvalue_compare(v1,v2) == ICAL_XLICCOMPARETYPE_GREATER));
+
+ icalvalue_free(v1);
+ icalvalue_free(v2);
+
+ v1 = icalvalue_new_integer(5);
+ v2 = icalvalue_new_integer(5);
+
+ ok("test compare of 5 and 5 results in EQUAL",
+ (icalvalue_compare(v1,v2) == ICAL_XLICCOMPARETYPE_EQUAL));
+
+ icalvalue_free(v1);
+ icalvalue_free(v2);
+
+ v1 = icalvalue_new_integer(5);
+ v2 = icalvalue_new_integer(10);
+
+ ok("test compare of 5 and 10 results in LESS",
+ (icalvalue_compare(v1,v2) == ICAL_XLICCOMPARETYPE_LESS));
+
+ ok("test compare of 10 and 5 results in GREATER",
+ (icalvalue_compare(v2,v1) == ICAL_XLICCOMPARETYPE_GREATER));
+
+ icalvalue_free(v1);
+ icalvalue_free(v2);
+}
+
+
+void test_restriction()
+{
+ icalcomponent *comp;
+ struct icaltimetype atime = icaltime_from_timet( time(0),0);
+ int valid;
+
+ struct icaldatetimeperiodtype rtime;
+
+ char *str;
+
+ rtime.period.start = icaltime_from_timet( time(0),0);
+ rtime.period.end = icaltime_from_timet( time(0),0);
+ rtime.period.end.hour++;
+ rtime.time = icaltime_null_time();
+
+ comp =
+ icalcomponent_vanew(
+ ICAL_VCALENDAR_COMPONENT,
+ icalproperty_new_version("2.0"),
+ icalproperty_new_prodid("-//RDU Software//NONSGML HandCal//EN"),
+ icalproperty_new_method(ICAL_METHOD_REQUEST),
+ icalcomponent_vanew(
+ ICAL_VTIMEZONE_COMPONENT,
+ icalproperty_new_tzid("America/New_York"),
+ icalcomponent_vanew(
+ ICAL_XDAYLIGHT_COMPONENT,
+ icalproperty_new_dtstart(atime),
+ icalproperty_new_rdate(rtime),
+ icalproperty_new_tzoffsetfrom(-4.0),
+ icalproperty_new_tzoffsetto(-5.0),
+ icalproperty_new_tzname("EST"),
+ (void *)0),
+ icalcomponent_vanew(
+ ICAL_XSTANDARD_COMPONENT,
+ icalproperty_new_dtstart(atime),
+ icalproperty_new_rdate(rtime),
+ icalproperty_new_tzoffsetfrom(-5.0),
+ icalproperty_new_tzoffsetto(-4.0),
+ icalproperty_new_tzname("EST"),
+ (void *)0),
+ (void *)0),
+ icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_new_dtstamp(atime),
+ icalproperty_new_uid("guid-1.host1.com"),
+ icalproperty_vanew_organizer(
+ "mrbig@host.com",
+ icalparameter_new_role(ICAL_ROLE_CHAIR),
+ (void *)0),
+ icalproperty_vanew_attendee(
+ "employee-A@host.com",
+ icalparameter_new_role(ICAL_ROLE_REQPARTICIPANT),
+ icalparameter_new_rsvp(ICAL_RSVP_TRUE),
+ icalparameter_new_cutype(ICAL_CUTYPE_GROUP),
+ (void *)0),
+ icalproperty_new_description("Project XYZ Review Meeting"),
+ icalproperty_new_categories("MEETING"),
+ icalproperty_new_class(ICAL_CLASS_PUBLIC),
+ icalproperty_new_created(atime),
+ icalproperty_new_summary("XYZ Project Review"),
+ /* icalproperty_new_dtstart(
+ atime,
+ icalparameter_new_tzid("America/New_York"),
+ 0
+ ),*/
+ icalproperty_vanew_dtend(
+ atime,
+ icalparameter_new_tzid("America/New_York"),
+ (void *)0),
+ icalproperty_new_location("1CP Conference Room 4350"),
+ (void *)0),
+ (void *)0);
+
+ valid = icalrestriction_check(comp);
+
+ ok("icalrestriction_check() == 0", (valid==0));
+
+ str = icalcomponent_as_ical_string(comp);
+
+ icalcomponent_free(comp);
+
+}
+
+void test_calendar()
+{
+ icalcomponent *comp;
+ icalset *c;
+ icalset *s;
+ icalcalendar* calendar;
+ icalerrorenum error;
+ struct icaltimetype atime = icaltime_from_timet( time(0),0);
+
+#ifndef _WIN32
+ mkdir("calendar", 0755);
+ mkdir("calendar/booked", 0755);
+#else
+ mkdir("calendar");
+ mkdir("calendar/booked");
+#endif
+
+ calendar = icalcalendar_new("calendar");
+
+ comp = icalcomponent_vanew(ICAL_VCALENDAR_COMPONENT,
+ icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_new_version("2.0"),
+ icalproperty_new_description("This is an event"),
+ icalproperty_new_dtstart(atime),
+ icalproperty_vanew_comment(
+ "Another Comment",
+ icalparameter_new_cn("A Common Name 1"),
+ icalparameter_new_cn("A Common Name 2"),
+ icalparameter_new_cn("A Common Name 3"),
+ icalparameter_new_cn("A Common Name 4"),
+ (void *)0),
+ icalproperty_vanew_xlicerror(
+ "This is only a test",
+ icalparameter_new_xlicerrortype(ICAL_XLICERRORTYPE_COMPONENTPARSEERROR),
+ (void *)0),
+
+ (void *)0),(void *)0);
+
+ s = icalcalendar_get_booked(calendar);
+
+ error = icaldirset_add_component(s,comp);
+
+ ok("Adding Component to dirset", (error == ICAL_NO_ERROR));
+
+ c = icalcalendar_get_properties(calendar);
+
+ error = icalfileset_add_component(c,icalcomponent_new_clone(comp));
+
+ ok("Adding Clone Component to dirset", (error == ICAL_NO_ERROR));
+
+ icalcalendar_free(calendar);
+
+ ok("icalcalendar test", (1));
+}
+
+
+void test_increment(void);
+
+void print_occur(struct icalrecurrencetype recur, struct icaltimetype start)
+{
+ struct icaltimetype next;
+ icalrecur_iterator* ritr;
+
+ time_t tt = icaltime_as_timet(start);
+
+ printf("#### %s\n",icalrecurrencetype_as_string(&recur));
+ printf("#### %s\n",ctime(&tt ));
+
+ for(ritr = icalrecur_iterator_new(recur,start),
+ next = icalrecur_iterator_next(ritr);
+ !icaltime_is_null_time(next);
+ next = icalrecur_iterator_next(ritr)){
+
+ tt = icaltime_as_timet(next);
+
+ printf(" %s",ctime(&tt ));
+
+ }
+
+ icalrecur_iterator_free(ritr);
+}
+
+void test_recur()
+{
+ struct icalrecurrencetype rt;
+ struct icaltimetype start;
+ time_t array[25];
+ int i;
+
+ rt = icalrecurrencetype_from_string("FREQ=MONTHLY;UNTIL=19971224T000000Z;INTERVAL=1;BYDAY=TU,2FR,3SA");
+ start = icaltime_from_string("19970905T090000Z");
+
+ if (VERBOSE) print_occur(rt,start);
+
+ if (VERBOSE) printf("\n Using icalrecur_expand_recurrence\n");
+
+ icalrecur_expand_recurrence("FREQ=MONTHLY;UNTIL=19971224T000000Z;INTERVAL=1;BYDAY=TU,2FR,3SA",
+ icaltime_as_timet(start),
+ 25,
+ array);
+
+ for(i =0; array[i] != 0 && i < 25 ; i++){
+ if (VERBOSE) printf(" %s",ctime(&(array[i])));
+ }
+
+
+/* test_increment();*/
+
+}
+
+
+void test_expand_recurrence(){
+
+ time_t arr[10];
+ time_t now = 931057385;
+ int i, numfound = 0;
+ icalrecur_expand_recurrence( "FREQ=MONTHLY;BYDAY=MO,WE", now,
+ 5, arr );
+
+ if (VERBOSE) printf("Start %s",ctime(&now) );
+
+ for (i=0; i<5; i++) {
+ numfound++;
+ if (VERBOSE) printf("i=%d %s\n", i, ctime(&arr[i]) );
+ }
+ int_is("Get an array of 5 items", numfound, 5);
+}
+
+
+
+enum byrule {
+ NO_CONTRACTION = -1,
+ BY_SECOND = 0,
+ BY_MINUTE = 1,
+ BY_HOUR = 2,
+ BY_DAY = 3,
+ BY_MONTH_DAY = 4,
+ BY_YEAR_DAY = 5,
+ BY_WEEK_NO = 6,
+ BY_MONTH = 7,
+ BY_SET_POS
+};
+
+void icalrecurrencetype_test()
+{
+ icalvalue *v = icalvalue_new_from_string(
+ ICAL_RECUR_VALUE,
+ "FREQ=YEARLY;UNTIL=20060101T000000;INTERVAL=2;BYDAY=SU,WE;BYSECOND=15,30; BYMONTH=1,6,11");
+
+ struct icalrecurrencetype r = icalvalue_get_recur(v);
+ struct icaltimetype t = icaltime_from_timet( time(0), 0);
+ struct icaltimetype next;
+ time_t tt;
+
+ struct icalrecur_iterator_impl* itr
+ = (struct icalrecur_iterator_impl*) icalrecur_iterator_new(r,t);
+
+ do {
+
+ next = icalrecur_iterator_next(itr);
+ tt = icaltime_as_timet(next);
+
+ printf("%s",ctime(&tt ));
+
+ } while( ! icaltime_is_null_time(next));
+
+ icalvalue_free(v);
+
+ icalrecur_iterator_free(itr);
+
+}
+
+/* From Federico Mena Quintero <federico@ximian.com> */
+void test_recur_parameter_bug(){
+
+ static const char test_icalcomp_str[] =
+"BEGIN:VEVENT\r\n"
+"RRULE;X-EVOLUTION-ENDDATE=20030209T081500:FREQ=DAILY;COUNT=10;INTERVAL=6\r\n"
+"END:VEVENT\r\n";
+
+ icalcomponent *icalcomp;
+ icalproperty *prop;
+ struct icalrecurrencetype recur;
+ int n_errors;
+ char *str;
+
+ icalcomp = icalparser_parse_string ((char *) test_icalcomp_str);
+ ok("icalparser_parse_string()",(icalcomp!=NULL));
+ assert(icalcomp!=NULL);
+
+ str = icalcomponent_as_ical_string(icalcomp);
+ is("parsed matches original", str, (char*)test_icalcomp_str);
+ if (VERBOSE) printf("%s\n\n",str);
+
+ n_errors = icalcomponent_count_errors (icalcomp);
+ int_is("no parse errors", n_errors, 0);
+
+ if (n_errors) {
+ icalproperty *p;
+
+ for (p = icalcomponent_get_first_property (icalcomp,
+ ICAL_XLICERROR_PROPERTY);
+ p;
+ p = icalcomponent_get_next_property (icalcomp,
+ ICAL_XLICERROR_PROPERTY)) {
+ const char *str;
+
+ str = icalproperty_as_ical_string (p);
+ fprintf (stderr, "error: %s\n", str);
+ }
+ }
+
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY);
+ ok("get RRULE property", (prop!=NULL));
+ assert(prop!=NULL);
+
+ recur = icalproperty_get_rrule (prop);
+
+ if (VERBOSE) printf("%s\n",icalrecurrencetype_as_string(&recur));
+
+ icalcomponent_free(icalcomp);
+}
+
+
+void test_duration()
+{
+ struct icaldurationtype d;
+
+ d = icaldurationtype_from_string("PT8H30M");
+ if (VERBOSE) printf("%s\n",icaldurationtype_as_ical_string(d));
+ int_is("PT8H30M", icaldurationtype_as_int(d), 30600);
+
+ d = icaldurationtype_from_string("-PT8H30M");
+ if (VERBOSE) printf("%s\n",icaldurationtype_as_ical_string(d));
+ int_is("-PT8H30M", icaldurationtype_as_int(d), -30600);
+
+ d = icaldurationtype_from_string("PT10H10M10S");
+ if (VERBOSE) printf("%s\n",icaldurationtype_as_ical_string(d));
+ int_is("PT10H10M10S", icaldurationtype_as_int(d), 36610);
+
+ d = icaldurationtype_from_string("P7W");
+ if (VERBOSE) printf("%s\n",icaldurationtype_as_ical_string(d));
+ int_is("P7W", icaldurationtype_as_int(d), 4233600);
+
+ d = icaldurationtype_from_string("P2DT8H30M");
+ if (VERBOSE) printf("%s\n",icaldurationtype_as_ical_string(d));
+ int_is("P2DT8H30M", icaldurationtype_as_int(d), 203400);
+
+ d = icaldurationtype_from_string("P2W1DT5H");
+ if (VERBOSE) printf("%s %d\n",icaldurationtype_as_ical_string(d),
+ icaldurationtype_as_int(d));
+ int_is("P2W1DT5H", icaldurationtype_as_int(d), 1314000);
+
+ icalerror_errors_are_fatal = 0;
+
+ /* Test conversion of bad input */
+
+ d = icaldurationtype_from_int(1314000);
+ if (VERBOSE) printf("%s %d\n",icaldurationtype_as_ical_string(d),
+ icaldurationtype_as_int(d));
+ is("1314000", icaldurationtype_as_ical_string(d), "P15DT5H");
+
+ d = icaldurationtype_from_string("P-2DT8H30M");
+ if (VERBOSE) printf("%s\n",icaldurationtype_as_ical_string(d));
+ int_is("P-2DT8H30M", icaldurationtype_as_int(d), 0);
+
+ d = icaldurationtype_from_string("P7W8H");
+ if (VERBOSE) printf("%s\n",icaldurationtype_as_ical_string(d));
+ int_is("P7W8H", icaldurationtype_as_int(d), 0);
+
+ d = icaldurationtype_from_string("T10H");
+ if (VERBOSE) printf("%s\n",icaldurationtype_as_ical_string(d));
+ int_is("T10H", icaldurationtype_as_int(d), 0);
+
+ icalerror_errors_are_fatal = 1;
+
+ d = icaldurationtype_from_int(4233600);
+ if (VERBOSE) printf("%s\n",icaldurationtype_as_ical_string(d));
+ is("P7W",
+ icaldurationtype_as_ical_string(d), "P7W");
+
+ d = icaldurationtype_from_int(4424400);
+ if (VERBOSE) printf("%s\n",icaldurationtype_as_ical_string(d));
+ is("P51DT5H",
+ icaldurationtype_as_ical_string(d), "P51DT5H");
+}
+
+
+void test_period()
+{
+ struct icalperiodtype p;
+ icalvalue *v;
+ char *str;
+
+ str = "19971015T050000Z/PT8H30M";
+ p = icalperiodtype_from_string(str);
+ is(str, icalperiodtype_as_ical_string(p),str);
+
+
+ str = "19971015T050000Z/19971015T060000Z";
+ p = icalperiodtype_from_string(str);
+ is(str, icalperiodtype_as_ical_string(p),str);
+
+
+ str = "19970101T120000/PT3H";
+
+ v = icalvalue_new_from_string(ICAL_PERIOD_VALUE,str);
+ is(str, icalvalue_as_ical_string(v), str);
+
+ icalvalue_free(v);
+}
+
+
+void test_strings(){
+ icalvalue *v;
+
+ v = icalvalue_new_text("foo;bar;bats");
+ if (VERBOSE)
+ printf("%s\n",icalvalue_as_ical_string(v));
+
+ is("test encoding of 'foo;bar;bats'",
+ "foo\\;bar\\;bats", icalvalue_as_ical_string(v));
+
+ icalvalue_free(v);
+
+
+ v = icalvalue_new_text("foo\\;b\nar\\;ba\tts");
+ if (VERBOSE)
+ printf("%s\n",icalvalue_as_ical_string(v));
+
+ is("test encoding of 'foo\\\\;b\\nar\\\\;ba\\tts'",
+ "foo\\\\\\;b\\nar\\\\\\;ba\\tts", icalvalue_as_ical_string(v));
+
+ icalvalue_free(v);
+}
+
+
+#ifdef INVALID_TEST
+/* This test is invalid because parameters may not have control chars, such as '\n' */
+void test_tzid_escape(){
+ icalparameter *tzid;
+ icalproperty *prop;
+
+ tzid = icalparameter_new_tzid("Timezone\nwith a newline");
+ prop = icalproperty_new_dtstart(icaltime_from_day_of_year(26, 2009));
+ icalproperty_add_parameter(prop, tzid);
+
+ if (VERBOSE)
+ printf("%s\n",icalproperty_as_ical_string(prop));
+
+ is("test encoding of 'Timezone\\nwith a newline'",
+ icalproperty_as_ical_string(prop), "DTSTART;VALUE=DATE,TZID=Timezone\\nwith a newline:20090126");
+
+ icalproperty_free(prop);
+}
+#endif
+
+
+void test_requeststat()
+{
+ icalcomponent *c;
+ icalproperty *p;
+ icalrequeststatus s;
+ struct icalreqstattype st, st2;
+ char temp[1024];
+
+ static const char test_icalcomp_str[] =
+"BEGIN:VEVENT\n"
+"REQUEST-STATUS:2.1;Success but fallback taken on one or more property values.;booga\n"
+"END:VEVENT\n";
+
+ s = icalenum_num_to_reqstat(2,1);
+
+ ok("icalenum_num_to_reqstat(2,1)",(s == ICAL_2_1_FALLBACK_STATUS));
+
+ ok("icalenum_reqstat_major()",(icalenum_reqstat_major(s) == 2));
+ ok("icalenum_reqstat_minor()",(icalenum_reqstat_minor(s) == 1));
+
+ is ("icalenum_reqstat_desc() -> 2.1", icalenum_reqstat_desc(s),
+ "Success but fallback taken on one or more property values.");
+
+ st.code = s;
+ st.debug = "booga";
+ st.desc = 0;
+
+ is("icalreqstattype_as_string()",
+ icalreqstattype_as_string(st),
+ "2.1;Success but fallback taken on one or more property values.;booga");
+
+ st.desc = " A non-standard description";
+
+ is("icalreqstattype_as_string() w/ non standard description",
+ icalreqstattype_as_string(st),
+ "2.1; A non-standard description;booga");
+
+ st.desc = 0;
+
+ sprintf(temp,"%s\n",icalreqstattype_as_string(st));
+
+
+ st2 = icalreqstattype_from_string("2.1;Success but fallback taken on one or more property values.;booga");
+
+ /* printf("%d -- %d -- %s -- %s\n",*/
+ ok("icalenum_reqstat_major()",(icalenum_reqstat_major(st2.code) == 2));
+ ok("icalenum_reqstat_minor()",(icalenum_reqstat_minor(st2.code) == 1));
+ is("icalenum_reqstat_desc",
+ icalenum_reqstat_desc(st2.code),
+ "Success but fallback taken on one or more property values.");
+
+ st2 = icalreqstattype_from_string("2.1;Success but fallback taken on one or more property values.;booga");
+ if (VERBOSE) printf("%s\n",icalreqstattype_as_string(st2));
+
+ st2 = icalreqstattype_from_string("2.1;Success but fallback taken on one or more property values.;");
+ if (VERBOSE) printf("%s\n",icalreqstattype_as_string(st2));
+
+ st2 = icalreqstattype_from_string("2.1;Success but fallback taken on one or more property values.");
+ if (VERBOSE) printf("%s\n",icalreqstattype_as_string(st2));
+
+ st2 = icalreqstattype_from_string("2.1;");
+ if (VERBOSE) printf("%s\n",icalreqstattype_as_string(st2));
+
+ is("st2 test again",
+ icalreqstattype_as_string(st2),
+ "2.1;Success but fallback taken on one or more property values.");
+
+ st2 = icalreqstattype_from_string("2.1");
+ is("st2 test #3",
+ icalreqstattype_as_string(st2),
+ "2.1;Success but fallback taken on one or more property values.");
+
+ c = icalparser_parse_string ((char *) test_icalcomp_str);
+ ok("icalparser_parse_string()", (c != NULL));
+ if (!c) {
+ exit (EXIT_FAILURE);
+ }
+
+ if (VERBOSE) printf("%s",icalcomponent_as_ical_string(c));
+
+ p = icalcomponent_get_first_property(c,ICAL_REQUESTSTATUS_PROPERTY);
+
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ is("icalproperty_new_from_string()",
+ icalproperty_as_ical_string(p),
+ "REQUEST-STATUS:2.1;Success but fallback taken on one or more property \n values.;booga\n");
+#endif
+
+ icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,ICAL_ERROR_NONFATAL);
+ st2 = icalreqstattype_from_string("16.4");
+
+ ok("test unknown code", (st2.code == ICAL_UNKNOWN_STATUS));
+
+ st2 = icalreqstattype_from_string("1.");
+
+ ok("test malformed code", (st2.code == ICAL_UNKNOWN_STATUS));
+ icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,ICAL_ERROR_DEFAULT);
+
+ icalproperty_free(p);
+}
+
+
+void test_dtstart(){
+
+ struct icaltimetype tt,tt2;
+
+ icalproperty *p;
+
+
+ tt = icaltime_from_string("19970101");
+
+ int_is("19970101 is a date", tt.is_date, 1);
+
+ p = icalproperty_new_dtstart(tt);
+
+ if (VERBOSE) printf("%s\n",icalvalue_kind_to_string(icalvalue_isa(icalproperty_get_value(p))));
+
+ ok("ICAL_DATE_VALUE", (icalvalue_isa(icalproperty_get_value(p))==ICAL_DATE_VALUE));
+
+ tt2 = icalproperty_get_dtstart(p);
+ int_is("converted date is date", tt2.is_date, 1);
+
+ if (VERBOSE) printf("%s\n",icalproperty_as_ical_string(p));
+
+ tt = icaltime_from_string("19970101T103000");
+
+ int_is("19970101T103000 is not a date", tt.is_date, 0);
+
+ icalproperty_free(p);
+
+ p = icalproperty_new_dtstart(tt);
+
+ if (VERBOSE) printf("%s\n",icalvalue_kind_to_string(icalvalue_isa(icalproperty_get_value(p))));
+ ok("ICAL_DATETIME_VALUE", (icalvalue_isa(icalproperty_get_value(p))==ICAL_DATETIME_VALUE));
+
+ tt2 = icalproperty_get_dtstart(p);
+ int_is("converted datetime is not date", tt2.is_date, 0);
+
+ if (VERBOSE) printf("%s\n",icalproperty_as_ical_string(p));
+
+ icalproperty_free(p);
+}
+
+void do_test_time(char* zone)
+{
+ struct icaltimetype ictt, icttutc, icttzone, icttdayl,
+ icttla, icttny,icttphoenix, icttlocal, icttnorm;
+ time_t tt,tt2, tt_p200;
+ int offset_tz;
+ icalvalue *v;
+ short day_of_week,start_day_of_week, day_of_year;
+ icaltimezone *azone, *utczone;
+ char msg[256];
+
+ icalerror_errors_are_fatal = 0;
+
+ azone = icaltimezone_get_builtin_timezone(zone);
+ utczone = icaltimezone_get_utc_timezone();
+
+ /* Test new API */
+ if (VERBOSE) printf("\n---> From time_t \n");
+
+ tt = 1025127869; /* stick with a constant... */
+
+ if (VERBOSE) printf("Orig : %s\n",ical_timet_string(tt));
+ if (VERBOSE) printf("\nicaltime_from_timet(tt,0) (DEPRECATED)\n");
+
+ ictt = icaltime_from_timet(tt, 0);
+
+ is("icaltime_from_timet(1025127869) as UTC", ictt_as_string(ictt),
+ "2002-06-26 21:44:29 (floating)");
+
+ ictt = icaltime_from_timet_with_zone(tt, 0, NULL);
+ is("Floating time from time_t",
+ ictt_as_string(ictt), "2002-06-26 21:44:29 (floating)");
+
+ ictt = icaltime_from_timet_with_zone(tt, 0, azone);
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ ok("icaltime_from_timet_with_zone(tt,0,zone) as zone",
+ strncmp(ictt_as_string(ictt), "2002-06-26 21:44:29", 19)==0);
+#endif
+
+ ictt = icaltime_from_timet_with_zone(tt, 0, utczone);
+
+ is("icaltime_from_timet_with_zone(tt,0,utc)", ictt_as_string(ictt),
+ "2002-06-26 21:44:29 Z UTC");
+
+ if (VERBOSE) printf("\n---> Convert from floating \n");
+
+ ictt = icaltime_from_timet_with_zone(tt, 0, NULL);
+ icttutc = icaltime_convert_to_zone(ictt, utczone);
+
+ is("Convert from floating to UTC",
+ ictt_as_string(icttutc),
+ "2002-06-26 21:44:29 Z UTC");
+
+ icttzone = icaltime_convert_to_zone(ictt, azone);
+ ok("Convert from floating to zone",
+ (strncmp(ictt_as_string(icttzone), "2002-06-26 21:44:29", 19)==0));
+
+ tt2 = icaltime_as_timet(icttzone);
+
+ if (VERBOSE) printf("\n---> Convert from UTC \n");
+
+ ictt = icaltime_from_timet_with_zone(tt, 0, utczone);
+ icttutc = icaltime_convert_to_zone(ictt, utczone);
+
+ is("Convert from UTC to UTC",
+ ictt_as_string(icttutc),
+ "2002-06-26 21:44:29 Z UTC");
+
+ icttzone = icaltime_convert_to_zone(ictt, azone);
+
+ ok("Convert from UTC to zone (test year/mon only..)",
+ (strncmp(ictt_as_string(icttzone), "2002-06-26 21:44:29", 7)==0));
+
+ tt2 = icaltime_as_timet(icttzone);
+
+ if (VERBOSE) printf("No conversion: %s\n", ical_timet_string(tt2));
+
+ ok("No conversion at all (test year/mon only)",
+ (strncmp(ical_timet_string(tt2), "2002-06-26 21:44:29 Z",7) == 0));
+
+ tt2 = icaltime_as_timet_with_zone(icttzone, utczone);
+ if (VERBOSE) printf("Back to UTC : %s\n", ical_timet_string(tt2));
+
+ ok("test time conversion routines",(tt==tt2));
+
+ if (VERBOSE) printf("\n---> Convert from zone \n");
+ ictt = icaltime_from_timet_with_zone(tt, 0, azone);
+ icttzone = icaltime_convert_to_zone(ictt, azone);
+
+ if (VERBOSE)
+ printf("To zone : %s\n", ictt_as_string(icttzone));
+ icttutc = icaltime_convert_to_zone(ictt, utczone);
+
+ if (VERBOSE)
+ printf("To UTC : %s\n", ictt_as_string(icttutc));
+ tt2 = icaltime_as_timet(icttutc);
+
+ if (VERBOSE)
+ printf("No conversion: %s\n", ical_timet_string(tt2));
+
+ tt2 = icaltime_as_timet_with_zone(icttutc, azone);
+
+ if (VERBOSE)
+ printf("Back to zone : %s\n", ical_timet_string(tt2));
+
+ ok("test time conversion, round 2", (tt==tt2));
+
+ ictt = icaltime_from_string("20001103T183030Z");
+
+ tt = icaltime_as_timet(ictt);
+
+ ok("test icaltime -> time_t for 20001103T183030Z", (tt==973276230));
+ /* Fri Nov 3 10:30:30 PST 2000 in PST
+ Fri Nov 3 18:30:30 PST 2000 in UTC */
+
+ if (VERBOSE) {
+ printf(" Normalize \n");
+ printf("Orig (ical) : %s\n", ictt_as_string(ictt));
+ }
+ icttnorm = ictt;
+ icttnorm.second -= 60 * 60 * 24 * 5;
+ icttnorm = icaltime_normalize(icttnorm);
+
+ if (VERBOSE)
+ printf("-5d in sec : %s\n", ictt_as_string(icttnorm));
+ icttnorm.day += 60;
+ icttnorm = icaltime_normalize(icttnorm);
+
+ if (VERBOSE)
+ printf("+60 d : %s\n", ictt_as_string(icttnorm));
+
+ /** add test case here.. **/
+
+ if (VERBOSE)
+ printf("\n As time_t \n");
+
+ tt2 = icaltime_as_timet(ictt);
+
+ if (VERBOSE) {
+ printf("20001103T183030Z (timet): %s\n",ical_timet_string(tt2));
+ printf("20001103T183030Z : %s\n",ictt_as_string(ictt));
+ }
+
+ /** this test is bogus **/
+ ok("test normalization", (tt2 == tt));
+
+ icttlocal = icaltime_convert_to_zone(ictt, azone);
+ tt2 = icaltime_as_timet(icttlocal);
+ if (VERBOSE) {
+ printf("20001103T183030 (timet): %s\n",ical_timet_string(tt2));
+ printf("20001103T183030 : %s\n",ictt_as_string(icttlocal));
+ }
+
+ offset_tz = -icaltimezone_get_utc_offset_of_utc_time(azone, &ictt, 0); /* FIXME */
+ if (VERBOSE)
+ printf("offset_tz : %d\n",offset_tz);
+
+ ok("test utc offset", (tt-tt2 == offset_tz));
+
+ /* FIXME with the new API, it's not very useful */
+ icttlocal = ictt;
+ icaltimezone_convert_time(&icttlocal,
+ icaltimezone_get_utc_timezone(),
+ icaltimezone_get_builtin_timezone(zone));
+
+ if (VERBOSE)
+ printf("As local : %s\n", ictt_as_string(icttlocal));
+
+ if (VERBOSE) printf("\n Convert to and from lib c \n");
+
+ if (VERBOSE) printf("System time is: %s\n",ical_timet_string(tt));
+
+ v = icalvalue_new_datetime(ictt);
+
+ if (VERBOSE)
+ printf("System time from libical: %s\n",icalvalue_as_ical_string(v));
+
+ icalvalue_free(v);
+
+ tt2 = icaltime_as_timet(ictt);
+
+ if (VERBOSE)
+ printf("Converted back to libc: %s\n",ical_timet_string(tt2));
+
+ if (VERBOSE) printf("\n Incrementing time \n");
+
+ icttnorm = ictt;
+
+ icttnorm.year++;
+ tt2 = icaltime_as_timet(icttnorm);
+ if (VERBOSE)
+ printf("Add a year: %s\n",ical_timet_string(tt2));
+
+ icttnorm.month+=13;
+ tt2 = icaltime_as_timet(icttnorm);
+ if (VERBOSE)
+ printf("Add 13 months: %s\n",ical_timet_string(tt2));
+
+ icttnorm.second+=90;
+ tt2 = icaltime_as_timet(icttnorm);
+ if (VERBOSE)
+ printf("Add 90 seconds: %s\n",ical_timet_string(tt2));
+
+ if (VERBOSE) printf("\n Day Of week \n");
+
+ day_of_week = icaltime_day_of_week(ictt);
+ start_day_of_week = icaltime_start_doy_of_week(ictt);
+ day_of_year = icaltime_day_of_year(ictt);
+
+ sprintf(msg, "Testing day of week %d", day_of_week);
+ int_is(msg, day_of_week, 6);
+
+ sprintf(msg, "Testing day of year %d",day_of_year);
+ int_is(msg, day_of_year, 308);
+
+ sprintf(msg, "Week started on doy of %d", start_day_of_week);
+ int_is(msg, start_day_of_week , 303);
+
+ if (VERBOSE) printf("\n TimeZone Conversions \n");
+
+/*
+ icttla = ictt;
+ icaltimezone_convert_time(&icttla,
+ icaltimezone_get_utc_timezone(),
+ lazone);
+*/
+ icttla = icaltime_convert_to_zone(ictt,
+ icaltimezone_get_builtin_timezone("America/Los_Angeles"));
+
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ int_is("Converted hour in America/Los_Angeles is 10", icttla.hour, 10);
+#endif
+
+ icttutc = icaltime_convert_to_zone(icttla,icaltimezone_get_utc_timezone());
+
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ ok("America/Los_Angeles local time is 2000-11-03 10:30:30",
+ (strncmp(ictt_as_string(icttla), "2000-11-03 10:30:30", 19)==0));
+#endif
+
+ ok("Test conversion back to UTC",(icaltime_compare(icttutc, ictt) == 0));
+
+ icttny = icaltime_convert_to_zone(ictt,
+ icaltimezone_get_builtin_timezone("America/New_York"));
+
+ icttphoenix = icaltime_convert_to_zone(ictt,
+ icaltimezone_get_builtin_timezone("America/Phoenix"));
+
+ if (VERBOSE) {
+ printf("Orig (ctime): %s\n", ical_timet_string(tt) );
+ printf("Orig (ical) : %s\n", ictt_as_string(ictt));
+ printf("UTC : %s\n", ictt_as_string(icttutc));
+ printf("Los Angeles : %s\n", ictt_as_string(icttla));
+ printf("Phoenix : %s\n", ictt_as_string(icttphoenix));
+ printf("New York : %s\n", ictt_as_string(icttny));
+ }
+ /** @todo Check results for Phoenix here?... **/
+
+ /* Daylight savings test for New York */
+ if (VERBOSE) {
+ printf("\n Daylight Savings \n");
+
+ printf("Orig (ctime): %s\n", ical_timet_string(tt) );
+ printf("Orig (ical) : %s\n", ictt_as_string(ictt));
+ printf("NY : %s\n", ictt_as_string(icttny));
+ }
+
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ ok("Converted time in zone America/New_York is 2000-11-03 13:30:30",
+ (strncmp(ictt_as_string(icttny),"2000-11-03 13:30:30",19)==0));
+#endif
+
+ tt_p200 = tt + 200 * 24 * 60 * 60 ; /* Add 200 days */
+
+ icttdayl = icaltime_from_timet_with_zone(tt_p200,0,
+ icaltimezone_get_utc_timezone());
+ icttny = icaltime_convert_to_zone(icttdayl,
+ icaltimezone_get_builtin_timezone("America/New_York"));
+
+ if (VERBOSE) {
+ printf("Orig +200d : %s\n", ical_timet_string(tt_p200) );
+ printf("NY+200D : %s\n", ictt_as_string(icttny));
+ }
+
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ ok("Converted time +200d in zone America/New_York is 2001-05-22 14:30:30",
+ (strncmp(ictt_as_string(icttny),"2001-05-22 14:30:30",19)==0));
+#endif
+
+
+ /* Daylight savings test for Los Angeles */
+
+ icttla = icaltime_convert_to_zone(ictt,
+ icaltimezone_get_builtin_timezone("America/Los_Angeles"));
+
+ if (VERBOSE) {
+ printf("\nOrig (ctime): %s\n", ical_timet_string(tt) );
+ printf("Orig (ical) : %s\n", ictt_as_string(ictt));
+ printf("LA : %s\n", ictt_as_string(icttla));
+ }
+
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ ok("Converted time in zone America/Los_Angeles is 2000-11-03 10:30:30",
+ (strncmp(ictt_as_string(icttla),"2000-11-03 10:30:30",19)==0));
+#endif
+
+
+ icttla = icaltime_convert_to_zone(icttdayl,
+ icaltimezone_get_builtin_timezone("America/Los_Angeles"));
+
+ if (VERBOSE) {
+ printf("Orig +200d : %s\n", ical_timet_string(tt_p200) );
+ printf("LA+200D : %s\n", ictt_as_string(icttla));
+ }
+
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ ok("Converted time +200d in zone America/Los_Angeles is 2001-05-22 11:30:30",
+ (strncmp(ictt_as_string(icttla),"2001-05-22 11:30:30",19)==0));
+#endif
+
+
+ icalerror_errors_are_fatal = 1;
+}
+
+void test_iterators()
+{
+ icalcomponent *c,*inner,*next;
+ icalcompiter i;
+ char vevent_list[64] = "";
+ char remaining_list[64] = "";
+
+ char *vevent_list_good = "12347";
+ char *remaining_list_good = "568910";
+
+ int nomore = 1;
+
+ c= icalcomponent_vanew(
+ ICAL_VCALENDAR_COMPONENT,
+ icalcomponent_vanew(ICAL_VEVENT_COMPONENT,
+ icalproperty_new_version("1"),(void *)0),
+ icalcomponent_vanew(ICAL_VEVENT_COMPONENT,
+ icalproperty_new_version("2"),(void *)0),
+ icalcomponent_vanew(ICAL_VEVENT_COMPONENT,
+ icalproperty_new_version("3"),(void *)0),
+ icalcomponent_vanew(ICAL_VEVENT_COMPONENT,
+ icalproperty_new_version("4"),(void *)0),
+ icalcomponent_vanew(ICAL_VTODO_COMPONENT,
+ icalproperty_new_version("5"),(void *)0),
+ icalcomponent_vanew(ICAL_VJOURNAL_COMPONENT,
+ icalproperty_new_version("6"),(void *)0),
+ icalcomponent_vanew(ICAL_VEVENT_COMPONENT,
+ icalproperty_new_version("7"),(void *)0),
+ icalcomponent_vanew(ICAL_VJOURNAL_COMPONENT,
+ icalproperty_new_version("8"),(void *)0),
+ icalcomponent_vanew(ICAL_VJOURNAL_COMPONENT,
+ icalproperty_new_version("9"),(void *)0),
+ icalcomponent_vanew(ICAL_VJOURNAL_COMPONENT,
+ icalproperty_new_version("10"),(void *)0),
+ (void *)0);
+
+ /* List all of the VEVENTS */
+
+ for(i = icalcomponent_begin_component(c,ICAL_VEVENT_COMPONENT);
+ icalcompiter_deref(&i)!= 0; icalcompiter_next(&i)){
+
+ icalcomponent *this = icalcompiter_deref(&i);
+
+ icalproperty *p =
+ icalcomponent_get_first_property(this,
+ ICAL_VERSION_PROPERTY);
+ const char* s = icalproperty_get_version(p);
+
+ strcat(vevent_list, s);
+ }
+ is("iterate through VEVENTS in a component",
+ vevent_list, vevent_list_good);
+
+ /* Delete all of the VEVENTS */
+ /* reset iterator */
+ icalcomponent_get_first_component(c,ICAL_VEVENT_COMPONENT);
+
+ while((inner=icalcomponent_get_current_component(c)) != 0 ){
+ if(icalcomponent_isa(inner) == ICAL_VEVENT_COMPONENT){
+ icalcomponent_remove_component(c,inner);
+ icalcomponent_free(inner);
+ } else {
+ icalcomponent_get_next_component(c,ICAL_VEVENT_COMPONENT);
+ }
+ }
+
+ /* List all remaining components */
+ for(inner = icalcomponent_get_first_component(c,ICAL_ANY_COMPONENT);
+ inner != 0;
+ inner = icalcomponent_get_next_component(c,ICAL_ANY_COMPONENT)){
+
+
+ icalproperty *p =
+ icalcomponent_get_first_property(inner,ICAL_VERSION_PROPERTY);
+
+ const char* s = icalproperty_get_version(p);
+
+ strcat(remaining_list, s);
+ }
+
+ is("iterate through remaining components",
+ remaining_list, remaining_list_good);
+
+
+ /* Remove all remaining components */
+ for(inner = icalcomponent_get_first_component(c,ICAL_ANY_COMPONENT);
+ inner != 0;
+ inner = next){
+
+ icalcomponent *this;
+ icalproperty *p;
+ const char* s;
+ next = icalcomponent_get_next_component(c,ICAL_ANY_COMPONENT);
+
+ p=icalcomponent_get_first_property(inner,ICAL_VERSION_PROPERTY);
+ s = icalproperty_get_version(p);
+
+ icalcomponent_remove_component(c,inner);
+
+ this = icalcomponent_get_current_component(c);
+
+ if(this != 0){
+ p=icalcomponent_get_first_property(this,ICAL_VERSION_PROPERTY);
+ s = icalproperty_get_version(p);
+ }
+
+ icalcomponent_free(inner);
+ }
+
+
+ /* List all remaining components */
+ for(inner = icalcomponent_get_first_component(c,ICAL_ANY_COMPONENT);
+ inner != 0;
+ inner = icalcomponent_get_next_component(c,ICAL_ANY_COMPONENT)){
+
+ icalproperty *p =
+ icalcomponent_get_first_property(inner,ICAL_VERSION_PROPERTY);
+
+ const char* s = icalproperty_get_version(p);
+
+ if (s)
+ nomore = 0;
+ }
+
+ ok("test if any components remain after deleting the rest",
+ nomore == 1);
+
+ icalcomponent_free(c);
+}
+
+
+void test_time()
+{
+ char *zones[6] = { "America/Los_Angeles","America/New_York","Europe/London","Asia/Shanghai", NULL};
+
+ int i;
+
+ do_test_time(0);
+
+ for(i = 0; zones[i] != NULL; i++){
+
+ if (VERBOSE) printf(" ######### Timezone: %s ############\n",zones[i]);
+
+ do_test_time(zones[i]);
+
+ }
+
+}
+
+
+void test_icalset()
+{
+ icalcomponent *c;
+
+ icalset* f = icalset_new_file("2446.ics");
+ icalset* d = icalset_new_dir("outdir");
+
+ assert(f!=0);
+ assert(d!=0);
+
+ for(c = icalset_get_first_component(f);
+ c != 0;
+ c = icalset_get_next_component(f)){
+
+ icalcomponent *clone;
+
+ clone = icalcomponent_new_clone(c);
+
+ icalset_add_component(d,clone);
+
+ printf(" class %d\n",icalclassify(c,0,"user"));
+
+ }
+
+ icalset_free(f);
+ icalset_free(d);
+}
+
+
+icalcomponent* icalclassify_find_overlaps(icalset* set, icalcomponent* comp);
+
+void test_overlaps()
+{
+ icalcomponent *cset,*c;
+ icalset *set;
+ time_t tm1 = 973378800; /*Sat Nov 4 23:00:00 UTC 2000,
+ Sat Nov 4 15:00:00 PST 2000 */
+ time_t tm2 = 973382400; /*Sat Nov 5 00:00:00 UTC 2000
+ Sat Nov 4 16:00:00 PST 2000 */
+
+ time_t hh = 1800; /* one half hour */
+
+ icalfileset_options options = {O_RDONLY, 0644, 0};
+ set = icalset_new(ICAL_FILE_SET, TEST_DATADIR "/overlaps.ics", &options);
+
+ c = icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_vanew_dtstart(icaltime_from_timet(tm1-hh,0),(void *)0),
+ icalproperty_vanew_dtend(icaltime_from_timet(tm2-hh,0),(void *)0),
+ 0
+ );
+
+ cset = icalclassify_find_overlaps(set,c);
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ ok("TODO find overlaps 1", (cset != NULL));
+#endif
+
+ if (VERBOSE && cset) printf("%s\n",icalcomponent_as_ical_string(cset));
+
+ if (cset) icalcomponent_free(cset);
+ if (c) icalcomponent_free(c);
+
+
+ c = icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_vanew_dtstart(icaltime_from_timet(tm1-hh,0),(void *)0),
+ icalproperty_vanew_dtend(icaltime_from_timet(tm2,0),(void *)0),
+ 0
+ );
+
+ cset = icalclassify_find_overlaps(set,c);
+
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ ok("TODO find overlaps 1", cset != NULL);
+#endif
+ if (VERBOSE && cset) printf("%s\n",icalcomponent_as_ical_string(cset));
+
+ if (cset) icalcomponent_free(cset);
+ if (c) icalcomponent_free(c);
+
+ c = icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_vanew_dtstart(icaltime_from_timet(tm1+5*hh,0),(void *)0),
+ icalproperty_vanew_dtend(icaltime_from_timet(tm2+5*hh,0),(void *)0),
+ 0
+ );
+
+ cset = icalclassify_find_overlaps(set,c);
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ ok("TODO find overlaps 1", cset != NULL);
+#endif
+ if (VERBOSE && cset) printf("%s\n",icalcomponent_as_ical_string(cset));
+
+ if (set) icalset_free(set);
+ if (cset) icalcomponent_free(cset);
+ if (c) icalcomponent_free(c);
+}
+
+
+
+void test_fblist()
+{
+ icalspanlist *sl, *new_sl;
+ icalfileset_options options = {O_RDONLY, 0644, 0};
+ icalset *set = icalset_new(ICAL_FILE_SET, TEST_DATADIR "/spanlist.ics", &options);
+ struct icalperiodtype period;
+ icalcomponent *comp;
+ int * foo;
+ int i;
+
+ sl = icalspanlist_new(set,
+ icaltime_from_string("19980101T000000Z"),
+ icaltime_from_string("19980108T000000Z"));
+
+ ok("open ../../test-data/spanlist.ics", (set!=NULL));
+ assert(set!=NULL);
+
+ if (VERBOSE) printf("Restricted spanlist\n");
+ if (VERBOSE) icalspanlist_dump(sl);
+
+ period= icalspanlist_next_free_time(sl,
+ icaltime_from_string("19970801T120000"));
+
+ is("Next Free time start 19970801T120000", icaltime_as_ical_string(period.start), "19970801T120000");
+ is("Next Free time end 19980101T000000", icaltime_as_ical_string(period.end), "19980101T000000");
+
+ period= icalspanlist_next_free_time(sl, period.end);
+
+ is("Next Free time start 19980101T010000", icaltime_as_ical_string(period.start), "19980101T010000");
+ is("Next Free time end 19980102T010000", icaltime_as_ical_string(period.end), "19980102T010000");
+
+ if (VERBOSE) printf("%s\n",
+ icalcomponent_as_ical_string(icalspanlist_as_vfreebusy(sl,
+ "a@foo.com",
+ "b@foo.com")
+ ));
+
+ foo = icalspanlist_as_freebusy_matrix(sl,3600);
+
+ for (i=0; foo[i] != -1; i++); /* find number entries */
+
+ int_is("Calculating freebusy hourly matrix", i, (7*24));
+
+ if (VERBOSE) {
+ for (i=0; foo[i] != -1; i++) {
+ printf("%d", foo[i]);
+ if ((i % 24) == 23)
+ printf("\n");
+ }
+ printf("\n\n");
+ }
+
+
+ free(foo);
+
+ foo = icalspanlist_as_freebusy_matrix(sl,3600*24);
+
+ ok("Calculating daily freebusy matrix", (foo!=NULL));
+
+ {
+ char out_str[80] = "";
+ char *strp = out_str;
+
+ for (i=0; foo[i]!=-1; i++){
+ sprintf(strp, "%d", foo[i]);
+ strp++;
+ }
+ is("Checking freebusy validity", out_str, "1121110");
+ }
+ if (VERBOSE) {
+ for (i=0; foo[i] != -1; i++) {
+ printf("%d", foo[i]);
+ if ((i % 7) == 6)
+ printf("\n");
+ }
+ printf("\n\n");
+ }
+ free(foo);
+
+ icalspanlist_free(sl);
+
+
+ if (VERBOSE) printf("Unrestricted spanlist\n");
+
+ sl = icalspanlist_new(set,
+ icaltime_from_string("19970324T120000Z"),
+ icaltime_null_time());
+
+ ok("add 19970324T120000Z to spanlist", (sl!=NULL));
+
+ if (VERBOSE) printf("Restricted spanlist\n");
+ if (VERBOSE) icalspanlist_dump(sl);
+
+ period= icalspanlist_next_free_time(sl,
+ icaltime_from_string("19970801T120000Z"));
+
+
+ is("Next Free time start 19980101T010000",
+ icaltime_as_ical_string(period.start),
+ "19980101T010000");
+
+ is("Next Free time end 19980102T010000",
+ icaltime_as_ical_string(period.end),
+ "19980102T010000");
+
+ comp = icalspanlist_as_vfreebusy(sl, "a@foo.com", "b@foo.com");
+
+ ok("Calculating VFREEBUSY component", (comp != NULL));
+ if (VERBOSE) printf("%s\n", icalcomponent_as_ical_string(comp));
+
+ new_sl = icalspanlist_from_vfreebusy(comp);
+
+ ok("Calculating spanlist from generated VFREEBUSY component",
+ (new_sl != NULL));
+
+ if (VERBOSE) icalspanlist_dump(new_sl);
+
+ if (sl) icalspanlist_free(sl);
+ if (new_sl) icalspanlist_free(new_sl);
+ if (comp) icalcomponent_free(comp);
+
+ icalset_free(set);
+}
+
+
+void test_convenience(){
+ icalcomponent *c;
+ int duration;
+ struct icaltimetype tt;
+
+ c = icalcomponent_vanew(
+ ICAL_VCALENDAR_COMPONENT,
+ icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_new_dtstart(icaltime_from_string("19970801T120000")),
+ icalproperty_new_dtend(icaltime_from_string("19970801T130000")),
+ (void *)0),
+ (void *)0);
+
+ if (VERBOSE) printf("\n%s\n", icalcomponent_as_ical_string(c));
+
+ duration = icaldurationtype_as_int(icalcomponent_get_duration(c))/60;
+
+ is("Start is 1997-08-01 12:00:00 (floating)",
+ ictt_as_string(icalcomponent_get_dtstart(c)), "1997-08-01 12:00:00 (floating)");
+ is("End is 1997-08-01 13:00:00 (floating)",
+ ictt_as_string(icalcomponent_get_dtend(c)), "1997-08-01 13:00:00 (floating)");
+ ok("Duration is 60 m", (duration == 60));
+
+ icalcomponent_free(c);
+
+ c = icalcomponent_vanew(
+ ICAL_VCALENDAR_COMPONENT,
+ icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_new_dtstart(icaltime_from_string("19970801T120000Z")),
+ icalproperty_new_duration(icaldurationtype_from_string("PT1H30M")),
+ (void *)0),
+ (void *)0);
+
+ if (VERBOSE) printf("\n%s\n", icalcomponent_as_ical_string(c));
+
+ duration = icaldurationtype_as_int(icalcomponent_get_duration(c))/60;
+
+ is("Start is 1997-08-01 12:00:00 Z UTC",
+ ictt_as_string(icalcomponent_get_dtstart(c)), "1997-08-01 12:00:00 Z UTC");
+ is("End is 1997-08-01 13:30:00 Z UTC",
+ ictt_as_string(icalcomponent_get_dtend(c)), "1997-08-01 13:30:00 Z UTC");
+ ok("Duration is 90 m", (duration == 90));
+
+ icalcomponent_free(c);
+
+ icalerror_errors_are_fatal = 0;
+
+ c = icalcomponent_vanew(
+ ICAL_VCALENDAR_COMPONENT,
+ icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_new_dtstart(icaltime_from_string("19970801T120000")),
+ icalproperty_new_dtend(icaltime_from_string("19970801T130000")),
+ (void *)0),
+ (void *)0);
+
+ icalcomponent_set_duration(c,icaldurationtype_from_string("PT1H30M"));
+
+ if (VERBOSE) printf("\n%s\n", icalcomponent_as_ical_string(c));
+
+ duration = icaldurationtype_as_int(icalcomponent_get_duration(c))/60;
+
+ is("Start is 1997-08-01 12:00:00 (floating)",
+ ictt_as_string(icalcomponent_get_dtstart(c)),
+ "1997-08-01 12:00:00 (floating)");
+ is("End is 1997-08-01 13:00:00 (floating)",
+ ictt_as_string(icalcomponent_get_dtend(c)),
+ "1997-08-01 13:00:00 (floating)");
+ ok("Duration is 60 m", (duration == 60));
+
+ icalcomponent_free(c);
+
+ c = icalcomponent_vanew(
+ ICAL_VCALENDAR_COMPONENT,
+ icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_new_dtstart(icaltime_from_string("19970801T120000Z")),
+ icalproperty_new_duration(icaldurationtype_from_string("PT1H30M")),
+ (void *)0),
+ (void *)0);
+
+ icalcomponent_set_dtend(c,icaltime_from_string("19970801T133000Z"));
+
+ if (VERBOSE) printf("\n%s\n", icalcomponent_as_ical_string(c));
+
+
+ duration = icaldurationtype_as_int(icalcomponent_get_duration(c))/60;
+
+ ok("Start is 1997-08-01 12:00:00 Z UTC",
+ (0 == strcmp("1997-08-01 12:00:00 Z UTC", ictt_as_string(icalcomponent_get_dtstart(c)))));
+ ok("End is 1997-08-01 13:30:00 Z UTC",
+ (0 == strcmp("1997-08-01 13:30:00 Z UTC", ictt_as_string(icalcomponent_get_dtend(c)))));
+ ok("Duration is 90 m", (duration == 90));
+
+ icalerror_errors_are_fatal = 1;
+
+ icalcomponent_free(c);
+
+ c = icalcomponent_vanew(
+ ICAL_VCALENDAR_COMPONENT,
+ icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ (void *)0),
+ (void *)0);
+
+ icalcomponent_set_dtstart(c,icaltime_from_string("19970801T120000Z"));
+ icalcomponent_set_dtend(c,icaltime_from_string("19970801T133000Z"));
+
+ if (VERBOSE) printf("\n%s\n", icalcomponent_as_ical_string(c));
+
+
+ duration = icaldurationtype_as_int(icalcomponent_get_duration(c))/60;
+
+ ok("Start is 1997-08-01 12:00:00 Z UTC",
+ (0 == strcmp("1997-08-01 12:00:00 Z UTC", ictt_as_string(icalcomponent_get_dtstart(c)))));
+ ok("End is 1997-08-01 13:30:00 Z UTC",
+ (0 == strcmp("1997-08-01 13:30:00 Z UTC", ictt_as_string(icalcomponent_get_dtend(c)))));
+ ok("Duration is 90 m", (duration == 90));
+
+ icalcomponent_free(c);
+
+ c = icalcomponent_vanew(
+ ICAL_VCALENDAR_COMPONENT,
+ icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ (void *)0),
+ (void *)0);
+
+
+ icalcomponent_set_dtstart(c,icaltime_from_string("19970801T120000Z"));
+ icalcomponent_set_duration(c,icaldurationtype_from_string("PT1H30M"));
+
+ if (VERBOSE) printf("\n%s\n", icalcomponent_as_ical_string(c));
+
+
+ duration = icaldurationtype_as_int(icalcomponent_get_duration(c))/60;
+
+ ok("Start is 1997-08-01 12:00:00 Z UTC",
+ (0 == strcmp("1997-08-01 12:00:00 Z UTC", ictt_as_string(icalcomponent_get_dtstart(c)))));
+ ok("End is 1997-08-01 13:30:00 Z UTC",
+ (0 == strcmp("1997-08-01 13:30:00 Z UTC", ictt_as_string(icalcomponent_get_dtend(c)))));
+ ok("Duration is 90 m", (duration == 90));
+
+ icalcomponent_free(c);
+
+ c = icalcomponent_vanew(
+ ICAL_VCALENDAR_COMPONENT,
+ icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ (void *)0),
+ (void *)0);
+
+ tt = icaltime_from_string("19970801T120000");
+ icaltime_set_timezone(&tt,
+ icaltimezone_get_builtin_timezone("Europe/Rome"));
+ icalcomponent_set_dtstart(c,tt);
+
+ if (VERBOSE) printf("\n%s\n", icalcomponent_as_ical_string(c));
+
+ icalcomponent_set_duration(c,icaldurationtype_from_string("PT1H30M"));
+ duration = icaldurationtype_as_int(icalcomponent_get_duration(c))/60;
+
+#ifndef USE_BUILTIN_TZDATA
+ ok("Start is 1997-08-01 12:00:00 Europe/Rome",
+ (0 == strcmp("1997-08-01 12:00:00 /softwarestudio.org/Tzfile/Europe/Rome", ictt_as_string(icalcomponent_get_dtstart(c)))));
+ ok("End is 1997-08-01 13:30:00 Europe/Rome",
+ (0 == strcmp("1997-08-01 13:30:00 /softwarestudio.org/Tzfile/Europe/Rome", ictt_as_string(icalcomponent_get_dtend(c)))));
+#else
+ ok("Start is 1997-08-01 12:00:00 Europe/Rome",
+ (0 == strcmp("1997-08-01 12:00:00 /citadel.org/20070227_1/Europe/Rome", ictt_as_string(icalcomponent_get_dtstart(c)))));
+ ok("End is 1997-08-01 13:30:00 Europe/Rome",
+ (0 == strcmp("1997-08-01 13:30:00 /citadel.org/20070227_1/Europe/Rome", ictt_as_string(icalcomponent_get_dtend(c)))));
+#endif
+ ok("Duration is 90 m", (duration == 90));
+
+ icalcomponent_free(c);
+}
+
+void test_time_parser()
+{
+ struct icaltimetype tt;
+
+ icalerror_errors_are_fatal = 0;
+
+ tt = icaltime_from_string("19970101T1000");
+ ok("19970101T1000 is null time", icaltime_is_null_time(tt));
+
+ tt = icaltime_from_string("19970101X100000");
+ ok("19970101X100000 is null time", icaltime_is_null_time(tt));
+
+ tt = icaltime_from_string("19970101T100000");
+ ok("19970101T100000 is valid", !icaltime_is_null_time(tt));
+
+ if (VERBOSE) printf("%s\n",icaltime_as_ctime(tt));
+
+ tt = icaltime_from_string("19970101T100000Z");
+
+ ok("19970101T100000Z is valid" , !icaltime_is_null_time(tt));
+ if (VERBOSE) printf("%s\n",icaltime_as_ctime(tt));
+
+ tt = icaltime_from_string("19970101");
+ ok("19970101 is valid", (!icaltime_is_null_time(tt)));
+
+ if (VERBOSE) printf("%s\n",icaltime_as_ctime(tt));
+
+ icalerror_errors_are_fatal = 1;
+}
+
+void test_recur_parser()
+{
+ struct icalrecurrencetype rt;
+ char *str;
+
+ str = "FREQ=YEARLY;UNTIL=20000131T090000Z;INTERVAL=1;BYDAY=-1TU,3WE,-4FR,SA,SU;BYYEARDAY=34,65,76,78;BYMONTH=1,2,3,4,8";
+ rt = icalrecurrencetype_from_string(str);
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ is(str, icalrecurrencetype_as_string(&rt), str);
+#endif
+
+ str = "FREQ=DAILY;COUNT=3;INTERVAL=1;BYDAY=-1TU,3WE,-4FR,SA,SU;BYYEARDAY=34,65,76,78;BYMONTH=1,2,3,4,8";
+
+ rt = icalrecurrencetype_from_string(str);
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ is(str, icalrecurrencetype_as_string(&rt), str);
+#endif
+}
+
+char* ical_strstr(const char *haystack, const char *needle){
+ return strstr(haystack,needle);
+}
+
+void test_start_of_week()
+{
+ struct icaltimetype tt2;
+ struct icaltimetype tt1 = icaltime_from_string("19900110");
+ int dow, doy,start_dow;
+
+ do{
+ tt1 = icaltime_normalize(tt1);
+
+ doy = icaltime_start_doy_of_week(tt1);
+ dow = icaltime_day_of_week(tt1);
+
+ tt2 = icaltime_from_day_of_year(doy,tt1.year);
+ start_dow = icaltime_day_of_week(tt2);
+
+ if(doy == 1){
+ char msg[128];
+ sprintf(msg, "%s", ictt_as_string(tt1));
+ int_is(msg, start_dow, 1);
+ }
+
+ if(start_dow != 1){ /* Sunday is 1 */
+ printf("failed: Start of week (%s) is not a Sunday \n for %s (doy=%d,dow=%d)\n",ictt_as_string(tt2), ictt_as_string(tt1),dow,start_dow);
+ }
+
+
+ assert(start_dow == 1);
+
+
+ tt1.day+=1;
+
+ } while(tt1.year < 2010);
+}
+
+void test_doy()
+{
+ struct icaltimetype tt1, tt2;
+ short doy,doy2;
+ char msg[128];
+
+ doy = -1;
+
+ tt1 = icaltime_from_string("19900101");
+
+ if (VERBOSE) printf("Test icaltime_day_of_year() agreement with mktime\n");
+
+ do{
+ struct tm stm;
+
+ tt1 = icaltime_normalize(tt1);
+
+ stm.tm_sec = tt1.second;
+ stm.tm_min = tt1.minute;
+ stm.tm_hour = tt1.hour;
+ stm.tm_mday = tt1.day;
+ stm.tm_mon = tt1.month-1;
+ stm.tm_year = tt1.year-1900;
+ stm.tm_isdst = -1;
+
+ mktime(&stm);
+
+ doy = icaltime_day_of_year(tt1);
+
+ doy2 = stm.tm_yday+1;
+
+ if (doy == 1) {
+ /** show some test cases **/
+ sprintf(msg, "Year %d - mktime() compare", tt1.year);
+ int_is(msg, doy,doy2);
+ }
+
+ if (doy != doy2){
+ printf("Failed for %s (%d,%d)\n",ictt_as_string(tt1),doy,doy2);
+ }
+ assert(doy == doy2);
+
+ tt1.day+=1;
+
+ } while(tt1.year < 2010);
+
+ if (VERBOSE) printf("\nTest icaltime_day_of_year() agreement with icaltime_from_day_of_year()\n");
+
+ tt1 = icaltime_from_string("19900101");
+
+ do{
+ if(doy == 1){
+ /** show some test cases **/
+ sprintf(msg, "Year %d - icaltime_day_of_year() compare", tt1.year);
+ int_is(msg, doy,doy2);
+ }
+
+ doy = icaltime_day_of_year(tt1);
+ tt2 = icaltime_from_day_of_year(doy,tt1.year);
+ doy2 = icaltime_day_of_year(tt2);
+
+ assert(doy2 == doy);
+ assert(icaltime_compare(tt1,tt2) == 0);
+
+ tt1.day+=1;
+ tt1 = icaltime_normalize(tt1);
+
+ } while(tt1.year < 2010);
+
+
+ tt1 = icaltime_from_string("19950301");
+ doy = icaltime_day_of_year(tt1);
+ tt2 = icaltime_from_day_of_year(doy,1995);
+ if(VERBOSE) printf("%d %s %s\n",doy, icaltime_as_ctime(tt1),icaltime_as_ctime(tt2));
+
+ ok("test 19950301", (tt2.day == 1 && tt2.month == 3));
+ ok("day of year == 60", (doy == 60));
+
+ tt1 = icaltime_from_string("19960301");
+ doy = icaltime_day_of_year(tt1);
+ tt2 = icaltime_from_day_of_year(doy,1996);
+ if (VERBOSE) printf("%d %s %s\n",doy, icaltime_as_ctime(tt1),icaltime_as_ctime(tt2));
+ ok("test 19960301", (tt2.day == 1 && tt2.month == 3));
+ ok("day of year == 61", (doy == 61));
+
+ tt1 = icaltime_from_string("19970301");
+ doy = icaltime_day_of_year(tt1);
+ tt2 = icaltime_from_day_of_year(doy,1997);
+ if (VERBOSE) printf("%d %s %s\n",doy, icaltime_as_ctime(tt1),icaltime_as_ctime(tt2));
+
+ ok("test 19970301", (tt2.day == 1 && tt2.month == 3));
+ ok("day of year == 60", (doy == 60));
+
+}
+
+void test_x(){
+
+ static const char test_icalcomp_str[] =
+"BEGIN:VEVENT\r\n"
+"RRULE\r\n"
+" ;X-EVOLUTION-ENDDATE=20030209T081500\r\n"
+" :FREQ=DAILY;COUNT=10;INTERVAL=6\r\n"
+"X-COMMENT;X-FOO=BAR: Booga\r\n"
+"END:VEVENT\r\n";
+
+ icalcomponent *icalcomp;
+ icalproperty *prop;
+ struct icalrecurrencetype recur;
+ int n_errors;
+
+ icalcomp = icalparser_parse_string ((char *) test_icalcomp_str);
+ assert(icalcomp!=NULL);
+
+ if (VERBOSE) printf("%s\n\n",icalcomponent_as_ical_string(icalcomp));
+
+ n_errors = icalcomponent_count_errors (icalcomp);
+ int_is("icalparser_parse_string()", n_errors,0);
+
+ if (n_errors) {
+ /** NOT USED **/
+ icalproperty *p;
+
+ for (p = icalcomponent_get_first_property (icalcomp,
+ ICAL_XLICERROR_PROPERTY);
+ p;
+ p = icalcomponent_get_next_property (icalcomp,
+ ICAL_XLICERROR_PROPERTY)) {
+ const char *str;
+
+ str = icalproperty_as_ical_string (p);
+ fprintf (stderr, "error: %s\n", str);
+ }
+ }
+
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY);
+ ok("get RRULE property", (prop != NULL));
+ assert(prop!=NULL);
+
+ recur = icalproperty_get_rrule (prop);
+
+ if (VERBOSE) printf("%s\n",icalrecurrencetype_as_string(&recur));
+
+ icalcomponent_free(icalcomp);
+
+}
+
+void test_gauge_sql() {
+ icalgauge *g;
+ char* str;
+
+ str= "SELECT DTSTART,DTEND,COMMENT FROM VEVENT,VTODO WHERE VEVENT.SUMMARY = 'Bongoa' AND SEQUENCE < 5";
+
+ g = icalgauge_new_from_sql(str, 0);
+ ok(str, (g!=NULL));
+ if (VERBOSE) icalgauge_dump(g);
+
+ icalgauge_free(g);
+
+ str="SELECT * FROM VEVENT,VTODO WHERE VEVENT.SUMMARY = 'Bongoa' AND SEQUENCE < 5 OR METHOD != 'CREATE'";
+
+ g = icalgauge_new_from_sql(str, 0);
+ ok(str, (g!=NULL));
+ if (VERBOSE) icalgauge_dump(g);
+
+ icalgauge_free(g);
+
+ str="SELECT * FROM VEVENT WHERE SUMMARY == 'BA301'";
+
+ g = icalgauge_new_from_sql(str, 0);
+ ok(str, (g!=NULL));
+ if (VERBOSE) icalgauge_dump(g);
+
+ icalgauge_free(g);
+
+ str="SELECT * FROM VEVENT WHERE SUMMARY == 'BA301'";
+
+ g = icalgauge_new_from_sql(str, 0);
+ ok(str, (g!=NULL));
+ if (VERBOSE) icalgauge_dump(g);
+
+ icalgauge_free(g);
+
+ str="SELECT * FROM VEVENT WHERE LOCATION == '104 Forum'";
+
+ g = icalgauge_new_from_sql(str, 0);
+ ok(str, (g!=NULL));
+ if (VERBOSE) icalgauge_dump(g);
+
+ icalgauge_free(g);
+}
+
+
+void test_gauge_compare() {
+ icalgauge *g;
+ icalcomponent *c;
+ char* str;
+
+ /* Equality */
+
+ c = icalcomponent_vanew(ICAL_VCALENDAR_COMPONENT,
+ icalcomponent_vanew(ICAL_VEVENT_COMPONENT,
+ icalproperty_new_dtstart(
+ icaltime_from_string("20000101T000002")),0),(void *)0);
+
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART = '20000101T000002'", 0);
+
+ ok("SELECT * FROM VEVENT WHERE DTSTART = '20000101T000002'", (c!=0 && g!=0));
+ assert(c!=0);
+ assert(g!=0);
+
+ int_is("compare",icalgauge_compare(g,c), 1);
+
+ icalgauge_free(g);
+
+
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART = '20000101T000001'", 0);
+
+ ok("SELECT * FROM VEVENT WHERE DTSTART = '20000101T000001'\n", (g!=0));
+
+ assert(g!=0);
+ int_is("compare",icalgauge_compare(g,c), 0);
+
+ icalgauge_free(g);
+
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART != '20000101T000003'", 0);
+
+ ok("SELECT * FROM VEVENT WHERE DTSTART != '20000101T000003'\n", (c!=0 && g!=0));
+
+
+ assert(g!=0);
+ int_is("compare",icalgauge_compare(g,c), 1);
+
+ icalgauge_free(g);
+
+
+ /* Less than */
+
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART < '20000101T000003'", 0);
+
+ ok("SELECT * FROM VEVENT WHERE DTSTART < '20000101T000003'", (c!=0 && g!=0));
+
+ int_is("compare",icalgauge_compare(g,c), 1);
+
+ assert(g!=0);
+ icalgauge_free(g);
+
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART < '20000101T000002'", 0);
+
+ ok("SELECT * FROM VEVENT WHERE DTSTART < '20000101T000002'\n", (g!=0));
+
+
+ assert(g!=0);
+ int_is("compare",icalgauge_compare(g,c), 0);
+
+ icalgauge_free(g);
+
+ /* Greater than */
+
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART > '20000101T000001'", 0);
+
+ ok("SELECT * FROM VEVENT WHERE DTSTART > '20000101T000001'\n", (g!=0));
+
+
+ assert(g!=0);
+ int_is("compare",icalgauge_compare(g,c), 1);
+
+ icalgauge_free(g);
+
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART > '20000101T000002'", 0);
+
+ ok("SELECT * FROM VEVENT WHERE DTSTART > '20000101T000002'\n", (g!=0));
+
+
+ assert(g!=0);
+ int_is("compare",icalgauge_compare(g,c), 0);
+
+
+ icalgauge_free(g);
+
+
+ /* Greater than or Equal to */
+
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART >= '20000101T000002'", 0);
+
+ ok("SELECT * FROM VEVENT WHERE DTSTART >= '20000101T000002'\n", (g!=0));
+
+
+ int_is("compare",icalgauge_compare(g,c), 1);
+
+ icalgauge_free(g);
+
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART >= '20000101T000003'", 0);
+
+ ok("SELECT * FROM VEVENT WHERE DTSTART >= '20000101T000003'\n", (g!=0));
+
+
+ int_is("compare",icalgauge_compare(g,c), 0);
+
+ icalgauge_free(g);
+
+ /* Less than or Equal to */
+
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART <= '20000101T000002'", 0);
+
+ ok("SELECT * FROM VEVENT WHERE DTSTART <= '20000101T000002'\n", (g!=0));
+
+
+ assert(g!=0);
+ int_is("compare",icalgauge_compare(g,c), 1);
+
+ icalgauge_free(g);
+
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART <= '20000101T000001'", 0);
+
+ ok("SELECT * FROM VEVENT WHERE DTSTART <= '20000101T000001'\n", (g!=0));
+
+
+ int_is("compare",icalgauge_compare(g,c), 0);
+
+ icalgauge_free(g);
+
+ icalcomponent_free(c);
+
+ /* Combinations */
+
+ c = icalcomponent_vanew(ICAL_VCALENDAR_COMPONENT,
+ icalcomponent_vanew(ICAL_VEVENT_COMPONENT,
+ icalproperty_new_dtstart(
+ icaltime_from_string("20000102T000000")),0),(void *)0);
+
+
+ str = "SELECT * FROM VEVENT WHERE DTSTART > '20000101T000000' and DTSTART < '20000103T000000'";
+
+ g = icalgauge_new_from_sql(str, 0);
+ ok(str, (g!=0));
+ int_is("compare",icalgauge_compare(g,c), 1);
+
+ icalgauge_free(g);
+
+ str = "SELECT * FROM VEVENT WHERE DTSTART > '20000101T000000' and DTSTART < '20000102T000000'";
+
+ g = icalgauge_new_from_sql(str, 0);
+ ok(str, (g!=0));
+ int_is("compare",icalgauge_compare(g,c), 0);
+
+ icalgauge_free(g);
+
+ str = "SELECT * FROM VEVENT WHERE DTSTART > '20000101T000000' or DTSTART < '20000102T000000'";
+
+ g = icalgauge_new_from_sql(str, 0);
+ ok(str, (g!=0));
+ int_is("compare",icalgauge_compare(g,c), 1);
+
+ icalgauge_free(g);
+
+
+ icalcomponent_free(c);
+
+ /* Combinations, non-cannonical component */
+
+ c = icalcomponent_vanew(ICAL_VEVENT_COMPONENT,
+ icalproperty_new_dtstart(
+ icaltime_from_string("20000102T000000")),(void *)0);
+
+
+ str = "SELECT * FROM VEVENT WHERE DTSTART > '20000101T000000' and DTSTART < '20000103T000000'";
+
+ g = icalgauge_new_from_sql(str, 0);
+ ok(str, (g!=0));
+ int_is("compare",icalgauge_compare(g,c), 1);
+
+ icalgauge_free(g);
+
+ str = "SELECT * FROM VEVENT WHERE DTSTART > '20000101T000000' and DTSTART < '20000102T000000'";
+
+ g = icalgauge_new_from_sql(str, 0);
+ ok(str, (g!=0));
+ int_is("compare",icalgauge_compare(g,c), 0);
+
+ icalgauge_free(g);
+
+ str = "SELECT * FROM VEVENT WHERE DTSTART > '20000101T000000' or DTSTART < '20000102T000000'";
+
+ g = icalgauge_new_from_sql(str, 0);
+ ok(str, (g!=0));
+ int_is("compare",icalgauge_compare(g,c), 1);
+
+ icalgauge_free(g);
+ icalcomponent_free(c);
+
+
+ /* Complex comparisions */
+
+ c = icalcomponent_vanew(
+ ICAL_VCALENDAR_COMPONENT,
+ icalproperty_new_method(ICAL_METHOD_REQUEST),
+ icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_new_dtstart(
+ icaltime_from_string("20000101T000002")),
+ icalproperty_new_comment("foo"),
+ icalcomponent_vanew(
+ ICAL_VALARM_COMPONENT,
+ icalproperty_new_dtstart(
+ icaltime_from_string("20000101T120000")),
+
+ (void *)0),
+ (void *)0),
+ (void *)0);
+
+
+ str = "SELECT * FROM VEVENT WHERE VALARM.DTSTART = '20000101T120000'";
+
+ g = icalgauge_new_from_sql(str, 0);
+ ok(str, (g!=0));
+ int_is("compare",icalgauge_compare(g,c), 1);
+
+ icalgauge_free(g);
+
+ str = "SELECT * FROM VEVENT WHERE COMMENT = 'foo'";
+ g = icalgauge_new_from_sql(str, 0);
+ ok(str, (g!=0));
+ int_is("compare",icalgauge_compare(g,c), 1);
+
+ icalgauge_free(g);
+
+ str = "SELECT * FROM VEVENT WHERE COMMENT = 'foo' AND VALARM.DTSTART = '20000101T120000'";
+ g = icalgauge_new_from_sql(str, 0);
+ ok(str, (g!=0));
+ int_is("compare",icalgauge_compare(g,c), 1);
+
+ icalgauge_free(g);
+
+ str = "SELECT * FROM VEVENT WHERE COMMENT = 'bar' AND VALARM.DTSTART = '20000101T120000'";
+ g = icalgauge_new_from_sql(str, 0);
+ ok(str, (g!=0));
+ int_is("compare",icalgauge_compare(g,c), 0);
+
+ icalgauge_free(g);
+
+ str = "SELECT * FROM VEVENT WHERE COMMENT = 'bar' or VALARM.DTSTART = '20000101T120000'";
+ g = icalgauge_new_from_sql(str, 0);
+ ok(str, (g!=0));
+ int_is("compare",icalgauge_compare(g,c), 1);
+
+ icalgauge_free(g);
+
+ icalcomponent_free(c);
+
+}
+
+icalcomponent* make_component(int i){
+
+ icalcomponent *c;
+
+ struct icaltimetype t = icaltime_from_string("20000101T120000Z");
+
+ t.day += i;
+
+ icaltime_normalize(t);
+
+ c = icalcomponent_vanew(
+ ICAL_VCALENDAR_COMPONENT,
+ icalproperty_new_method(ICAL_METHOD_REQUEST),
+ icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_new_dtstart(t),
+ (void *)0),
+ (void *)0);
+
+ assert(c != 0);
+
+ return c;
+
+}
+void test_fileset()
+{
+ icalset *fs;
+ icalcomponent *c;
+ int i;
+ int comp_count = 0;
+ char *path = "test_fileset.ics";
+ icalgauge *g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART > '20000103T120000Z' AND DTSTART <= '20000106T120000Z'", 0);
+
+ ok("icalgauge_new_from_sql()", (g!=NULL));
+
+ unlink(path);
+
+ fs = icalfileset_new(path);
+
+ ok("icalfileset_new()", (fs!=NULL));
+ assert(fs != 0);
+
+ for (i = 0; i!= 10; i++){
+ c = make_component(i);
+ icalfileset_add_component(fs,c);
+ }
+
+ icalfileset_commit(fs);
+
+ icalset_free(fs);
+ /** reopen fileset.ics **/
+ fs = icalfileset_new(path);
+
+ if (VERBOSE) printf("== No Selections \n");
+
+ comp_count = 0;
+ for (c = icalfileset_get_first_component(fs);
+ c != 0;
+ c = icalfileset_get_next_component(fs)){
+ struct icaltimetype t = icalcomponent_get_dtstart(c);
+ comp_count++;
+ if (VERBOSE) printf("%s\n",icaltime_as_ctime(t));
+ }
+ int_is("icalfileset get components",comp_count, 10);
+
+ icalfileset_select(fs,g);
+
+ if (VERBOSE) printf("\n== DTSTART > '20000103T120000Z' AND DTSTART <= '20000106T120000Z' \n");
+
+ comp_count = 0;
+ for (c = icalfileset_get_first_component(fs);
+ c != 0;
+ c = icalfileset_get_next_component(fs)){
+ struct icaltimetype t = icalcomponent_get_dtstart(c);
+ comp_count++;
+ if (VERBOSE) printf("%s\n",icaltime_as_ctime(t));
+ }
+ int_is("icalfileset get components with gauge",comp_count, 3);
+
+ icalset_free(fs);
+
+ /*icalgauge_free(g);*/
+
+}
+
+void microsleep(int us)
+{
+#ifndef WIN32
+ struct timeval tv;
+
+ tv.tv_sec = 0;
+ tv.tv_usec = us;
+
+ select(0,0,0,0,&tv);
+#else
+ Sleep(us);
+#endif
+}
+
+
+void test_file_locks()
+{
+#ifndef WIN32
+ pid_t pid;
+ char *path = "test_fileset_locktest.ics";
+ icalset *fs;
+ icalcomponent *c, *c2;
+ struct icaldurationtype d;
+ int i;
+ int final,sec = 0;
+
+ icalerror_clear_errno();
+
+ unlink(path);
+
+ fs = icalfileset_new(path);
+
+ if(icalfileset_get_first_component(fs)==0){
+ c = make_component(0);
+
+ d = icaldurationtype_from_int(1);
+
+ icalcomponent_set_duration(c,d);
+
+ icalfileset_add_component(fs,c);
+
+ c2 = icalcomponent_new_clone(c);
+
+ icalfileset_add_component(fs,c2);
+
+ icalfileset_commit(fs);
+ }
+
+ icalset_free(fs);
+
+ assert(icalerrno == ICAL_NO_ERROR);
+
+ pid = fork();
+
+ assert(pid >= 0);
+
+ if(pid == 0){
+ /*child*/
+ int i;
+
+ microsleep(rand()/(RAND_MAX/100));
+
+ for(i = 0; i< 50; i++){
+ fs = icalfileset_new(path);
+
+
+ assert(fs != 0);
+
+ c = icalfileset_get_first_component(fs);
+
+ assert(c!=0);
+
+ d = icalcomponent_get_duration(c);
+ d = icaldurationtype_from_int(icaldurationtype_as_int(d)+1);
+
+ icalcomponent_set_duration(c,d);
+ icalcomponent_set_summary(c,"Child");
+
+ c2 = icalcomponent_new_clone(c);
+ icalcomponent_set_summary(c2,"Child");
+ icalfileset_add_component(fs,c2);
+
+ icalfileset_mark(fs);
+ icalfileset_commit(fs);
+
+ icalset_free(fs);
+
+ microsleep(rand()/(RAND_MAX/20));
+
+
+ }
+
+ exit(0);
+
+ } else {
+ /* parent */
+ int i;
+
+ for(i = 0; i< 50; i++){
+ fs = icalfileset_new(path);
+
+ assert(fs != 0);
+
+ c = icalfileset_get_first_component(fs);
+
+ assert(c!=0);
+
+ d = icalcomponent_get_duration(c);
+ d = icaldurationtype_from_int(icaldurationtype_as_int(d)+1);
+
+ icalcomponent_set_duration(c,d);
+ icalcomponent_set_summary(c,"Parent");
+
+ c2 = icalcomponent_new_clone(c);
+ icalcomponent_set_summary(c2,"Parent");
+ icalfileset_add_component(fs,c2);
+
+ icalfileset_mark(fs);
+ icalfileset_commit(fs);
+ icalset_free(fs);
+
+ putc('.',stdout);
+ fflush(stdout);
+
+ }
+ }
+
+ assert(waitpid(pid,0,0)==pid);
+
+
+ fs = icalfileset_new(path);
+
+ i=1;
+
+ c = icalfileset_get_first_component(fs);
+ final = icaldurationtype_as_int(icalcomponent_get_duration(c));
+ for (c = icalfileset_get_next_component(fs);
+ c != 0;
+ c = icalfileset_get_next_component(fs)){
+ struct icaldurationtype d = icalcomponent_get_duration(c);
+ sec = icaldurationtype_as_int(d);
+
+ /*printf("%d,%d ",i,sec);*/
+ assert(i == sec);
+ i++;
+ }
+
+ printf("\nFinal: %d\n",final);
+
+
+ assert(sec == final);
+#endif
+}
+
+void test_action()
+{
+ icalcomponent *c;
+ icalproperty *p;
+ char *str;
+
+ static const char test_icalcomp_str[] =
+"BEGIN:VEVENT\r\n"
+"ACTION:EMAIL\r\n"
+"ACTION:PROCEDURE\r\n"
+"ACTION:AUDIO\r\n"
+"ACTION:FUBAR\r\n"
+"END:VEVENT\r\n";
+
+
+ c = icalparser_parse_string ((char *) test_icalcomp_str);
+
+ ok("icalparser_parse_string(), ACTIONS", (c!=NULL));
+ assert(c!=0);
+
+ str = icalcomponent_as_ical_string(c);
+ is("icalcomponent_as_ical_string()", str, ((char*) test_icalcomp_str));
+ if (VERBOSE) printf("%s\n\n",str);
+
+ p = icalcomponent_get_first_property(c,ICAL_ACTION_PROPERTY);
+
+ ok("ICAL_ACTION_EMAIL", (icalproperty_get_action(p) == ICAL_ACTION_EMAIL));
+
+ p = icalcomponent_get_next_property(c,ICAL_ACTION_PROPERTY);
+
+ ok("ICAL_ACTION_PROCEDURE", (icalproperty_get_action(p) == ICAL_ACTION_PROCEDURE));
+
+ p = icalcomponent_get_next_property(c,ICAL_ACTION_PROPERTY);
+
+ ok("ICAL_ACTION_AUDIO", (icalproperty_get_action(p) == ICAL_ACTION_AUDIO));
+
+ p = icalcomponent_get_next_property(c,ICAL_ACTION_PROPERTY);
+
+ ok("ICAL_ACTION_X", (icalproperty_get_action(p) == ICAL_ACTION_X));
+ is("ICAL_ACTION -> FUBAR", icalvalue_get_x(icalproperty_get_value(p)), "FUBAR");
+ icalcomponent_free(c);
+}
+
+
+
+void test_trigger()
+{
+
+ struct icaltriggertype tr;
+ icalcomponent *c;
+ icalproperty *p;
+ const char* str;
+
+ static const char test_icalcomp_str[] =
+"BEGIN:VEVENT\r\n"
+"TRIGGER;VALUE=DATE-TIME:19980403T120000\r\n"
+"TRIGGER;VALUE=DURATION:-PT15M\r\n"
+"TRIGGER;VALUE=DATE-TIME:19980403T120000\r\n"
+"TRIGGER;VALUE=DURATION:-PT15M\r\n"
+"END:VEVENT\r\n";
+
+
+ c = icalparser_parse_string ((char *) test_icalcomp_str);
+ ok("icalparser_parse_string()", (c!= NULL));
+ assert(c!=NULL);
+
+ is("parsed triggers", icalcomponent_as_ical_string(c), (char*)test_icalcomp_str);
+
+ for(p = icalcomponent_get_first_property(c,ICAL_TRIGGER_PROPERTY);
+ p != 0;
+ p = icalcomponent_get_next_property(c,ICAL_TRIGGER_PROPERTY)){
+ tr = icalproperty_get_trigger(p);
+
+ if(!icaltime_is_null_time(tr.time)){
+ if (VERBOSE) printf("value=DATE-TIME:%s\n", icaltime_as_ical_string(tr.time));
+ } else {
+ if (VERBOSE) printf("value=DURATION:%s\n", icaldurationtype_as_ical_string(tr.duration));
+ }
+ }
+
+ icalcomponent_free(c);
+
+ /* Trigger, as a DATETIME */
+ tr.duration = icaldurationtype_null_duration();
+ tr.time = icaltime_from_string("19970101T120000");
+ p = icalproperty_new_trigger(tr);
+ str = icalproperty_as_ical_string(p);
+
+ is("TRIGGER;VALUE=DATE-TIME:19970101T120000", str, "TRIGGER;VALUE=DATE-TIME:19970101T120000\r\n");
+ icalproperty_free(p);
+
+ /* TRIGGER, as a DURATION */
+ tr.time = icaltime_null_time();
+ tr.duration = icaldurationtype_from_string("P3DT3H50M45S");
+ p = icalproperty_new_trigger(tr);
+ str = icalproperty_as_ical_string(p);
+
+ is("TRIGGER;VALUE=DURATION:P3DT3H50M45S", str, "TRIGGER;VALUE=DURATION:P3DT3H50M45S\r\n");
+ icalproperty_free(p);
+
+ /* TRIGGER, as a DATETIME, VALUE=DATETIME*/
+ tr.duration = icaldurationtype_null_duration();
+ tr.time = icaltime_from_string("19970101T120000");
+ p = icalproperty_new_trigger(tr);
+ icalproperty_add_parameter(p,icalparameter_new_value( ICAL_VALUE_DATETIME));
+ str = icalproperty_as_ical_string(p);
+
+ is("TRIGGER;VALUE=DATE-TIME:19970101T120000", str, "TRIGGER;VALUE=DATE-TIME:19970101T120000\r\n");
+ icalproperty_free(p);
+
+ /*TRIGGER, as a DURATION, VALUE=DATETIME */
+ tr.time = icaltime_null_time();
+ tr.duration = icaldurationtype_from_string("P3DT3H50M45S");
+ p = icalproperty_new_trigger(tr);
+ icalproperty_add_parameter(p,icalparameter_new_value( ICAL_VALUE_DATETIME ));
+
+ str = icalproperty_as_ical_string(p);
+
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ is("TRIGGER;VALUE=DURATION:P3DT3H50M45S", str, "TRIGGER;VALUE=DURATION:P3DT3H50M45S\r\n");
+#endif
+ icalproperty_free(p);
+
+ /* TRIGGER, as a DATETIME, VALUE=DURATION*/
+ tr.duration = icaldurationtype_null_duration();
+ tr.time = icaltime_from_string("19970101T120000");
+ p = icalproperty_new_trigger(tr);
+ icalproperty_add_parameter(p,icalparameter_new_value( ICAL_VALUE_DURATION));
+ str = icalproperty_as_ical_string(p);
+
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ is("TRIGGER;VALUE=DATE-TIME:19970101T120000", str, "TRIGGER;VALUE=DATE-TIME:19970101T120000\r\n");
+#endif
+ icalproperty_free(p);
+
+ /*TRIGGER, as a DURATION, VALUE=DURATION */
+ tr.time = icaltime_null_time();
+ tr.duration = icaldurationtype_from_string("P3DT3H50M45S");
+ p = icalproperty_new_trigger(tr);
+ icalproperty_add_parameter(p,icalparameter_new_value( ICAL_VALUE_DURATION));
+
+ str = icalproperty_as_ical_string(p);
+
+ is("TRIGGER;VALUE=DURATION:P3DT3H50M45S", str, "TRIGGER;VALUE=DURATION:P3DT3H50M45S\r\n");
+ icalproperty_free(p);
+
+
+ /* TRIGGER, as a DATETIME, VALUE=BINARY */
+ tr.duration = icaldurationtype_null_duration();
+ tr.time = icaltime_from_string("19970101T120000");
+ p = icalproperty_new_trigger(tr);
+ icalproperty_add_parameter(p,icalparameter_new_value(ICAL_VALUE_BINARY));
+ str = icalproperty_as_ical_string(p);
+
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ is("TRIGGER;VALUE=DATE-TIME:19970101T120000", str, "TRIGGER;VALUE=DATE-TIME:19970101T120000\r\n");
+#endif
+ icalproperty_free(p);
+
+ /*TRIGGER, as a DURATION, VALUE=BINARY */
+ tr.time = icaltime_null_time();
+ tr.duration = icaldurationtype_from_string("P3DT3H50M45S");
+ p = icalproperty_new_trigger(tr);
+ icalproperty_add_parameter(p,icalparameter_new_value(ICAL_VALUE_BINARY));
+
+ str = icalproperty_as_ical_string(p);
+
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ is("TRIGGER;VALUE=DURATION:P3DT3H50M45S", str, "TRIGGER;VALUE=DURATION:P3DT3H50M45S\r\n");
+#endif
+ icalproperty_free(p);
+}
+
+
+void test_rdate()
+{
+
+ struct icaldatetimeperiodtype dtp;
+ icalproperty *p;
+ const char* str;
+ struct icalperiodtype period;
+
+ period.start = icaltime_from_string("19970101T120000");
+ period.end = icaltime_null_time();
+ period.duration = icaldurationtype_from_string("PT3H10M15S");
+
+ /* RDATE, as DATE-TIME */
+ dtp.time = icaltime_from_string("19970101T120000");
+ dtp.period = icalperiodtype_null_period();
+ p = icalproperty_new_rdate(dtp);
+ str = icalproperty_as_ical_string(p);
+
+ is("RDATE as DATE-TIME", str, "RDATE;VALUE=DATE-TIME:19970101T120000\r\n");
+ icalproperty_free(p);
+
+ /* RDATE, as PERIOD */
+ dtp.time = icaltime_null_time();
+ dtp.period = period;
+ p = icalproperty_new_rdate(dtp);
+
+ str = icalproperty_as_ical_string(p);
+ is("RDATE, as PERIOD", str,
+ "RDATE;VALUE=PERIOD:19970101T120000/PT3H10M15S\r\n");
+ icalproperty_free(p);
+
+ /* RDATE, as DATE-TIME, VALUE=DATE-TIME */
+ dtp.time = icaltime_from_string("19970101T120000");
+ dtp.period = icalperiodtype_null_period();
+ p = icalproperty_new_rdate(dtp);
+ icalproperty_add_parameter(p,icalparameter_new_value(ICAL_VALUE_DATETIME));
+ str = icalproperty_as_ical_string(p);
+
+ is("RDATE, as DATE-TIME, VALUE=DATE-TIME", str,
+ "RDATE;VALUE=DATE-TIME:19970101T120000\r\n");
+ icalproperty_free(p);
+
+
+ /* RDATE, as PERIOD, VALUE=DATE-TIME */
+ dtp.time = icaltime_null_time();
+ dtp.period = period;
+ p = icalproperty_new_rdate(dtp);
+ icalproperty_add_parameter(p,icalparameter_new_value(ICAL_VALUE_DATETIME));
+ str = icalproperty_as_ical_string(p);
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ is("RDATE, as PERIOD, VALUE=DATE-TIME", str,
+ "RDATE;VALUE=PERIOD:19970101T120000/PT3H10M15S\r\n");
+#endif
+ icalproperty_free(p);
+
+
+ /* RDATE, as DATE-TIME, VALUE=PERIOD */
+ dtp.time = icaltime_from_string("19970101T120000");
+ dtp.period = icalperiodtype_null_period();
+ p = icalproperty_new_rdate(dtp);
+ icalproperty_add_parameter(p,icalparameter_new_value(ICAL_VALUE_PERIOD));
+ str = icalproperty_as_ical_string(p);
+
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ is("RDATE, as DATE-TIME, VALUE=PERIOD", str,
+ "RDATE;VALUE=DATE-TIME:19970101T120000\r\n");
+#endif
+ icalproperty_free(p);
+
+
+ /* RDATE, as PERIOD, VALUE=PERIOD */
+ dtp.time = icaltime_null_time();
+ dtp.period = period;
+ p = icalproperty_new_rdate(dtp);
+ icalproperty_add_parameter(p,icalparameter_new_value(ICAL_VALUE_PERIOD));
+ str = icalproperty_as_ical_string(p);
+
+ is("RDATE, as PERIOD, VALUE=PERIOD", str,
+ "RDATE;VALUE=PERIOD:19970101T120000/PT3H10M15S\r\n");
+ icalproperty_free(p);
+
+
+ /* RDATE, as DATE-TIME, VALUE=BINARY */
+ dtp.time = icaltime_from_string("19970101T120000");
+ dtp.period = icalperiodtype_null_period();
+ p = icalproperty_new_rdate(dtp);
+ icalproperty_add_parameter(p,icalparameter_new_value(ICAL_VALUE_BINARY));
+ str = icalproperty_as_ical_string(p);
+
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ is("RDATE, as DATE-TIME, VALUE=BINARY", str,
+ "RDATE;VALUE=DATE-TIME:19970101T120000\r\n");
+#endif
+ icalproperty_free(p);
+
+
+ /* RDATE, as PERIOD, VALUE=BINARY */
+ dtp.time = icaltime_null_time();
+ dtp.period = period;
+ p = icalproperty_new_rdate(dtp);
+ icalproperty_add_parameter(p,icalparameter_new_value(ICAL_VALUE_BINARY));
+ str = icalproperty_as_ical_string(p);
+
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ is("RDATE, as PERIOD, VALUE=BINARY", str,
+ "RDATE;VALUE=PERIOD:19970101T120000/PT3H10M15S\r\n");
+#endif
+ icalproperty_free(p);
+}
+
+
+void test_langbind()
+{
+ icalcomponent *c, *inner;
+ icalproperty *p;
+ char *test_str_parsed;
+ 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"
+"COMMENT: Comment with \"quotable\" \'characters\' and other \t bad magic \n things \f Yeah.\n"
+"DTSTART:19970101T120000\n"
+"DTSTART:19970101T120000Z\n"
+"DTSTART:19970101\n"
+"DURATION:P3DT4H25M\n"
+"FREEBUSY:19970101T120000/19970101T120000\n"
+"FREEBUSY:19970101T120000/P3DT4H25M\n"
+"END:VEVENT\n";
+
+ static const char *test_str_parsed_good =
+"BEGIN:VEVENT\r\n"
+"ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:MAILTO:\r\n"
+" employee-A@host.com\r\n"
+"COMMENT: Comment that spans a line\r\n"
+"COMMENT: Comment with \\\"quotable\\\" 'characters' and other \\t bad magic \r\n"
+" things \\f Yeah.\r\n"
+"DTSTART:19970101T120000\r\n"
+"DTSTART:19970101T120000Z\r\n"
+"DTSTART;VALUE=DATE:19970101\r\n"
+"DURATION:P3DT4H25M\r\n"
+"FREEBUSY:19970101T120000/19970101T120000\r\n"
+"FREEBUSY:19970101T120000/P3DT4H25M\r\n"
+"END:VEVENT\r\n";
+
+ if (VERBOSE) printf("%s\n",test_str);
+
+ c = icalparser_parse_string(test_str);
+
+ ok("icalparser_parse_string()", (c!=NULL));
+ assert(c != NULL);
+
+ test_str_parsed = icalcomponent_as_ical_string(c);
+
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ is("parsed version with bad chars, etc",
+ test_str_parsed,
+ test_str_parsed_good);
+#endif
+
+
+ inner = icalcomponent_get_inner(c);
+
+ for(
+ p = icallangbind_get_first_property(inner,"ANY");
+ p != 0;
+ p = icallangbind_get_next_property(inner,"ANY")
+ ) {
+
+ const char *str = icallangbind_property_eval_string(p,":");
+ /** TODO add tests **/
+ if (VERBOSE) printf("%s\n",str);
+ }
+
+
+ p = icalcomponent_get_first_property(inner,ICAL_ATTENDEE_PROPERTY);
+
+ icalproperty_set_parameter_from_string(p,"CUTYPE","INDIVIDUAL");
+
+ is ("Set attendee parameter",
+ icalproperty_as_ical_string(p),
+ "ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=INDIVIDUAL:MAILTO:\r\n"
+ " employee-A@host.com\r\n");
+
+ icalproperty_set_value_from_string(p,"mary@foo.org","TEXT");
+
+ is ("Set attendee parameter value",
+ icalproperty_as_ical_string(p),
+ "ATTENDEE;VALUE=TEXT;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=INDIVIDUAL:\r\n"
+" mary@foo.org\r\n");
+
+ icalcomponent_free(c);
+}
+
+void test_property_parse()
+{
+ icalcomponent *c;
+ icalproperty *p;
+ const char *str;
+
+ static const char test_icalcomp_str[] =
+"BEGIN:VEVENT\n"
+"ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:MAILTO:employee-A@host.com\n"
+"DTSTART:19970101T120000Z\n"
+"END:VEVENT\n";
+
+ c = icalparser_parse_string ((char *) test_icalcomp_str);
+ ok("icalparser_parse_string()", (c != NULL));
+ if (!c) {
+ exit (EXIT_FAILURE);
+ }
+
+ p = icalcomponent_get_first_property(c,ICAL_ATTENDEE_PROPERTY);
+
+ ok("icalproperty_from_string(), ATTENDEE", (p != 0));
+
+ str = icalproperty_as_ical_string(p);
+ if (VERBOSE) printf("%s\n",str);
+
+ icalproperty_free(p);
+
+ p = icalcomponent_get_first_property(c,ICAL_DTSTART_PROPERTY);
+
+ ok("icalproperty_from_string(), simple DTSTART", (p != 0));
+
+ str = icalproperty_as_ical_string(p);
+ if (VERBOSE) printf("%s\n",str);
+
+ icalproperty_free(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);
+ ok("icalparser_parse_string()", (c != NULL));
+ if (!c) {
+ exit (EXIT_FAILURE);
+ }
+
+ if (VERBOSE) 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);
+
+ ok("icalproperty_get_value()", (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);
+ ok("icalproperty_get_first_parameter()",(icalparameter_get_value(param) == ICAL_VALUE_DATE));
+
+ icalcomponent_free(c);
+}
+
+
+void test_x_parameter()
+{
+ icalcomponent *c;
+ icalproperty *p;
+
+ static const char test_icalcomp_str[] =
+"BEGIN:VEVENT\n"
+"COMMENT;X-A=1;X-B=2:\\sThis is a note\n"
+"END:VEVENT\n";
+
+ c = icalparser_parse_string ((char *) test_icalcomp_str);
+ ok("icalparser_parse_string()", (c != NULL));
+ if (!c) {
+ exit (EXIT_FAILURE);
+ }
+
+ if (VERBOSE) printf("%s",icalcomponent_as_ical_string(c));
+
+ p = icalcomponent_get_first_property(c,ICAL_COMMENT_PROPERTY);
+ icalproperty_set_parameter_from_string(p,"X-LIES", "no");
+ icalproperty_set_parameter_from_string(p,"X-LAUGHS", "big");
+ icalproperty_set_parameter_from_string(p,"X-TRUTH", "yes");
+ icalproperty_set_parameter_from_string(p,"X-HUMOUR", "bad");
+
+ if (VERBOSE) printf("%s\n",icalproperty_as_ical_string(p));
+
+ is("COMMENT parses param", icalproperty_get_comment(p)," This is a note");
+
+ is("Check X-LIES", icalproperty_get_parameter_as_string(p, "X-LIES"), "no");
+ is("Check X-LAUGHS", icalproperty_get_parameter_as_string(p, "X-LAUGHS"), "big");
+ is("Check X-TRUTH", icalproperty_get_parameter_as_string(p, "X-TRUTH"), "yes");
+ is("Check X-HUMOUR", icalproperty_get_parameter_as_string(p, "X-HUMOUR"), "bad");
+
+ icalcomponent_free(c);
+}
+
+
+
+void test_x_property()
+{
+ icalcomponent *c;
+ icalproperty *p;
+
+ static const char test_icalcomp_str[] =
+"BEGIN:VEVENT\n"
+"X-LIC-PROPERTY:\\sThis is a note\n"
+"END:VEVENT\n";
+
+ c = icalparser_parse_string ((char *) test_icalcomp_str);
+ ok("icalparser_parse_string()", (c != NULL));
+ if (!c) {
+ exit (EXIT_FAILURE);
+ }
+
+ if (VERBOSE) printf("%s",icalcomponent_as_ical_string(c));
+
+ p = icalcomponent_get_first_property(c,ICAL_X_PROPERTY);
+ ok("x-property is correct kind",(icalproperty_isa(p) == ICAL_X_PROPERTY));
+ is("icalproperty_get_x_name() works",
+ icalproperty_get_x_name(p),"X-LIC-PROPERTY");
+ is("icalproperty_get_x() works",
+ icalproperty_get_x(p)," This is a note");
+
+ icalcomponent_free(c);
+}
+
+void test_utcoffset()
+{
+ icalcomponent *c;
+
+ static const char test_icalcomp_str[] =
+"BEGIN:VTIMEZONE\n"
+"TZOFFSETFROM:-001608\n"
+"END:VTIMEZONE\n";
+
+ c = icalparser_parse_string ((char *) test_icalcomp_str);
+ ok("parse TZOFFSETFROM:-001608", (c!=NULL));
+
+ if (VERBOSE && c) printf("%s",icalcomponent_as_ical_string(c));
+
+ if (c) icalcomponent_free(c);
+}
+
+void test_attach()
+{
+ icalcomponent *c;
+
+ static const char test_icalcomp_str[] =
+"BEGIN:VEVENT\n"
+"ATTACH:CID:jsmith.part3.960817T083000.xyzMain@host1.com\n"
+"ATTACH:FMTTYPE=application/postscript;ftp://xyzCorp.com/pub/reports/r-960812.ps\n"
+"END:VEVENT\n";
+
+ c = icalparser_parse_string ((char *) test_icalcomp_str);
+ ok("parse simple attachment", (c != NULL));
+
+ if (VERBOSE && c) printf("%s",icalcomponent_as_ical_string(c));
+
+ if (c) icalcomponent_free(c);
+}
+
+
+void test_vcal(void)
+{
+ VObject *vcal = 0;
+ icalcomponent *comp;
+ char* file = TEST_DATADIR "/user-cal.vcf";
+
+ vcal = Parse_MIME_FromFileName(file);
+
+ ok("Parsing " TEST_DATADIR "/user-cal.vcf", (vcal != 0));
+
+ comp = icalvcal_convert(vcal);
+
+ ok("Converting to ical component", (comp != 0));
+
+ if (VERBOSE && comp)
+ printf("%s\n",icalcomponent_as_ical_string(comp));
+
+ if (comp) icalcomponent_free(comp);
+ if (vcal) deleteVObject(vcal);
+}
+
+
+/*
+ * Test to see if recurrences are excluded in certain situations
+ * See r961 for more information
+ */
+void test_recurrenceexcluded(void)
+{
+ char funTime[2048];
+ icalcomponent * calendar = NULL;
+ icalcomponent * event = NULL;
+ struct icaltimetype dtstart;
+ struct icaltimetype recurtime;
+
+ funTime[0] = '\0';
+ strcat(funTime, "BEGIN:VCALENDAR\n");
+ strcat(funTime, "VERSION:2.0\n");
+ strcat(funTime, "BEGIN:VTIMEZONE\n");
+ strcat(funTime, "TZID:/mozilla.org/20071231_1/Europe/London\n");
+ strcat(funTime, "X-LIC-LOCATION:Europe/London\n");
+ strcat(funTime, "BEGIN:DAYLIGHT\n");
+ strcat(funTime, "TZOFFSETFROM:+0000\n");
+ strcat(funTime, "TZOFFSETTO:+0100\n");
+ strcat(funTime, "TZNAME:BST\n");
+ strcat(funTime, "DTSTART:19700328T230000\n");
+ strcat(funTime, "RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3\n");
+ strcat(funTime, "END:DAYLIGHT\n");
+ strcat(funTime, "BEGIN:STANDARD\n");
+ strcat(funTime, "TZOFFSETFROM:+0100\n");
+ strcat(funTime, "TZOFFSETTO:+0000\n");
+ strcat(funTime, "TZNAME:GMT\n");
+ strcat(funTime, "DTSTART:19701025T000000\n");
+ strcat(funTime, "RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10\n");
+ strcat(funTime, "END:STANDARD\n");
+ strcat(funTime, "END:VTIMEZONE\n");
+ strcat(funTime, "BEGIN:VEVENT\n");
+ strcat(funTime, "DTSTAMP:20080805T174443Z\n");
+ strcat(funTime, "UID:5fb6ccb8-9646-45ab-8c95-8d15e9de1280\n");
+ strcat(funTime, "SUMMARY:Exclude test\n");
+ strcat(funTime, "EXDATE;TZID=/mozilla.org/20071231_1/Europe/London:20080818T190000\n");
+ strcat(funTime, "EXDATE:20080819T180000Z\n");
+ strcat(funTime, "RRULE:FREQ=DAILY;COUNT=12;INTERVAL=1;BYDAY=MO,TU,WE,TH,FR\n");
+ strcat(funTime, "DTSTART;TZID=/mozilla.org/20071231_1/Europe/London:20080811T190000\n");
+ strcat(funTime, "DTEND;TZID=/mozilla.org/20071231_1/Europe/London:20080811T200000\n");
+ strcat(funTime, "END:VEVENT\n");
+ strcat(funTime, "END:VCALENDAR\n");
+ calendar = icalparser_parse_string(funTime);
+ dtstart = icalcomponent_get_dtstart(calendar);
+ event = icalcomponent_get_first_component(calendar, ICAL_VEVENT_COMPONENT);
+ recurtime = icaltime_from_string("20080818T180000Z");
+ ok("Recurrence is excluded as per r961", icalproperty_recurrence_is_excluded(event, &dtstart, &recurtime));
+ recurtime = icaltime_from_string("20080819T180000Z");
+ ok("Recurrence is excluded for UTC EXDATE", icalproperty_recurrence_is_excluded(event, &dtstart, &recurtime));
+}
+
+
+void test_bad_dtstart_in_timezone(void)
+{
+ icaltimezone *myTZ = NULL;
+ icalcomponent *vtimezone = NULL;
+ char *str = NULL;
+
+ myTZ = icaltimezone_get_builtin_timezone("Europe/Zurich");
+ vtimezone = icaltimezone_get_component(myTZ);
+ str = icalcomponent_as_ical_string(vtimezone);
+
+ if(VERBOSE)
+ printf("%s\n", str);
+#if ADD_TESTS_REQUIRING_INVESTIGATION
+ ok("bad-dtstart-in-timezone.patch r960", (strstr(str, "DTSTART:19701025T030000") != NULL));
+ ok("bad-dtstart-in-timezone.patch r960", (strstr(str, "DTSTART:19700329T020000") != NULL));
+#endif
+}
+
+void test_icalcomponent_new_from_string(void)
+{
+ const char *item =
+ "BEGIN:VCALENDAR\n"
+ "PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n"
+ "VERSION:2.0\n"
+ "BEGIN:VEVENT\n"
+ "SUMMARY:phone meeting\n"
+ "DTEND:20060406T163000Z\n"
+ "DTSTART:20060406T160000Z\n"
+ "UID:1234567890@dummy\n"
+ "DTSTAMP:20110824T104144Z\n"
+ "LAST-MODIFIED:20110824T104144Z\n"
+ "CREATED:20060409T213201\n"
+ "LOCATION:my office\n"
+ "DESCRIPTION:let's talk\n"
+ "CLASS:PUBLIC\n"
+ "TRANSP:OPAQUE\n"
+ "SEQUENCE:1\n"
+ "END:VEVENT\n"
+ "END:VCALENDAR\n";
+ // must succeed and not leak memory...
+ icalcomponent *comp = icalcomponent_new_from_string(item);
+ ok("parsed", (comp != NULL));
+ icalcomponent_free(comp);
+}
+
+void test_comma_in_quoted_value(void)
+{
+ icalcomponent *c;
+ icalproperty *p;
+
+ static const char test_icalcomp_str[] =
+"BEGIN:VEVENT\n"
+"X-TEST;VALUE=URI:\"geo:10.123456,-70.123456\"\n"
+"END:VEVENT\n";
+
+ c = icalparser_parse_string ((char *) test_icalcomp_str);
+ ok("icalparser_parse_string()", (c != NULL));
+ if (!c) {
+ exit (EXIT_FAILURE);
+ }
+
+ if (VERBOSE) printf("%s",icalcomponent_as_ical_string(c));
+
+ p = icalcomponent_get_first_property(c,ICAL_X_PROPERTY);
+ ok("x-property is correct kind",(icalproperty_isa(p) == ICAL_X_PROPERTY));
+ is("icalproperty_get_x_name() works",
+ icalproperty_get_x_name(p),"X-TEST");
+ is("icalproperty_get_value_as_string() works",
+ icalproperty_get_value_as_string(p),"\"geo:10.123456,-70.123456\"");
+
+ icalcomponent_free(c);
+}
+
+int main(int argc, char *argv[])
+{
+#if !defined(HAVE_UNISTD_H)
+ extern char *optarg;
+ extern int optopt;
+#endif
+ int errflg=0;
+/* char* program_name = strrchr(argv[0],'/'); */
+ int do_test = 0;
+ int do_header = 0;
+
+ set_zone_directory("../../zoneinfo");
+ icaltimezone_set_tzid_prefix("/softwarestudio.org/");
+ putenv("TZ=");
+
+ test_start(0);
+
+
+#ifndef WIN32
+ int c;
+ while ((c = getopt(argc, argv, "lvq")) != -1) {
+ switch (c) {
+ case 'v': {
+ VERBOSE = 1;
+ break;
+ }
+ case 'q': {
+ QUIET = 1;
+ break;
+ }
+ case 'l': {
+ do_header = 1;;
+ }
+ case '?': {
+ errflg++;
+ }
+ }
+ }
+ if (optind < argc) {
+ do_test = atoi(argv[argc-1]);
+ }
+#else
+ if (argc>1)
+ do_test = atoi(argv[1]);
+
+#endif
+
+ test_run("Test time parser functions", test_time_parser, do_test, do_header);
+ test_run("Test time", test_time, do_test, do_header);
+ test_run("Test day of Year", test_doy, do_test, do_header);
+ test_run("Test duration", test_duration, do_test, do_header);
+ test_run("Test period", test_period, do_test, do_header);
+ test_run("Test DTSTART", test_dtstart, do_test, do_header);
+ test_run("Test day of year of week start", test_start_of_week, do_test, do_header);
+ test_run("Test recur parser", test_recur_parser, do_test, do_header);
+ test_run("Test recur", test_recur, do_test, do_header);
+ test_run("Test Recurring Events File", test_recur_file, do_test, do_header);
+ test_run("Test parameter bug", test_recur_parameter_bug, do_test, do_header);
+ test_run("Test Array Expansion", test_expand_recurrence, do_test, do_header);
+ test_run("Test Free/Busy lists", test_fblist, do_test, do_header);
+ test_run("Test Overlaps", test_overlaps, do_test, do_header);
+
+ test_run("Test Span", test_icalcomponent_get_span, do_test, do_header);
+ test_run("Test Gauge SQL", test_gauge_sql, do_test, do_header);
+ test_run("Test Gauge Compare", test_gauge_compare, do_test, do_header);
+ test_run("Test File Set", test_fileset, do_test, do_header);
+ test_run("Test File Set (Extended)", test_fileset_extended, do_test, do_header);
+ test_run("Test Dir Set", test_dirset, do_test, do_header);
+ test_run("Test Dir Set (Extended)", test_dirset_extended, do_test, do_header);
+
+/* test_file_locks is slow but should work ok -- uncomment to test it */
+/* test_run("Test File Locks", test_file_locks, do_test, do_header);*/
+ test_run("Test X Props and Params", test_x, do_test, do_header);
+ test_run("Test Trigger", test_trigger, do_test, do_header);
+ test_run("Test Restriction", test_restriction, do_test, do_header);
+ test_run("Test RDATE", test_rdate, do_test, do_header);
+ test_run("Test language binding", test_langbind, do_test, do_header);
+ test_run("Test property parser", test_property_parse, do_test, do_header);
+ test_run("Test Action", test_action, do_test, do_header);
+ test_run("Test Value Parameter", test_value_parameter, do_test, do_header);
+ test_run("Test X property", test_x_property, do_test, do_header);
+ test_run("Test X parameter", test_x_parameter, do_test, do_header);
+ test_run("Test request status", test_requeststat, do_test, do_header);
+ test_run("Test UTC-OFFSET", test_utcoffset, do_test, do_header);
+ test_run("Test Values", test_values, do_test, do_header);
+ test_run("Test Parameters", test_parameters, do_test, do_header);
+ test_run("Test Properties", test_properties, do_test, do_header);
+ test_run("Test Components", test_components, do_test, do_header);
+ test_run("Test Convenience", test_convenience, do_test, do_header);
+ test_run("Test classify ", test_classify, do_test, do_header);
+ test_run("Test Iterators", test_iterators, do_test, do_header);
+ test_run("Test strings", test_strings, do_test, do_header);
+#ifdef INVALID_TEST
+ test_run("Test TZID escaping", test_tzid_escape, do_test, do_header);
+#endif
+ test_run("Test Compare", test_compare, do_test, do_header);
+ test_run("Create Simple Component", create_simple_component, do_test, do_header);
+ test_run("Create Components", create_new_component, do_test, do_header);
+ test_run("Create Components with vaargs", create_new_component_with_va_args, do_test, do_header);
+ test_run("Test Memory", test_memory, do_test, do_header);
+ test_run("Test Attachment", test_attach, do_test, do_header);
+ test_run("Test icalcalendar", test_calendar, do_test, do_header);
+ test_run("Test Dirset", test_dirset, do_test, do_header);
+ test_run("Test vCal to iCal conversion", test_vcal, do_test, do_header);
+ test_run("Test UTF-8 Handling", test_utf8, do_test, do_header);
+ test_run("Test exclusion of recurrences as per r961", test_recurrenceexcluded, do_test, do_header);
+ test_run("Test bad dtstart in timezone as per r960", test_bad_dtstart_in_timezone, do_test, do_header);
+ test_run("Test icalcomponent_new_from_string()", test_icalcomponent_new_from_string, do_test, do_header);
+ test_run("Test comma in quoted value of x property", test_comma_in_quoted_value, do_test, do_header);
+
+ /** OPTIONAL TESTS go here... **/
+
+#ifdef WITH_CXX_BINDINGS
+ test_run("Test C++ API", test_cxx, do_test, do_header);
+#endif
+
+#ifdef WITH_BDB
+ test_run("Test BDB Set", test_bdbset, do_test, do_header);
+#endif
+
+ icaltimezone_free_builtin_timezones();
+ icalmemory_free_ring();
+ free_zone_directory();
+
+ test_end();
+
+ return 0;
+}
+
+
diff --git a/src/test/regression.dsp b/src/test/regression.dsp
new file mode 100644
index 00000000..f7b76a2e
--- /dev/null
+++ b/src/test/regression.dsp
@@ -0,0 +1,125 @@
+# Microsoft Developer Studio Project File - Name="regression" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=regression - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "regression.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "regression.mak" CFG="regression - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "regression - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "regression - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "regression - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../libical" /I "../libicalss" /I "../libicalvcal" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libical.lib libicalss.lib libicalvcal.lib /nologo /subsystem:console /machine:I386 /libpath:"../libical/Release" /libpath:"../libicalss/Release" /libpath:"../libicalvcal/Release"
+
+!ELSEIF "$(CFG)" == "regression - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../libical" /I "../libicalss" /I "../libicalvcal" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libical.lib libicalss.lib libicalvcal.lib /nologo /subsystem:console /profile /debug /machine:I386 /libpath:"../libical/Debug" /libpath:"../libicalss/Debug" /libpath:"../libicalvcal/Debug"
+
+!ENDIF
+
+# Begin Target
+
+# Name "regression - Win32 Release"
+# Name "regression - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=".\regression-classify.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\regression-component.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\regression-recur.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\regression-storage.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\regression-utils.c"
+# End Source File
+# Begin Source File
+
+SOURCE=.\regression.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\regression.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/src/test/regression.h b/src/test/regression.h
new file mode 100644
index 00000000..b7630321
--- /dev/null
+++ b/src/test/regression.h
@@ -0,0 +1,55 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ADD_TESTS_REQUIRING_INVESTIGATION 0
+
+extern int VERBOSE;
+extern int QUIET;
+
+/* regression-component.c */
+void create_new_component(void);
+void create_new_component_with_va_args(void);
+void create_simple_component(void);
+void test_icalcomponent_get_span(void);
+void create_new_component_with_va_args(void);
+
+/* regression-classify.c */
+void test_classify(void);
+
+/* regression-recur.c */
+void test_recur_file(void);
+
+/* regression-cxx.c */
+void test_cxx(void);
+
+/* regression-storage.c */
+void test_fileset_extended(void);
+void test_dirset_extended(void);
+void test_bdbset(void);
+
+/* regression-utils.c */
+const char* ical_timet_string(const time_t t);
+const char* ictt_as_string(struct icaltimetype t);
+char* icaltime_as_ctime(struct icaltimetype t);
+
+
+void _ok(char*name, int result, char*file, int linenum, char *test);
+void _is(char* test_name, const char* str1, const char* str2, char *file, int linenum);
+void _int_is(char* test_name, int i1, int i2, char *file, int linenum);
+#define ok(TEST, EX) (_ok(TEST, EX, __FILE__, __LINE__, #EX))
+#define is(S1, S2, EX) (_is(S1, S2, EX, __FILE__, __LINE__))
+#define int_is(I1, I2, EX) (_int_is(I1, I2, EX, __FILE__, __LINE__))
+void test_header(char*title, int test_set);
+void test_start(int);
+void test_end(void);
+void test_run(char *test_name,
+ void (*test_fcn)(void),
+ int do_test, int headeronly);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/test/storage.c b/src/test/storage.c
new file mode 100644
index 00000000..ef273367
--- /dev/null
+++ b/src/test/storage.c
@@ -0,0 +1,873 @@
+/* -*- Mode: C -*-
+ ======================================================================
+ FILE: storage.c
+ CREATOR: eric 03 April 1999
+
+ DESCRIPTION:
+
+ $Id: storage.c,v 1.6 2008-01-02 20:07:46 dothebart Exp $
+ $Locker: $
+
+ (C) COPYRIGHT 1999 Eric Busboom
+ http://www.softwarestudio.org
+
+ The contents of this file are subject to the Mozilla Public License
+ Version 1.0 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and
+ limitations under the License.
+
+ The original author is Eric Busboom
+ The original code is usecases.c
+
+
+ ======================================================================*/
+
+#include <libical/ical.h>
+#include <assert.h>
+#include <string.h> /* for strdup */
+#include <stdlib.h> /* for malloc */
+#include <stdio.h> /* for printf */
+#include <time.h> /* for time() */
+#include "icalmemory.h"
+#include "icaldirset.h"
+#include "icalfileset.h"
+#ifdef WITH_BDB4
+#include "icalbdbset.h"
+#endif
+#include "icalerror.h"
+#include "icalrestriction.h"
+#include "icalcalendar.h"
+
+#define OUTPUT_FILE "filesetout.ics"
+#define DATABASE "calendar.db"
+
+/* define sample calendar struct */
+struct calendar {
+ int ID;
+ int total_size;
+
+ /* offsets */
+ int total_size_offset;
+ int vcalendar_size_offset;
+ int vcalendar_offset;
+ int title_size_offset;
+ int title_offset;
+
+ /* data */
+ int vcalendar_size;
+ char *vcalendar;
+
+ int title_size;
+ char *title;
+
+};
+
+int vcalendar_init(struct calendar **cal, char *vcalendar, char *title);
+
+#ifdef WITH_BDB4
+int get_title(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey);
+char * parse_vcalendar(const DBT *dbt) ;
+#endif
+
+char * pack_calendar(struct calendar *cal, int size);
+struct calendar * unpack_calendar(char *str, int size);
+
+char str[] = "BEGIN:VCALENDAR\n\
+PRODID:\"-//RDU Software//NONSGML HandCal//EN\"\n\
+VERSION:2.0\n\
+BEGIN:VTIMEZONE\n\
+TZID:US-Eastern\n\
+BEGIN:STANDARD\n\
+DTSTART:19981025T020000\n\
+RDATE:19981025T020000\n\
+TZOFFSETFROM:-0400\n\
+TZOFFSETTO:-0500\n\
+TZNAME:EST\n\
+END:STANDARD\n\
+BEGIN:DAYLIGHT\n\
+DTSTART:19990404T020000\n\
+RDATE:19990404T020000\n\
+TZOFFSETFROM:-0500\n\
+TZOFFSETTO:-0400\n\
+TZNAME:EDT\n\
+END:DAYLIGHT\n\
+END:VTIMEZONE\n\
+BEGIN:VEVENT\n\
+DTSTAMP:19980309T231000Z\n\
+UID:guid-1.host1.com\n\
+ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com\n\
+ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:MAILTO:employee-A@host.com\n\
+DESCRIPTION:Project XYZ Review Meeting\n\
+CATEGORIES:MEETING\n\
+CLASS:PUBLIC\n\
+CREATED:19980309T130000Z\n\
+SUMMARY:XYZ Project Review\n\
+DTSTART;TZID=US-Eastern:19980312T083000\n\
+DTEND;TZID=US-Eastern:19980312T093000\n\
+LOCATION:1CP Conference Room 4350\n\
+END:VEVENT\n\
+BEGIN:BOOGA\n\
+DTSTAMP:19980309T231000Z\n\
+X-LIC-FOO:Booga\n\
+DTSTOMP:19980309T231000Z\n\
+UID:guid-1.host1.com\n\
+END:BOOGA\n\
+END:VCALENDAR";
+
+char str2[] = "BEGIN:VCALENDAR\n\
+PRODID:\"-//RDU Software//NONSGML HandCal//EN\"\n\
+VERSION:2.0\n\
+BEGIN:VEVENT\n\
+DTSTAMP:19980309T231000Z\n\
+UID:guid-1.host1.com\n\
+ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com\n\
+ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:MAILTO:employee-A@host.com\n\
+DESCRIPTION:Project XYZ Review Meeting\n\
+CATEGORIES:MEETING\n\
+CLASS:PUBLIC\n\
+CREATED:19980309T130000Z\n\
+SUMMARY:XYZ Project Review\n\
+DTSTART;TZID=US-Eastern:19980312T083000\n\
+DTEND;TZID=US-Eastern:19980312T093000\n\
+LOCATION:1CP Conference Room 4350\n\
+END:VEVENT\n\
+END:VCALENDAR\n\
+";
+
+void test_fileset()
+{
+ icalfileset *cout;
+ int month = 0;
+ int count=0;
+ struct icaltimetype start, end;
+ icalcomponent *c,*clone, *itr;
+
+ start = icaltime_from_timet( time(0),0);
+ end = start;
+ end.hour++;
+
+ cout = icalfileset_new(OUTPUT_FILE);
+ assert(cout != 0);
+
+ c = icalparser_parse_string(str2);
+ assert(c != 0);
+
+ /* Add data to the file */
+
+ for(month = 1; month < 10; month++){
+ icalcomponent *event;
+ icalproperty *dtstart, *dtend;
+
+ cout = icalfileset_new(OUTPUT_FILE);
+ assert(cout != 0);
+
+ start.month = month;
+ end.month = month;
+
+ clone = icalcomponent_new_clone(c);
+ assert(clone !=0);
+ event = icalcomponent_get_first_component(clone,ICAL_VEVENT_COMPONENT);
+ assert(event != 0);
+
+ dtstart = icalcomponent_get_first_property(event,ICAL_DTSTART_PROPERTY);
+ assert(dtstart!=0);
+ icalproperty_set_dtstart(dtstart,start);
+
+ dtend = icalcomponent_get_first_property(event,ICAL_DTEND_PROPERTY);
+ assert(dtend!=0);
+ icalproperty_set_dtend(dtend,end);
+
+ icalfileset_add_component(cout,clone);
+ icalfileset_commit(cout);
+
+ icalset_free(cout);
+
+ }
+
+ /* Print them out */
+
+ cout = icalfileset_new(OUTPUT_FILE);
+ assert(cout != 0);
+
+ for (itr = icalfileset_get_first_component(cout);
+ itr != 0;
+ itr = icalfileset_get_next_component(cout)){
+
+ icalcomponent *event;
+ icalproperty *dtstart, *dtend;
+
+ count++;
+
+ event = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT);
+
+ dtstart = icalcomponent_get_first_property(event,ICAL_DTSTART_PROPERTY);
+ dtend = icalcomponent_get_first_property(event,ICAL_DTEND_PROPERTY);
+
+ printf("%d %s %s\n",count, icalproperty_as_ical_string(dtstart),
+ icalproperty_as_ical_string(dtend));
+
+ }
+
+ /* Remove all of them */
+
+ icalset_free(cout);
+
+ cout = icalfileset_new(OUTPUT_FILE);
+ assert(cout != 0);
+
+ for (itr = icalfileset_get_first_component(cout);
+ itr != 0;
+ itr = icalfileset_get_next_component(cout)){
+
+
+ icalfileset_remove_component(cout, itr);
+ }
+
+ icalset_free(cout);
+
+
+ /* Print them out again */
+
+ cout = icalfileset_new(OUTPUT_FILE);
+ assert(cout != 0);
+ count =0;
+
+ for (itr = icalfileset_get_first_component(cout);
+ itr != 0;
+ itr = icalfileset_get_next_component(cout)){
+
+ icalcomponent *event;
+ icalproperty *dtstart, *dtend;
+
+ count++;
+
+ event = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT);
+
+ dtstart = icalcomponent_get_first_property(event,ICAL_DTSTART_PROPERTY);
+ dtend = icalcomponent_get_first_property(event,ICAL_DTEND_PROPERTY);
+
+ printf("%d %s %s\n",count, icalproperty_as_ical_string(dtstart),
+ icalproperty_as_ical_string(dtend));
+
+ }
+
+ icalset_free(cout);
+
+
+}
+
+/*
+ In this example, we're storing a calendar with several components
+ under the reference id "calendar_7286" and retrieving records based
+ on title, "month_1" through "month_10". We use a number of the
+ "optional" arguments to specify secondary indices, sub-databases
+ (i.e. having multiple databases residing within a single Berkeley
+ DB file), and keys for storage and retrieval.
+*/
+
+#ifdef WITH_BDB4
+void test_bdbset()
+{
+ icalbdbset *cout;
+ int month = 0;
+ int count=0;
+ int num_components=0;
+ int szdata_len=0;
+ int ret=0;
+ char *subdb, *szdata, *szpacked_data;
+ char uid[255];
+ struct icaltimetype start, end;
+ icalcomponent *c,*clone, *itr;
+ DB *dbp, *sdbp;
+ DBT key, data;
+ DBC *dbcp;
+
+ struct calendar *cal;
+ int cal_size;
+
+ start = icaltime_from_timet( time(0),0);
+ end = start;
+ end.hour++;
+
+ /* Note: as per the Berkeley DB ref pages:
+ *
+ * The database argument is optional, and allows applications to
+ * have multiple databases in a single file. Although no database
+ * argument needs to be specified, it is an error to attempt to
+ * open a second database in a file that was not initially created
+ * using a database name.
+ *
+ */
+
+ subdb = "calendar_id";
+ sdbp = 0;
+
+ /* open database, using subdb */
+ dbp = icalbdbset_database_open(DATABASE, subdb, DB_HASH);
+ sdbp = icalbdbset_secondary_open(dbp,
+ DATABASE,
+ "title",
+ get_title,
+ DB_HASH);
+
+ c = icalparser_parse_string(str2);
+ assert(c != 0);
+
+ /* Add data to the file */
+
+ for(month = 1; month < 10; month++){
+ icalcomponent *event;
+ icalproperty *dtstart, *dtend, *location;
+
+ /* retrieve data */
+ cout = icalbdbset_new(dbp, sdbp, NULL);
+ assert(cout != 0);
+
+ start.month = month;
+ end.month = month;
+
+ clone = icalcomponent_new_clone(c);
+ assert(clone !=0);
+ event = icalcomponent_get_first_component(clone,
+ ICAL_VEVENT_COMPONENT);
+ assert(event != 0);
+
+ dtstart = icalcomponent_get_first_property(event,
+ ICAL_DTSTART_PROPERTY);
+ assert(dtstart!=0);
+ icalproperty_set_dtstart(dtstart,start);
+
+ dtend = icalcomponent_get_first_property(event,ICAL_DTEND_PROPERTY);
+ assert(dtend!=0);
+ icalproperty_set_dtend(dtend,end);
+
+ location = icalcomponent_get_first_property(event, ICAL_LOCATION_PROPERTY);
+ assert(location!=0);
+
+#if 0
+ /* change the uid to include the month */
+ sprintf(uid, "%s_%d", icalcomponent_get_uid(clone), month);
+ icalcomponent_set_uid(clone, uid);
+#endif
+
+ icalbdbset_add_component(cout,clone);
+
+ /* commit changes */
+ icalbdbset_commit(cout);
+
+ num_components = icalcomponent_count_components(clone, ICAL_ANY_COMPONENT);
+
+ icalset_free(cout);
+
+ }
+
+ /* try out the cursor operations */
+ memset(&key, 0, sizeof(DBT));
+ memset(&data, 0, sizeof(DBT));
+
+ ret = icalbdbset_acquire_cursor(dbp, &dbcp);
+ ret = icalbdbset_get_first(dbcp, &key, &data);
+ ret = icalbdbset_get_next(dbcp, &key, &data);
+ ret = icalbdbset_get_last(dbcp, &key, &data);
+
+ /* Print them out */
+
+ for(month = 1, count=0; month < 10; month++){
+ char *title;
+
+ icalcomponent *event;
+ icalproperty *dtstart, *dtend;
+
+ cout = icalbdbset_new(dbp, sdbp, NULL);
+ assert(cout != 0);
+
+ for (itr = icalbdbset_get_first_component(cout);
+ itr != 0;
+ itr = icalbdbset_get_next_component(cout)){
+
+ icalcomponent *event;
+ icalproperty *dtstart, *dtend;
+
+ count++;
+
+ event = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT);
+
+ dtstart = icalcomponent_get_first_property(event,ICAL_DTSTART_PROPERTY);
+ dtend = icalcomponent_get_first_property(event,ICAL_DTEND_PROPERTY);
+
+ printf("%d %s %s\n",count, icalproperty_as_ical_string(dtstart),
+ icalproperty_as_ical_string(dtend));
+
+ }
+ icalset_free(cout);
+ }
+
+ /* close database */
+ icalbdbset_database_close(dbp);
+ icalbdbset_database_close(sdbp);
+
+ /* open database */
+ dbp = icalbdbset_database_open(DATABASE, subdb, DB_HASH);
+ sdbp = icalbdbset_secondary_open(dbp,
+ DATABASE,
+ "title",
+ get_title,
+ DB_HASH);
+
+ /* Remove all of them */
+ for(month = 1; month < 10; month++){
+
+ cout = icalbdbset_new(dbp, sdbp, NULL);
+ assert(cout != 0);
+
+ for (itr = icalbdbset_get_first_component(cout);
+ itr != 0;
+ itr = icalbdbset_get_next_component(cout)){
+
+ icalbdbset_remove_component(cout, itr);
+ }
+
+ icalbdbset_commit(cout);
+ icalset_free(cout);
+
+ }
+
+ /* Print them out again */
+
+ for(month = 1, count=0; month < 10; month++){
+ char *title;
+
+ icalcomponent *event;
+ icalproperty *dtstart, *dtend;
+
+ cout = icalbdbset_new(dbp, sdbp, NULL);
+ assert(cout != 0);
+
+ for (itr = icalbdbset_get_first_component(cout);
+ itr != 0;
+ itr = icalbdbset_get_next_component(cout)){
+
+ icalcomponent *event;
+ icalproperty *dtstart, *dtend;
+
+ count++;
+
+ event = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT);
+
+ dtstart = icalcomponent_get_first_property(event,ICAL_DTSTART_PROPERTY);
+ dtend = icalcomponent_get_first_property(event,ICAL_DTEND_PROPERTY);
+
+ printf("%d %s %s\n",count, icalproperty_as_ical_string(dtstart),
+ icalproperty_as_ical_string(dtend));
+
+ }
+ icalset_free(cout);
+ }
+}
+
+/* get_title -- extracts a secondary key (the vcalendar)
+ * from a primary key/data pair */
+
+/* just create a random title for now */
+
+int get_title(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey)
+{
+ icalcomponent *cl;
+ char title[255];
+
+ memset(skey, 0, sizeof(DBT));
+
+ cl = icalparser_parse_string((char *)pdata->data);
+ sprintf(title, "title_%s", icalcomponent_get_uid(cl));
+
+ skey->data = strdup(title);
+ skey->size = strlen(skey->data);
+ return (0);
+}
+
+char * parse_vcalendar(const DBT *dbt)
+{
+ char *str;
+ struct calendar *cal;
+
+ str = (char *)dbt->data;
+ cal = unpack_calendar(str, dbt->size);
+
+ return cal->vcalendar;
+}
+
+#endif
+
+
+int vcalendar_init(struct calendar **rcal, char *vcalendar, char *title)
+{
+ int vcalendar_size, title_size, total_size;
+ struct calendar *cal;
+
+ if(vcalendar)
+ vcalendar_size = strlen(vcalendar);
+ else {
+ vcalendar = "";
+ vcalendar_size = strlen(vcalendar);
+ }
+
+ if(title)
+ title_size = strlen(title);
+ else {
+ title = "";
+ title_size = strlen(title);
+ }
+
+ total_size = sizeof(struct calendar) + vcalendar_size + title_size;
+
+ if((cal = (struct calendar *)malloc(total_size))==NULL)
+ return 0;
+ memset(cal, 0, total_size);
+
+ /* offsets */
+ cal->total_size_offset = sizeof(int);
+ cal->vcalendar_size_offset = (sizeof(int) * 7);
+ cal->vcalendar_offset = cal->vcalendar_size_offset + sizeof(int);
+ cal->title_size_offset = cal->vcalendar_offset + vcalendar_size;
+ cal->title_offset = cal->title_size_offset + sizeof(int);
+
+ /* sizes */
+ cal->total_size = total_size;
+ cal->vcalendar_size = vcalendar_size;
+ cal->title_size = title_size;
+
+ if (vcalendar && *vcalendar)
+ cal->vcalendar = strdup(vcalendar);
+
+ if (title && *title)
+ cal->title = strdup(title);
+
+ *rcal = cal;
+
+ return 0;
+}
+
+char * pack_calendar(struct calendar *cal, int size)
+{
+ char *str;
+
+ if((str = (char *)malloc(sizeof(char) * size))==NULL)
+ return 0;
+
+ /* ID */
+ memcpy(str, &cal->ID, sizeof(cal->ID));
+
+ /* total_size */
+ memcpy(str + cal->total_size_offset,
+ &cal->total_size,
+ sizeof(cal->total_size));
+
+ /* vcalendar_size */
+ memcpy(str + cal->vcalendar_size_offset,
+ &cal->vcalendar_size,
+ sizeof(cal->vcalendar_size));
+
+ /* vcalendar */
+ memcpy(str + cal->vcalendar_offset,
+ cal->vcalendar,
+ cal->vcalendar_size);
+
+ /* title_size */
+ memcpy(str + cal->title_size_offset,
+ &cal->title_size,
+ sizeof(cal->title_size));
+
+ /* title */
+ memcpy(str + cal->title_offset,
+ cal->title,
+ cal->title_size);
+
+ return str;
+}
+
+struct calendar * unpack_calendar(char *str, int size)
+{
+ struct calendar *cal;
+ if((cal = (struct calendar *) malloc(size))==NULL)
+ return 0;
+ memset(cal, 0, size);
+
+ /* offsets */
+ cal->total_size_offset = sizeof(int);
+ cal->vcalendar_size_offset = (sizeof(int) * 7);
+ cal->vcalendar_offset = cal->vcalendar_size_offset + sizeof(int);
+
+ /* ID */
+ memcpy(&cal->ID, str, sizeof(cal->ID));
+
+ /* total_size */
+ memcpy(&cal->total_size,
+ str + cal->total_size_offset,
+ sizeof(cal->total_size));
+
+ /* vcalendar_size */
+ memcpy(&cal->vcalendar_size,
+ str + cal->vcalendar_size_offset,
+ sizeof(cal->vcalendar_size));
+
+ if((cal->vcalendar = (char *)malloc(sizeof(char) *
+ cal->vcalendar_size))==NULL)
+ return 0;
+
+ /* vcalendar */
+ memcpy(cal->vcalendar,
+ (char *)(str + cal->vcalendar_offset),
+ cal->vcalendar_size);
+
+ cal->title_size_offset = cal->vcalendar_offset + cal->vcalendar_size;
+ cal->title_offset = cal->title_size_offset + sizeof(int);
+
+ /* title_size */
+ memcpy(&cal->title_size,
+ str + cal->title_size_offset,
+ sizeof(cal->title_size));
+
+ if((cal->title = (char *)malloc(sizeof(char) *
+ cal->title_size))==NULL)
+ return 0;
+
+ /* title*/
+ memcpy(cal->title,
+ (char *)(str + cal->title_offset),
+ cal->title_size);
+
+ return cal;
+}
+
+int test_dirset()
+{
+
+ icalcomponent *c, *gauge;
+ icalerrorenum error;
+ icalcomponent *itr;
+ icalfileset* cluster;
+ struct icalperiodtype rtime;
+ icaldirset *s = icaldirset_new("store");
+ int i;
+
+ assert(s != 0);
+
+ rtime.start = icaltime_from_timet( time(0),0);
+
+ cluster = icalfileset_new(OUTPUT_FILE);
+
+ assert(cluster != 0);
+
+#define NUMCOMP 4
+
+ /* Duplicate every component in the cluster NUMCOMP times */
+
+ icalerror_clear_errno();
+
+ for (i = 1; i<NUMCOMP+1; i++){
+
+ /*rtime.start.month = i%12;*/
+ rtime.start.month = i;
+ rtime.end = rtime.start;
+ rtime.end.hour++;
+
+ for (itr = icalfileset_get_first_component(cluster);
+ itr != 0;
+ itr = icalfileset_get_next_component(cluster)){
+ icalcomponent *clone, *inner;
+ icalproperty *p;
+
+ inner = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT);
+ if (inner == 0){
+ continue;
+ }
+
+ /* Change the dtstart and dtend times in the component
+ pointed to by Itr*/
+
+ clone = icalcomponent_new_clone(itr);
+ inner = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT);
+
+ assert(icalerrno == ICAL_NO_ERROR);
+ assert(inner !=0);
+
+ /* DTSTART*/
+ p = icalcomponent_get_first_property(inner,ICAL_DTSTART_PROPERTY);
+ assert(icalerrno == ICAL_NO_ERROR);
+
+ if (p == 0){
+ p = icalproperty_new_dtstart(rtime.start);
+ icalcomponent_add_property(inner,p);
+ } else {
+ icalproperty_set_dtstart(p,rtime.start);
+ }
+ assert(icalerrno == ICAL_NO_ERROR);
+
+ /* DTEND*/
+ p = icalcomponent_get_first_property(inner,ICAL_DTEND_PROPERTY);
+ assert(icalerrno == ICAL_NO_ERROR);
+
+ if (p == 0){
+ p = icalproperty_new_dtstart(rtime.end);
+ icalcomponent_add_property(inner,p);
+ } else {
+ icalproperty_set_dtstart(p,rtime.end);
+ }
+ assert(icalerrno == ICAL_NO_ERROR);
+
+ printf("\n----------\n%s\n---------\n",icalcomponent_as_ical_string(inner));
+
+ error = icaldirset_add_component(s,
+ icalcomponent_new_clone(itr));
+
+ assert(icalerrno == ICAL_NO_ERROR);
+
+ }
+
+ }
+
+ gauge =
+ icalcomponent_vanew(
+ ICAL_VCALENDAR_COMPONENT,
+ icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_vanew_summary(
+ "Submit Income Taxes",
+ icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_EQUAL),
+ 0),
+ 0),
+ icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_vanew_summary(
+ "Bastille Day Party",
+ icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_EQUAL),
+ 0),
+ 0),
+ 0);
+
+#if 0
+
+
+ icaldirset_select(s,gauge);
+
+ for(c = icaldirset_first(s); c != 0; c = icaldirset_next(s)){
+
+ printf("Got one! (%d)\n", count++);
+
+ if (c != 0){
+ printf("%s", icalcomponent_as_ical_string(c));;
+ if (icaldirset_store(s2,c) == 0){
+ printf("Failed to write!\n");
+ }
+ icalcomponent_free(c);
+ } else {
+ printf("Failed to get component\n");
+ }
+ }
+
+
+ icalset_free(s2);
+#endif
+
+
+ for(c = icaldirset_get_first_component(s);
+ c != 0;
+ c = icaldirset_get_next_component(s)){
+
+ if (c != 0){
+ printf("%s", icalcomponent_as_ical_string(c));;
+ } else {
+ printf("Failed to get component\n");
+ }
+
+ }
+
+ /* Remove all of the components */
+ i=0;
+ while((c=icaldirset_get_current_component(s)) != 0 ){
+ i++;
+
+ icaldirset_remove_component(s,c);
+ }
+
+
+ icalset_free(s);
+ return 0;
+}
+
+#if 0
+void test_calendar()
+{
+ icalcomponent *comp;
+ icalfileset *c;
+ icaldirset *s;
+ icalcalendar* calendar = icalcalendar_new("calendar");
+ icalerrorenum error;
+ struct icaltimetype atime = icaltime_null_time();
+
+ comp = icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_new_version("2.0"),
+ icalproperty_new_description("This is an event"),
+ icalproperty_new_dtstart(atime),
+ icalproperty_vanew_comment(
+ "Another Comment",
+ icalparameter_new_cn("A Common Name 1"),
+ icalparameter_new_cn("A Common Name 2"),
+ icalparameter_new_cn("A Common Name 3"),
+ icalparameter_new_cn("A Common Name 4"),
+ 0),
+ icalproperty_vanew_xlicerror(
+ "This is only a test",
+ icalparameter_new_xlicerrortype(ICAL_XLICERRORTYPE_COMPONENTPARSEERROR),
+ 0),
+
+ 0);
+
+
+ s = icalcalendar_get_booked(calendar);
+
+ error = icaldirset_add_component(s,comp);
+
+ assert(error == ICAL_NO_ERROR);
+
+ c = icalcalendar_get_properties(calendar);
+
+ error = icalfileset_add_component(c,icalcomponent_new_clone(comp));
+
+ assert(error == ICAL_NO_ERROR);
+
+ icalcalendar_free(calendar);
+
+}
+#endif
+
+int main(int argc, char *argv[])
+{
+
+ printf("\n------------Test File Set---------------\n");
+ test_fileset();
+
+ printf("\n------------Test Dir Set---------------\n");
+ test_dirset();
+
+#ifdef WITH_BDB4
+ printf("\n------------Test BerkeleyDB Set---------------\n");
+ test_bdbset();
+#endif
+
+#if 0
+ printf("\n------------Test Calendar---------------\n");
+ test_calendar();
+#endif
+
+ return 0;
+}
+
+
+
diff --git a/src/test/stow.c b/src/test/stow.c
new file mode 100644
index 00000000..2836604a
--- /dev/null
+++ b/src/test/stow.c
@@ -0,0 +1,895 @@
+/* -*- Mode: C -*-
+ ======================================================================
+ FILE: stow.c
+ CREATOR: eric 29 April 2000
+
+ $Id: stow.c,v 1.10 2008-01-02 20:07:46 dothebart Exp $
+ $Locker: $
+
+ (C) COPYRIGHT 2000 Eric Busboom
+ http://www.softwarestudio.org
+
+ The contents of this file are subject to the Mozilla Public License
+ Version 1.0 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and
+ limitations under the License.
+
+ The Initial Developer of the Original Code is Eric Busboom
+
+ ======================================================================*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <limits.h> /* for PATH_MAX */
+#include <assert.h>
+#include <stdlib.h>
+#include <sys/utsname.h> /* for uname */
+#include <sys/stat.h> /* for stat */
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h> /* for stat, getpid, getopt */
+#endif
+#include <pwd.h> /* For getpwent */
+#include <sys/types.h> /* For getpwent */
+#include <ctype.h> /* for tolower */
+
+#include <libical/ical.h>
+#include <libicalss/icalss.h>
+
+char* program_name;
+#define TMPSIZE 2048
+#define SENDMAIL "/usr/lib/sendmail -t"
+
+void usage(char *message);
+
+#ifndef PATH_MAX
+#define PATH_MAX 256 /* HACK */
+#endif
+
+
+enum options {
+ STORE_IN_FILE,
+ STORE_IN_DB,
+ INPUT_IS_MIME,
+ INPUT_IS_ICAL,
+ INPUT_FROM_STDIN,
+ INPUT_FROM_FILE,
+ ERRORS_TO_STDOUT,
+ ERRORS_TO_ORGANIZER
+};
+
+struct options_struct
+{
+ enum options storage;
+ enum options input_type;
+ enum options input_source;
+ enum options errors;
+ char* input_file;
+ char* calid;
+ char* output_file;
+};
+
+
+enum file_type
+{
+ ERROR,
+ NO_FILE,
+ DIRECTORY,
+ REGULAR,
+ OTHER
+};
+
+enum file_type test_file(char *path)
+{
+ struct stat sbuf;
+ enum file_type type;
+
+ errno = 0;
+
+ /* Check if the path already exists and if it is a directory*/
+ if (stat(path,&sbuf) != 0){
+
+ /* A file by the given name does not exist, or there was
+ another error */
+ if(errno == ENOENT)
+ {
+ type = NO_FILE;
+ } else {
+ type = ERROR;
+ }
+
+ } else {
+ /* A file by the given name exists, but is it a directory? */
+
+ if (S_ISDIR(sbuf.st_mode)){
+ type = DIRECTORY;
+ } else if(S_ISREG(sbuf.st_mode)){
+ type = REGULAR;
+ } else {
+ type = OTHER;
+ }
+ }
+
+ return type;
+}
+
+char* lowercase(const char* str)
+{
+ char* p = 0;
+ char* new = strdup(str);
+
+ if(str ==0){
+ return 0;
+ }
+
+ for(p = new; *p!=0; p++){
+ *p = tolower(*p);
+ }
+
+ return new;
+}
+
+#if 0
+char* get_local_attendee(struct options_struct *opt)
+{
+ char attendee[PATH_MAX];
+
+ if(opt->calid){
+
+ strncpy(attendee,opt->calid,PATH_MAX);
+
+ } else {
+
+ char* user = getenv("USER");
+ struct utsname uts;
+ uname(&utget_option);
+ /* HACK nodename may not be a fully qualified domain name */
+ snprintf(attendee,PATH_MAX,"%s@%s",user,uts.nodename);
+
+ }
+
+ return lowercase(attendee);
+}
+#endif
+
+
+icalcomponent* get_first_real_component(icalcomponent *comp)
+{
+ icalcomponent *c;
+
+ for(c = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT);
+ c != 0;
+ c = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT)){
+ if (icalcomponent_isa(c) == ICAL_VEVENT_COMPONENT ||
+ icalcomponent_isa(c) == ICAL_VTODO_COMPONENT ||
+ icalcomponent_isa(c) == ICAL_VJOURNAL_COMPONENT )
+ {
+ return c;
+ }
+ }
+
+ return 0;
+}
+
+
+
+char* make_mime(const char* to, const char* from, const char* subject,
+ const char* text_message, const char* method,
+ const char* ical_message)
+{
+ size_t size = strlen(to)+strlen(from)+strlen(subject)+
+ strlen(text_message)+ strlen(ical_message)+TMPSIZE;
+
+ char mime_part_1[TMPSIZE];
+ char mime_part_2[TMPSIZE];
+ char content_id[TMPSIZE];
+ char boundary[TMPSIZE];
+ struct utsname uts;
+ char* m;
+
+
+ if ((m = malloc(sizeof(char)*size)) == 0){
+ fprintf(stderr,"%s: Can't allocate memory: %s\n",program_name,strerror(errno));
+ exit(1);
+ }
+
+ uname(&uts);
+
+ srand(time(0)<<getpid());
+ sprintf(content_id,"%d-%d@%s",(int)time(0),rand(),uts.nodename);
+ sprintf(boundary,"%d-%d-%s",(int)time(0),rand(),uts.nodename);
+
+ sprintf(mime_part_1,"Content-ID: %s\n\
+Content-type: text/plain\n\
+Content-Description: Text description of error message\n\n\
+%s\n\n--%s",
+ content_id,text_message,boundary);
+
+ if(ical_message != 0 && method != 0){
+ sprintf(mime_part_2,"Content-ID: %s\n\
+Content-type: text/calendar; method=%s\n\
+Content-Description: iCal component reply\n\n\
+%s\n\n--%s--",
+ content_id,method,ical_message,boundary);
+ }
+
+ sprintf(m,"To: %s\n\
+From: %s\n\
+Subject: %s\n\
+MIME-Version: 1.0\n\
+Content-ID: %s\n\
+Content-Type: multipart/mixed; boundary=\"%s\"\n\
+\n\
+ This is a multimedia message in MIME format\n\
+\n\
+--%s\n\
+%s\n\
+",
+ to,from,subject,content_id,boundary,boundary,
+ mime_part_1);
+
+ if(ical_message != 0 && method != 0){
+ strcat(m, mime_part_2);
+ } else {
+ strcat(m,"--\n");
+ }
+
+ return m;
+}
+
+/* The incoming component had fatal errors */
+void return_failure(icalcomponent* comp, char* message,
+ struct options_struct *opt)
+{
+ char* local_attendee = opt->calid;
+ FILE* p;
+ const char *org_addr;
+
+ icalcomponent *inner = get_first_real_component(comp);
+
+ icalproperty *organizer_prop = icalcomponent_get_first_property(inner,ICAL_ORGANIZER_PROPERTY);
+ const char *organizer = icalproperty_get_organizer(organizer_prop);
+
+ org_addr = strchr(organizer,':');
+
+ if(org_addr != 0){
+ org_addr++; /* Skip the ';' */
+ } else {
+ org_addr = organizer;
+ }
+
+ if (opt->errors == ERRORS_TO_ORGANIZER){
+ p = popen(SENDMAIL,"w");
+ } else {
+ p = stdout;
+ }
+
+ if(p == 0){
+ fprintf(stderr,
+ "%s: fatal. Could not open pipe to sendmail (\"%s\") \n",
+ program_name,SENDMAIL);
+ exit(1);
+ }
+
+ fputs(make_mime(org_addr, local_attendee, "iMIP error",
+ message, "reply",
+ icalcomponent_as_ical_string(comp)),p);
+
+ if (opt->errors == ERRORS_TO_ORGANIZER){
+ pclose(p);
+ }
+}
+
+/* The program had a fatal error and could not process the incoming component*/
+void return_error(icalcomponent* comp, char* message, struct options_struct *opt)
+{
+
+
+ fputs(make_mime("Dest", "Source", "iMIP system failure",
+ message, 0,0),stdout);
+
+}
+
+icalcomponent* make_reply(icalcomponent *comp, icalproperty *return_status,
+ struct options_struct *opt)
+
+{
+ icalcomponent *reply, *rinner;
+ icalcomponent *inner = get_first_real_component(comp);
+ icalproperty *p=0;
+ char* local_attendee = opt->calid;
+ char attendee[TMPSIZE];
+
+ char prodid[TMPSIZE];
+
+ snprintf(attendee,TMPSIZE,"mailto:%s",local_attendee);
+
+ snprintf(prodid,TMPSIZE,"-//Softwarestudio.org//%s version %s//EN",ICAL_PACKAGE,ICAL_VERSION);
+
+ /* Create the base component */
+ reply = icalcomponent_vanew(
+ ICAL_VCALENDAR_COMPONENT,
+ icalproperty_new_version(strdup("2.0")),
+ icalproperty_new_prodid(strdup(prodid)),
+ icalproperty_new_method(ICAL_METHOD_REPLY),
+ icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_new_clone(
+ icalcomponent_get_first_property(inner,ICAL_DTSTAMP_PROPERTY)),
+ icalproperty_new_clone(
+ icalcomponent_get_first_property(inner,ICAL_ORGANIZER_PROPERTY)),
+ icalproperty_new_clone(
+ icalcomponent_get_first_property(inner,ICAL_UID_PROPERTY)),
+ icalproperty_new_attendee(attendee),
+ 0),
+ 0);
+
+
+ /* Convert errors into request-status properties and transfers
+ them to the reply component */
+
+ icalcomponent_convert_errors(comp);
+
+ rinner = get_first_real_component(reply);
+
+ for(p = icalcomponent_get_first_property(inner,
+ ICAL_REQUESTSTATUS_PROPERTY);
+ p != 0;
+ p = icalcomponent_get_next_property(inner,
+ ICAL_REQUESTSTATUS_PROPERTY)){
+
+ icalcomponent_add_property(rinner,icalproperty_new_clone(p));
+ }
+
+ if(return_status != 0){
+ icalcomponent_add_property(rinner, return_status);
+ }
+
+ return reply;
+
+}
+
+int check_attendee(icalproperty *p, struct options_struct *opt){
+ const char* s = icalproperty_get_attendee(p);
+ char* lower_attendee = lowercase(s);
+ char* local_attendee = opt->calid;
+
+ /* Check that attendee begins with "mailto:" */
+ if (strncmp(lower_attendee,"mailto:",7) == 0){
+ /* skip over the mailto: part */
+ lower_attendee += 7;
+
+ if(strcmp(lower_attendee,local_attendee) == 0){
+ return 1;
+ }
+
+ lower_attendee -= 7;
+
+ free(lower_attendee);
+ }
+
+ return 0;
+}
+
+char static_component_error_str[PATH_MAX];
+char* check_component(icalcomponent* comp, icalproperty **return_status,
+ struct options_struct *opt)
+{
+ char* component_error_str=0;
+ icalcomponent* inner;
+ int errors = 0;
+ icalproperty *p;
+ int found_attendee = 0;
+ struct icalreqstattype rs;
+
+ rs.code = ICAL_UNKNOWN_STATUS;
+ rs.desc = 0;
+ rs.debug = 0;
+
+ /*{
+ icalrequeststatus code;
+ const char* desc;
+ const char* debug;
+ };*/
+
+ *return_status = 0;
+
+ /* This do/while loop only executes once because it is being used
+ to fake exceptions */
+
+ do {
+
+ /* Check that we actually got a component */
+ if(comp == 0){
+ strcpy(static_component_error_str,
+ "Did not find a component");
+ component_error_str = static_component_error_str;
+ break;
+ }
+
+ /* Check that the root component is a VCALENDAR */
+ if(icalcomponent_isa(comp) != ICAL_VCALENDAR_COMPONENT){
+ strcpy(static_component_error_str,
+ "Root component is not a VCALENDAR");
+ component_error_str = static_component_error_str;
+ rs.code = ICAL_3_11_MISSREQCOMP_STATUS;
+
+ break;
+ }
+
+
+ /* Check that the component has a METHOD */
+
+ if (icalcomponent_get_first_property(comp,ICAL_METHOD_PROPERTY) == 0)
+ {
+ strcpy(static_component_error_str,
+ "The component you sent did not have a METHOD property");
+ component_error_str = static_component_error_str;
+ rs.code = ICAL_3_11_MISSREQCOMP_STATUS;
+ break;
+ }
+
+ inner = get_first_real_component(comp);
+
+
+ /* Check that the compopnent has an organizer */
+ if(icalcomponent_get_first_property(inner,ICAL_ORGANIZER_PROPERTY) == 0){
+ fprintf(stderr,"%s: fatal. Component does not have an ORGANIZER property\n",program_name);
+ rs.code = ICAL_3_11_MISSREQCOMP_STATUS;
+ break;
+ }
+
+
+ /* Check for this user as an attendee or organizer */
+
+ for(p = icalcomponent_get_first_property(inner,ICAL_ATTENDEE_PROPERTY);
+ p != 0;
+ p = icalcomponent_get_next_property(inner,ICAL_ATTENDEE_PROPERTY)){
+
+ found_attendee += check_attendee(p,opt);
+ }
+
+ for(p = icalcomponent_get_first_property(inner,ICAL_ORGANIZER_PROPERTY);
+ p != 0;
+ p = icalcomponent_get_next_property(inner,ICAL_ORGANIZER_PROPERTY)){
+
+ found_attendee += check_attendee(p,opt);
+ }
+
+ if (found_attendee == 0){
+ struct icalreqstattype rs;
+ memset(static_component_error_str,0,PATH_MAX);
+
+ snprintf(static_component_error_str,PATH_MAX,
+ "This target user (%s) is not listed as an attendee or organizer",
+ opt->calid );
+ component_error_str = static_component_error_str;
+
+ rs.code = ICAL_3_7_INVCU_STATUS;
+
+ break;
+ }
+
+
+
+ /* Check that the component passes iTIP restrictions */
+
+ errors = icalcomponent_count_errors(comp);
+ icalrestriction_check(comp);
+
+ if(errors != icalcomponent_count_errors(comp)){
+ snprintf(static_component_error_str,PATH_MAX,
+ "The component does not conform to iTIP restrictions.\n Here is the original component; look at the X-LIC-ERROR properties\nfor details\n\n%s",icalcomponent_as_ical_string(comp));
+ component_error_str = static_component_error_str;
+ break;
+ }
+
+
+
+ } while(0);
+
+ if(rs.code != ICAL_UNKNOWN_STATUS){
+ *return_status = icalproperty_new_requeststatus(rs);
+ }
+
+ return component_error_str;
+}
+
+
+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 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\
+-n\tSend errors to stdout instead of organizer\n\
+");
+
+}
+
+
+void get_options(int argc, char* argv[], struct options_struct *opt)
+{
+ int c;
+#if !defined(HAVE_UNISTD_H)
+ extern char *optarg;
+ extern int optind, optopt;
+#endif
+ int errflg=0;
+
+ opt->storage = STORE_IN_FILE;
+ opt->input_source = INPUT_FROM_STDIN;
+ opt->input_type = INPUT_IS_ICAL;
+ opt->input_file = 0;
+ opt->errors = ERRORS_TO_ORGANIZER;
+ opt->calid = 0;
+ opt->output_file = 0;
+
+
+ while ((c = getopt(argc, argv, "nemu:o:d:b:c:i:")) != -1) {
+ switch (c) {
+ case 'e': { /* Input data is MIME encapsulated */
+ opt->input_type = INPUT_IS_MIME;
+ break;
+ }
+ case 'm': { /* Input is iCal. Default*/
+ opt->input_type = INPUT_IS_ICAL;
+ break;
+ }
+ case 'i': { /* Input comes from named file */
+ opt->input_source = INPUT_FROM_FILE;
+ opt->input_file = strdup(optarg);
+ break;
+ }
+ case 'o': { /* Output goes to named file. Default*/
+ opt->output_file = strdup(optarg);
+ opt->storage = STORE_IN_FILE;
+ break;
+ }
+ case 'd': { /* Output goes to database */
+ fprintf(stderr,"%s: option -d is unimplmented\n",program_name);
+ opt->storage = STORE_IN_DB;
+ errflg++;
+ break;
+ }
+ case 'c': {
+
+ break;
+ }
+ case 'u': { /* Set the calid for the output database or
+ file. Default is user name of user running
+ program */
+ opt->calid = strdup(optarg);
+ break;
+ }
+
+ case 'n': { /* Dump error to stdout. Default is to
+ send error to the organizer specified
+ in the iCal data */
+ opt->errors = ERRORS_TO_STDOUT;
+ break;
+ }
+
+ case ':': {/* Option given without an operand */
+ fprintf(stderr,
+ "%s: Option -%c requires an operand\n",
+ program_name,optopt);
+ errflg++;
+ break;
+ }
+ case '?': {
+ errflg++;
+ }
+
+ }
+
+ if (errflg >0){
+ usage("");
+ exit(1);
+ }
+ }
+
+ if(opt->calid == 0){
+ /* If no calid specified, use username */
+ char attendee[PATH_MAX];
+ char* user = getenv("USER");
+ struct utsname uts;
+ uname(&uts);
+ /* HACK nodename may not be a fully qualified domain name */
+ snprintf(attendee,PATH_MAX,"%s@%s",user,uts.nodename);
+
+ opt->calid = lowercase(attendee);
+ }
+
+ if(opt->storage == STORE_IN_FILE &&
+ opt->output_file ==0){
+ char file[PATH_MAX];
+ char* user = getenv("USER");
+ struct passwd *pw;
+
+ if(!user){
+ fprintf(stderr,"%s: Can't get username. Try explicitly specifing the output file with -o", program_name);
+ exit(1);
+ }
+
+ /* Find password entry for user */
+ while( (pw = getpwent())!=0){
+ if(strcmp(user,pw->pw_name)==0){
+ break;
+ }
+ }
+
+ if(pw==0){
+ fprintf(stderr,"%s: Can't get get password entry for user \"%s\" Try explicitly specifing the output file with -o",
+ program_name,user);
+ exit(1);
+ }
+
+ if(pw->pw_dir==0){
+ fprintf(stderr,"%s: User \"%s\" has no home directory. Try explicitly specifing the output file with -o",
+ program_name, user);
+ exit(1);
+ }
+
+ snprintf(file,PATH_MAX,"%s/.facs/%s",pw->pw_dir,opt->calid);
+
+ opt->output_file = strdup(file);
+ }
+
+
+ /* Now try to create the calendar directory if it does
+ not exist */
+
+ if(opt->storage == STORE_IN_FILE ) {
+ char * p;
+ char* facspath = strdup(opt->output_file);
+ enum file_type type;
+
+ /* Cut off the last slash to make it just a directoy */
+
+ p = strrchr(facspath,'/');
+
+ if (p != 0){
+ /* Use some other directory */
+ *p='\0';
+
+ type = test_file(facspath);
+
+ errno = 0;
+ if (type == NO_FILE){
+
+ if(mkdir(facspath,0775) != 0){
+ fprintf(stderr,
+ "%s: Failed to create calendar directory %s: %s\n",
+ program_name,facspath, strerror(errno));
+ exit(1);
+ } else {
+ fprintf(stderr,"%s: Creating calendar directory %s\n",
+ program_name,facspath);
+ }
+
+ } else if(type==REGULAR || type == ERROR){
+ fprintf(stderr,"%s: Cannot create calendar directory %s\n",
+ program_name,facspath);
+ exit(1);
+ }
+ }
+ }
+}
+
+char* check_options(struct options_struct *opt)
+{
+ return 0;
+}
+
+void store_component(icalcomponent *comp, struct options_struct *opt)
+{
+ icalerrorenum error;
+
+
+ if(opt->storage == STORE_IN_FILE){
+ icalset *fs = icalfileset_new(opt->output_file);
+
+ if (fs == 0){
+ fprintf(stderr,
+ "%s: Failed to get incoming component directory: %s\n",
+ program_name, icalerror_strerror(icalerrno));
+ exit(1);
+ }
+
+
+ error = icalfileset_add_component(fs,comp);
+
+ if (error != ICAL_NO_ERROR){
+ fprintf(stderr,"%s: Failed to write incoming component: %s\n",
+ program_name, icalerror_strerror(icalerrno));
+ exit(1);
+ }
+
+ error = icalfileset_commit(fs);
+
+ if (error != ICAL_NO_ERROR){
+ fprintf(stderr,"%s: Failed to commit incoming cluster: %s\n",
+ program_name, icalerror_strerror(icalerrno));
+ exit(1);
+ }
+
+ icalset_free(fs);
+
+ return;
+ } else {
+ assert(0);
+ }
+}
+
+char* read_stream(char *s, size_t size, void *d)
+{
+ char *c = fgets(s,size, (FILE*)d);
+
+ return c;
+}
+
+icalcomponent* read_nonmime_component(struct options_struct *opt)
+{
+ FILE *stream;
+ icalcomponent *comp;
+ icalparser* parser = icalparser_new();
+ icalerrorstate es = icalerror_get_error_state(ICAL_MALFORMEDDATA_ERROR);
+ char* line;
+
+ if(opt->input_source == INPUT_FROM_FILE){
+ stream = fopen(opt->input_file,"r");
+
+ if (stream == 0){
+ perror("Can't open input file");
+ exit(1);
+ }
+
+ } else {
+ stream = stdin;
+ }
+
+ assert(stream != 0);
+ icalparser_set_gen_data(parser,stream);
+
+ do {
+ line = icalparser_get_line(parser,read_stream);
+
+ icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,ICAL_ERROR_NONFATAL);
+ comp = icalparser_add_line(parser,line);
+ icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,es);
+
+ if (comp != 0){
+ return comp;
+ }
+
+ } while ( line != 0);
+
+ if(opt->input_source == INPUT_FROM_FILE){
+ fclose(stream);
+ }
+
+
+ return comp;
+ }
+
+icalcomponent* find_vcalendar(icalcomponent* comp)
+{
+ icalcomponent *c,*rtrn;
+
+ for(c = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT);
+ c != 0;
+ c = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT)){
+
+ if(icalcomponent_isa(c) == ICAL_VCALENDAR_COMPONENT){
+ icalcomponent_remove_component(comp,c);
+ return c;
+ }
+
+ if((rtrn=find_vcalendar(c)) != 0){
+ return rtrn;
+ }
+ }
+
+ return 0;
+}
+
+icalcomponent* read_mime_component(struct options_struct *opt)
+{
+ icalcomponent *comp,*mimecomp;
+ FILE* stream;
+
+ if(opt->input_source == INPUT_FROM_FILE){
+ stream = fopen(opt->input_file,"r");
+
+ if (stream == 0){
+ perror("Can't open input file");
+ exit(1);
+ }
+
+ } else {
+ stream = stdin;
+ }
+
+ assert(stream != 0);
+
+ mimecomp = icalmime_parse(read_stream,(void*)stream);
+
+ /* now find the iCal component embedded within the mime component */
+ comp = find_vcalendar(mimecomp);
+
+
+ if(comp == 0){
+ return 0;
+ }
+
+ return comp;
+}
+
+icalcomponent* read_component(struct options_struct *opt)
+{
+ if(opt->input_type == INPUT_IS_MIME){
+ return read_mime_component(opt);
+ } else if (opt->input_type == INPUT_IS_ICAL){
+ return read_nonmime_component(opt);
+ } else {
+ fprintf(stderr,"%s: Internal Error; unknown option for input_type\n",
+ program_name);
+ exit(1);
+ }
+}
+
+int main(int argc, char* argv[] )
+{
+ char* options_error_str;
+ char* component_error_str;
+ icalcomponent* comp, *reply;
+ struct options_struct opt;
+ icalproperty *return_status;
+
+ program_name = strrchr(argv[0],'/');
+
+ get_options(argc, argv, &opt);
+
+ if ( (options_error_str = check_options(&opt)) != 0 ){
+ usage(options_error_str);
+ exit(1);
+ }
+
+ comp = read_component(&opt);
+
+ /* If the component had any fatal errors, return an error message
+ to the organizer */
+ if ( (component_error_str =
+ check_component(comp,&return_status,&opt)) != 0){
+
+ reply = make_reply(comp,return_status,&opt);
+
+ return_failure(reply, component_error_str, &opt);
+ icalcomponent_free(reply);
+ exit(0);
+
+ }
+
+ store_component(comp,&opt);
+
+
+ /* Don't free the component comp, since it is now part of the
+ store, and will be freed there */
+
+ exit(0);
+}
+
diff --git a/src/test/testclassify.c b/src/test/testclassify.c
new file mode 100644
index 00000000..946f29ca
--- /dev/null
+++ b/src/test/testclassify.c
@@ -0,0 +1,129 @@
+/* -*- Mode: C -*-
+ ======================================================================
+ FILE: testclassify.c
+ CREATOR: eric 11 February 2000
+
+ $Id: testclassify.c,v 1.6 2008-01-02 20:07:46 dothebart Exp $
+ $Locker: $
+
+ (C) COPYRIGHT 2000 Eric Busboom
+ http://www.softwarestudio.org
+
+ The contents of this file are subject to the Mozilla Public License
+ Version 1.0 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and
+ limitations under the License.
+
+ The Original Code is eric. The Initial Developer of the Original
+ Code is Eric Busboom
+
+
+ ======================================================================*/
+
+#include <stdio.h> /* for printf */
+#include <libical/ical.h>
+#include <errno.h>
+#include <string.h> /* For strerror */
+#include <libicalss/icalss.h>
+
+/* Get a note about the purpose of the property*/
+const char* get_note(icalcomponent *c)
+{
+ icalproperty *p;
+ const char* note = 0;
+
+ if(c != 0){
+ for(p = icalcomponent_get_first_property(c,ICAL_X_PROPERTY);
+ p!= 0;
+ p = icalcomponent_get_next_property(c,ICAL_X_PROPERTY)){
+ if(strcmp(icalproperty_get_x_name(p),"X-LIC-NOTE")==0){
+ note = icalproperty_get_x(p);
+ }
+ }
+ }
+
+ if(note == 0){
+ note = "None";
+ }
+
+ return note;
+}
+
+
+int main(int argc, char* argv[])
+{
+ icalcomponent *c;
+ int i=0;
+
+ /* Open up the two storage files, one for the incomming components,
+ one for the calendar */
+ icalfileset_options options = {O_RDONLY, 0644, 0};
+ icalset* incoming = icalset_new(ICAL_FILE_SET, TEST_DATADIR "/incoming.ics", &options);
+ icalset* cal = icalset_new(ICAL_FILE_SET, TEST_DATADIR "/calendar.ics", &options);
+
+ assert(incoming!= 0);
+ assert(cal!=0);
+
+ /* Iterate through all of the incoming components */
+ for(c=icalset_get_first_component(incoming);c!=0;
+ c=icalset_get_next_component(incoming)){
+
+ icalproperty_xlicclass class;
+ icalcomponent *match = 0;
+ const char* this_uid;
+
+ i++;
+
+ /* Check this component against the restrictions imposed by
+ iTIP. An errors will be inserted as X-LIC-ERROR properties
+ in the component. The Parser will also insert errors if it
+ cannot parse the component */
+ icalcomponent_check_restrictions(c);
+
+ /* If there are any errors, print out the component */
+ if(icalcomponent_count_errors(c) != 0){
+ printf("----- Component has errors ------- \n%s-----------------\n",
+ icalcomponent_as_ical_string(c));
+ }
+
+ /* Use one of the icalcomponent convenience routines to get
+ the UID. This routine will save you from having to use
+ icalcomponent_get_inner(),
+ icalcomponent_get_first_property(), checking the return
+ value, and then calling icalproperty_get_uid. There are
+ several other convenience routines for DTSTART, DTEND,
+ DURATION, SUMMARY, METHOD, and COMMENT */
+ this_uid = icalcomponent_get_uid(c);
+
+ if(this_uid != 0){
+ /* Look in the calendar for a component with the same UID
+ as the incomming component. We should reall also be
+ checking the RECURRENCE-ID. Another way to do this
+ operation is to us icalset_find_match(), which does use
+ the RECURRENCE-ID. */
+ match = icalset_fetch(cal,this_uid);
+ }
+
+
+ /* Classify the incoming component. The third argument is the
+ calid of the user who owns the calendar. In a real program,
+ you would probably switch() on the class.*/
+ class = icalclassify(c,match,"A@example.com");
+
+ printf("Test %d\n\
+Incoming: %s\n\
+Matched: %s\n\
+Classification: %s\n\n",
+ i,get_note(c),get_note(match),
+ icalproperty_enum_to_string(class));
+ }
+
+ return 0;
+}
+
+
diff --git a/src/test/testmime.c b/src/test/testmime.c
new file mode 100644
index 00000000..effb495d
--- /dev/null
+++ b/src/test/testmime.c
@@ -0,0 +1,351 @@
+/* -*- Mode: C -*-
+ ======================================================================
+ FILE:
+ CREATOR: eric 25 June 2000
+
+ $Id: testmime.c,v 1.6 2008-02-03 16:10:48 dothebart Exp $
+ $Locker: $
+
+ The contents of this file are subject to the Mozilla Public License
+ Version 1.0 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and
+ limitations under the License.
+
+
+ This 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 Initial Developer of the Original Code is Eric Busboom
+
+ (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org
+ ======================================================================*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <libical/ical.h>
+
+#include <stdlib.h> /* For rand */
+#include <string.h> /* for strrchr, strdup*/
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h> /* for getopt */
+#endif
+
+/*int sspm_parse_mime(struct sspm_part *parts,
+ size_t max_parts,
+ struct sspm_action_map *actions,
+ char* (*get_string)(char *s, size_t size, void* data),
+ void *get_string_data,
+ struct sspm_header *first_header
+ );
+*/
+
+
+
+char* major_type_string[] = {
+ "TEXT",
+ "IMAGE",
+ "AUDIO",
+ "VIDEO",
+ "APPLICATION",
+ "MULTIPART",
+ "MESSAGE",
+ "UNKNOWN",
+ "NO"
+};
+
+char* minor_type_string[] = {
+ "ANY",
+ "PLAIN",
+ "RFC822",
+ "DIGEST",
+ "CALENDAR",
+ "MIXED",
+ "RELATED",
+ "ALTERNATIVE",
+ "PARALLEL",
+ "UNKNOWN",
+ "NO"
+};
+
+
+char* read_stream(char *s, size_t size, void *d)
+{
+ char *c = fgets(s,size, (FILE*)d);
+
+ return c;
+
+}
+
+
+int main(int argc, char* argv[]) {
+
+ FILE *f;
+ int c;
+#if !defined(HAVE_UNISTD_H)
+ extern char *optarg;
+ extern int optind, optopt;
+#endif
+ int errflg=0;
+ char* program_name;
+
+ struct options{
+ int normal;
+ int stress;
+ int base64;
+ int qp;
+ int sleep;
+ int count;
+ char* input_file;
+ } opt;
+
+ memset(&opt,0,sizeof(opt));
+
+ program_name = (char*)strrchr((char*)argv[0],'/');
+ program_name++;
+
+ while ((c = getopt(argc, argv, "nsbqi:S:c:")) != -1) {
+ switch (c) {
+ case 'i': { /* Input comes from named file */
+ opt.input_file = strdup(optarg);
+ break;
+ }
+ case 'n':{ /* Normal */
+
+ if(opt.stress+opt.base64+opt.qp != 0){
+ fprintf(stderr,
+ "%s: Use only one of n,s,b and q\n",
+ program_name);
+ }
+ opt.normal = 1;
+ break;
+ }
+ case 's':{ /* Stress-test*/
+ if(opt.base64+opt.normal+opt.qp != 0){
+ fprintf(stderr,
+ "%s: Use only one of n,s,b and q\n",
+ program_name);
+ }
+ opt.stress = 1;
+ break;
+ }
+ case 'b':{ /* test base64 decoding*/
+ if(opt.stress+opt.normal+opt.qp != 0){
+ fprintf(stderr,
+ "%s: Use only one of n,s,b and q\n",
+ program_name);
+ }
+ opt.base64 = 1;
+ break;
+ }
+ case 'q':{ /* test quoted-printable decoding*/
+ if(opt.stress+opt.base64+opt.normal != 0){
+ fprintf(stderr,
+ "%s: Use only one of n,s,b and q\n",
+ program_name);
+ }
+ opt.qp = 1;
+ break;
+ }
+ case 'S':{ /* sleep at end of run */
+ opt.sleep = atoi(optarg);
+ break;
+ }
+
+ case 'c':{ /* number of iterations of stress test */
+ opt.count = atoi(optarg);
+ break;
+ }
+
+ case ':': {/* Option given without an operand */
+ fprintf(stderr,
+ "%s: Option -%c requires an operand\n",
+ program_name,optopt);
+ errflg++;
+ break;
+ }
+ case '?': {
+ errflg++;
+ }
+ }
+ }
+
+ if (errflg >0){
+ fprintf(stderr,"Usage: %s [-n|-s|-b|-q] [-i input_file]\n",
+ program_name);
+ exit(1);
+ }
+
+ if(opt.stress+opt.base64+opt.normal+opt.qp == 0){
+ fprintf(stderr,
+ "%s: Must have one of n,s,b or q\n",
+ program_name);
+ }
+
+ if(opt.input_file){
+ f = fopen(opt.input_file,"r");
+ if (f == 0){
+ fprintf(stderr,"Could not open input file \"%s\"\n",
+ opt.input_file);
+ exit(1);
+ }
+ } else {
+ f = stdin;
+ }
+
+
+
+ if(opt.normal == 1){
+ icalcomponent *c;
+
+ c = icalmime_parse(read_stream,f);
+
+ printf("%s\n",icalcomponent_as_ical_string(c));
+
+ icalcomponent_free(c);
+
+ } else if (opt.stress==1 ){
+ /* Read file in by lines, then randomize the lines into a
+ string buffer */
+
+ char *array[1024];
+ char temp[1024];
+ char *buf;
+ int i,last;
+ int size = 0;
+ int non_rand;
+ int rand_lines;
+ int r;
+ int j;
+ icalcomponent *c;
+ struct slg_data {
+ char* pos;
+ char* str;
+ } d;
+
+ for(i=0; !feof(f); i++){
+ fgets(temp,1024,f);
+ array[i] = strdup(temp);
+ size += strlen(temp);
+ }
+ last = i;
+
+ buf = malloc(size*2);
+ assert(buf != 0);
+
+
+ for(j=0; j<opt.count; j++){
+
+ srand(j);
+ memset(buf,0,size*2);
+ /* First insert some non-randomized lines */
+ non_rand = ((float)rand()/(float)RAND_MAX) * last;
+ for(i=0;i<non_rand;i++){
+ strcat(buf,array[i]);
+ }
+
+ /* Then, insert some lines at random */
+
+ rand_lines = last - non_rand;
+
+ for(i=0;i<rand_lines;i++){
+ srand(i);
+ r = ((float)rand()/(float)RAND_MAX) * rand_lines;
+ strcat(buf,array[r+non_rand]);
+
+ }
+
+ d.pos = 0;
+ d.str = buf;
+
+ c = icalmime_parse(icalparser_string_line_generator,&d);
+
+ printf("%s\n",icalcomponent_as_ical_string(c));
+
+ icalcomponent_free(c);
+
+ }
+
+ free(buf);
+
+ for(i=0; i<last; i++){
+ free(array[i]);
+ }
+
+ } else if(opt.qp == 1){
+ char str[4096];
+ char conv[4096];
+
+ memset(str,0,4096);
+
+ while(!feof(f) && fgets(str,4096,f)!=0){
+ size_t size;
+
+ size = strlen(str);
+ memset(conv,0,4096);
+ decode_quoted_printable(conv,str,&size);
+
+ conv[size] = '\0';
+ printf("%s",conv);
+ memset(str,0,4096);
+
+ }
+ } else if (opt.base64 == 1) {
+ char str[4096];
+ char conv[4096];
+
+ memset(str,0,4096);
+
+ while(!feof(f) && fgets(str,4096,f)!=0){
+ size_t size;
+
+ size = strlen(str);
+ memset(conv,0,4096);
+ decode_base64(conv,str,&size);
+
+ conv[size] = '\0';
+ printf("%s",conv);
+ memset(str,0,4096);
+
+ }
+ }
+
+ if (opt.sleep != 0){
+#ifdef WIN32
+ _sleep(opt.sleep*1000);
+#else
+ sleep(opt.sleep);
+#endif
+ }
+
+ if( opt.input_file != 0){
+ free(opt.input_file);
+ }
+
+ icalmemory_free_ring();
+
+ return 0;
+
+}
+
+
+
+
+
+
+
+
diff --git a/src/test/testvcal.c b/src/test/testvcal.c
new file mode 100644
index 00000000..f9846748
--- /dev/null
+++ b/src/test/testvcal.c
@@ -0,0 +1,64 @@
+/* -*- Mode: C -*-
+ ======================================================================
+ FILE: vcal.c
+ CREATOR: eric 26 May 2000
+
+ $Id: testvcal.c,v 1.4 2008-01-02 20:07:46 dothebart Exp $
+ $Locker: $
+
+ (C) COPYRIGHT 2000 Eric Busboom
+ http://www.softwarestudio.org
+
+ The contents of this file are subject to the Mozilla Public License
+ Version 1.0 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and
+ limitations under the License.
+
+ The Original Code is eric. The Initial Developer of the Original
+ Code is Eric Busboom
+
+
+ ======================================================================*/
+
+#include <libicalvcal/icalvcal.h>
+#include <stdio.h>
+
+/* Given a vCal data file as its first argument, this program will
+ print out an equivalent iCal component.
+
+ For instance:
+
+ ./testvcal ../../test-data/user-cal.vcf
+
+*/
+
+int main(int argc, char* argv[])
+{
+ VObject *vcal = 0;
+ icalcomponent *comp;
+ char* file;
+
+ if (argc != 2){
+ file = "../../test-data/user-cal.vcf";
+ } else {
+ file = argv[1];
+ }
+
+
+ vcal = Parse_MIME_FromFileName(file);
+
+ assert(vcal != 0);
+
+ comp = icalvcal_convert(vcal);
+
+ printf("%s\n",icalcomponent_as_ical_string(comp));
+
+ return 0;
+}
+
+
diff --git a/src/test/timezones.c b/src/test/timezones.c
new file mode 100644
index 00000000..f55b33c0
--- /dev/null
+++ b/src/test/timezones.c
@@ -0,0 +1,165 @@
+/* -*- Mode: C -*-
+ ======================================================================
+
+ The contents of this file are subject to the Mozilla Public License
+ Version 1.0 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and
+ limitations under the License.
+
+ ======================================================================*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <libical/ical.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv)
+{
+ icalarray *timezones = icaltimezone_get_builtin_timezones();
+ int i;
+ int ret = 0;
+ unsigned int total_failed = 0;
+ unsigned int total_okay = 0;
+ unsigned int percent_failed = 0;
+ int verbose = 0;
+ icaltimezone *utc_zone = icaltimezone_get_utc_timezone();
+
+ /* for all known time zones... */
+ for (i = 0; i < timezones->num_elements; i++) {
+ icaltimezone *zone = icalarray_element_at(timezones, i);
+ const char *zone_location = icaltimezone_get_location(zone);
+ int day;
+ time_t start_time;
+ struct tm start_tm;
+ time_t curr_time;
+ struct tm curr_tm;
+ struct icaltimetype curr_tt;
+ int failed = 0;
+ int curr_failed;
+ int zonedef_printed = 0;
+
+ /*
+ * select this location for glibc: needs support for TZ=<location>
+ * which is not POSIX
+ */
+#if defined(HAVE_SETENV)
+ setenv("TZ", zone_location, 1);
+#else
+ static new_tz[256];
+ new_tz[0] = '\0';
+ strncat(new_tz, "TZ=", 255);
+ strncat(new_tz, zone_location, 255);
+ putenv(new_tz);
+#endif
+ tzset();
+
+ /*
+ * determine current local time and date: always use midday in
+ * the current zone and first day of first month in the year
+ */
+ start_time = time(NULL);
+ localtime_r(&start_time, &start_tm);
+ start_tm.tm_hour = 12;
+ start_tm.tm_min = 0;
+ start_tm.tm_sec = 0;
+ start_tm.tm_mday = 1;
+ start_tm.tm_mon = 0;
+ start_time = mktime(&start_tm);
+
+ /* check time conversion for the next 365 days */
+ for (day = 0, curr_time = start_time;
+ day < 365;
+ day++, curr_time += 24 * 60 * 60) {
+ /* determine date/time with glibc */
+ localtime_r(&curr_time, &curr_tm);
+ /* determine date/time with libical */
+ curr_tt = icaltime_from_timet_with_zone(curr_time, 0, utc_zone);
+ curr_tt.zone = utc_zone; /* workaround: icaltime_from_timet_with_zone() should do this, but doesn't! */
+ curr_tt = icaltime_convert_to_zone(curr_tt, zone);
+
+ /* compare... */
+ curr_failed =
+ curr_tm.tm_year + 1900 != curr_tt.year ||
+ curr_tm.tm_mon + 1 != curr_tt.month ||
+ curr_tm.tm_mday != curr_tt.day ||
+ curr_tm.tm_hour != curr_tt.hour ||
+ curr_tm.tm_min != curr_tt.minute ||
+ curr_tm.tm_sec != curr_tt.second;
+
+ /* only print first failed day and first day which is okay again */
+ if (verbose || curr_failed != failed) {
+ struct tm utc_tm;
+ gmtime_r(&curr_time, &utc_tm);
+ printf("%s: day %03d: %s: %04d-%02d-%02d %02d:%02d:%02d UTC = libc %04d-%02d-%02d %02d:%02d:%02d dst %d",
+ zone_location,
+ day,
+
+ verbose ?
+ (curr_failed ? "failed" : "okay") :
+ (curr_failed ? "first failed" : "okay again"),
+
+ utc_tm.tm_year + 1900,
+ utc_tm.tm_mon + 1,
+ utc_tm.tm_mday,
+ utc_tm.tm_hour,
+ utc_tm.tm_min,
+ utc_tm.tm_sec,
+
+ curr_tm.tm_year + 1900,
+ curr_tm.tm_mon + 1,
+ curr_tm.tm_mday,
+ curr_tm.tm_hour,
+ curr_tm.tm_min,
+ curr_tm.tm_sec,
+ curr_tm.tm_isdst);
+ if (curr_failed) {
+ printf(" != libical %04d-%02d-%02d %02d:%02d:%02d dst %d",
+ curr_tt.year,
+ curr_tt.month,
+ curr_tt.day,
+ curr_tt.hour,
+ curr_tt.minute,
+ curr_tt.second,
+ curr_tt.is_daylight);
+ ret = 1;
+ }
+ printf("\n");
+ failed = curr_failed;
+
+ if (!zonedef_printed) {
+ icalcomponent *comp = icaltimezone_get_component(zone);
+ if (comp) {
+ printf("%s\n", icalcomponent_as_ical_string(comp));
+ }
+ zonedef_printed = 1;
+ }
+ }
+
+ if (curr_failed) {
+ total_failed++;
+ } else {
+ total_okay++;
+ }
+ }
+ }
+
+ if (total_failed || total_okay) {
+ percent_failed = total_failed * 100 / (total_failed + total_okay);
+ printf(" *** Summary: %d zones tested, %u days failed, %u okay => %u%% failed ***\n",
+ timezones->num_elements,
+ total_failed,
+ total_okay,
+ percent_failed);
+ }
+
+ return ret;
+}