diff options
author | Allen Winter <allen.winter@kdab.com> | 2014-06-28 17:45:24 -0400 |
---|---|---|
committer | Allen Winter <allen.winter@kdab.com> | 2014-06-28 17:45:24 -0400 |
commit | 43858141030ba123a4959231cadc9951b983f0fd (patch) | |
tree | 8256c1dbf3ca7c9e58a3dbecf07cf826fb2e0ce2 /src/test | |
download | libical-git-1.0.0.tar.gz |
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/2445.ics | 326 | ||||
-rw-r--r-- | src/test/2446.ics | 0 | ||||
-rw-r--r-- | src/test/CMakeLists.txt | 103 | ||||
-rw-r--r-- | src/test/Makefile.am | 65 | ||||
-rw-r--r-- | src/test/Makefile.in | 823 | ||||
-rw-r--r-- | src/test/copycluster.c | 150 | ||||
-rw-r--r-- | src/test/findobj.c | 71 | ||||
-rw-r--r-- | src/test/icaltestparser.c | 122 | ||||
-rw-r--r-- | src/test/itip.ics | 14 | ||||
-rw-r--r-- | src/test/outgoing.ics | 544 | ||||
-rw-r--r-- | src/test/process.c | 416 | ||||
-rw-r--r-- | src/test/recur.c | 163 | ||||
-rw-r--r-- | src/test/recur.dsp | 102 | ||||
-rw-r--r-- | src/test/regression-classify.c | 193 | ||||
-rw-r--r-- | src/test/regression-component.c | 570 | ||||
-rw-r--r-- | src/test/regression-cxx.cpp | 137 | ||||
-rw-r--r-- | src/test/regression-recur.c | 199 | ||||
-rw-r--r-- | src/test/regression-storage.c | 808 | ||||
-rw-r--r-- | src/test/regression-utils.c | 180 | ||||
-rw-r--r-- | src/test/regression.c | 3907 | ||||
-rw-r--r-- | src/test/regression.dsp | 125 | ||||
-rw-r--r-- | src/test/regression.h | 55 | ||||
-rw-r--r-- | src/test/storage.c | 873 | ||||
-rw-r--r-- | src/test/stow.c | 895 | ||||
-rw-r--r-- | src/test/testclassify.c | 129 | ||||
-rw-r--r-- | src/test/testmime.c | 351 | ||||
-rw-r--r-- | src/test/testvcal.c | 64 | ||||
-rw-r--r-- | src/test/timezones.c | 165 |
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; +} |