From 25e1b34aafe43ba6cf1040340a38dd38a90aad33 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 18 Apr 2000 18:17:07 +0000 Subject: import of libical-0.16 svn path=/trunk/; revision=2484 --- libical/AUTHORS | 1 - libical/COPYING | 12 - libical/ChangeLog | 24 +- libical/INSTALL | 24 + libical/Makefile.am | 13 +- libical/NEWS | 251 ++++- libical/README | 22 +- libical/THANKS | 6 + libical/TODO | 6 +- libical/acconfig.h | 7 + libical/configure.in | 60 +- libical/design-data/.cvsignore | 1 + libical/design-data/Makefile.am | 10 + libical/design-data/components.txt | 1 + libical/design-data/prop-to-value.txt | 2 +- libical/design-data/status.txt | 88 +- libical/design-data/value-c-types.txt | 1 + libical/doc/.cvsignore | 1 + libical/doc/Makefile.am | 1 + libical/doc/UsingLibical.lyx | 1823 +++++++++++++++++++++++++++++--- libical/doc/UsingLibical.ps | 1308 +++++++++++++++++++++++ libical/missing | 190 ++++ libical/mkinstalldirs | 40 + libical/scripts/.cvsignore | 1 + libical/scripts/Makefile.am | 8 + libical/scripts/mkderivedcomponents.pl | 35 +- libical/scripts/mkderivedparameters.pl | 39 +- libical/src/Makefile.am | 2 +- libical/src/libical/.cvsignore | 3 + libical/src/libical/Makefile.am | 116 +- libical/src/libical/ical.h | 2 +- libical/src/libical/icalcomponent.c | 88 +- libical/src/libical/icalcomponent.h | 4 + libical/src/libical/icalenums.c | 76 +- libical/src/libical/icalenums.h | 15 +- libical/src/libical/icalerror.c | 14 + libical/src/libical/icalerror.h | 2 + libical/src/libical/icallexer.l | 282 +++++ libical/src/libical/icalmemory.c | 7 +- libical/src/libical/icalparameter.c | 90 +- libical/src/libical/icalparser.c | 963 +++++++++-------- libical/src/libical/icalparser.h | 47 +- libical/src/libical/icalproperty.c | 29 +- libical/src/libical/icalrestriction.c | 14 +- libical/src/libical/icaltypes.c | 86 ++ libical/src/libical/icaltypes.h | 20 +- libical/src/libical/icalvalue.c | 192 ++-- libical/src/libical/icalvalue.h | 5 + libical/src/libical/icalversion.h | 3 + libical/src/libical/icalversion.h.in | 3 + libical/src/libical/icalyacc.y | 480 +++++++++ libical/src/libical/pvl.c | 4 + libical/src/libicalss/Makefile.am | 32 +- libical/src/libicalss/icalcalendar.c | 5 + libical/src/libicalss/icalcluster.c | 323 +++--- libical/src/libicalss/icalcluster.h | 4 +- libical/src/libicalss/icalstore.c | 361 ++++--- libical/src/test/Makefile.am | 12 + libical/src/test/Makefile.in | 324 +++++- libical/src/test/icaltestparser.c | 123 ++- libical/src/test/regression.c | 232 ++-- libical/src/test/storage.c | 460 ++++++++ libical/src/test/usecases.c | 46 +- libical/test-data/.cvsignore | 1 + libical/test-data/2445.ics | 329 ++++++ libical/test-data/2446.ics | 1007 ++++++++++++++++++ libical/test-data/Makefile.am | 13 + libical/test-data/smallcluster.ics | 18 + 68 files changed, 8361 insertions(+), 1451 deletions(-) create mode 100644 libical/INSTALL create mode 100644 libical/THANKS create mode 100644 libical/acconfig.h create mode 100644 libical/design-data/.cvsignore create mode 100644 libical/design-data/Makefile.am create mode 100644 libical/doc/.cvsignore create mode 100644 libical/doc/Makefile.am create mode 100644 libical/doc/UsingLibical.ps create mode 100755 libical/missing create mode 100644 libical/mkinstalldirs create mode 100644 libical/scripts/.cvsignore create mode 100644 libical/scripts/Makefile.am create mode 100644 libical/src/libical/icallexer.l create mode 100644 libical/src/libical/icalversion.h create mode 100644 libical/src/libical/icalversion.h.in create mode 100644 libical/src/libical/icalyacc.y create mode 100644 libical/src/test/Makefile.am create mode 100644 libical/src/test/storage.c create mode 100644 libical/test-data/.cvsignore create mode 100644 libical/test-data/2445.ics create mode 100644 libical/test-data/2446.ics create mode 100644 libical/test-data/Makefile.am create mode 100644 libical/test-data/smallcluster.ics diff --git a/libical/AUTHORS b/libical/AUTHORS index 63a721db14..e69de29bb2 100644 --- a/libical/AUTHORS +++ b/libical/AUTHORS @@ -1 +0,0 @@ -Eric Busboom diff --git a/libical/COPYING b/libical/COPYING index 70f1116cbc..e69de29bb2 100644 --- a/libical/COPYING +++ b/libical/COPYING @@ -1,12 +0,0 @@ -(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. diff --git a/libical/ChangeLog b/libical/ChangeLog index 683a112752..4b226ac5a6 100644 --- a/libical/ChangeLog +++ b/libical/ChangeLog @@ -1,18 +1,20 @@ -2000-04-10 Damon Chaplin +2000-03-17 Eric Busboom - * configure.in: added AC_PROG_MAKE_SET. + * icalstore.c Vastly improved icalstore_test. -2000-03-01 Ettore Perazzoli +2000-03-16 Eric Busboom - * src/libicalss/Makefile.am (INCLUDES): Include from - `$(top_srcdir)/src/libical'. + * icalcluster.c Added compile flag (ICAL_SAFESAVES) to switch how + icalcluster saves files during commits. When the flag is define, + it will write the data to a temorar file and rename the file to + the target file. -2000-02-26 Seth Alves + * storage.c Added seterate test suite for sotage components - * src/libical/icalitipy.y: renamed icalitip.y so automake bung is easy + * icalparser.c Created parser object, implemented line-oriented + parsering, and made message oriented parsing work in terms f line + oriented parsing. - * src/libical/icalitipl.l: renamed icalitip.l so automake bung is easy + * icalparser.c Fixed icalparser_get_line to remove \r in input. + - * src/libical/Makefile.am: added icalparser_yy to the start - of all the yacc/lex names to avoid namespace conflicts. - note that this forces the build to use bison/flex diff --git a/libical/INSTALL b/libical/INSTALL new file mode 100644 index 0000000000..88e2a5e7d6 --- /dev/null +++ b/libical/INSTALL @@ -0,0 +1,24 @@ +Building the library +-------------------- + +This distribution is developed on Red Hat Linux 6.0 and usually +compiles on SunOS 5.6 and FreeBSD 2.27. I have reports of success of +previous version on MacOS ( with CodeWarrior ) but I don't know about +any other systems. + +The library is configured with automake. From the root directory, run + + ./configure + +To build all of the Makefiles for your system. If you will be installing the library, you may want to use the --prefix flag to set the directory where the library and header files will be installed. + + ./configure --prefix=/proj/local/ + +If configure runs fine, run "make" to build the library and +"make install" to install it. + +The current version of libical focuses on creating and +manipulating iCal objects. With it, you can parse text representations +of iCal components, add and remove sub-components, properties, +parameters and values, and print the components back out as strings. + diff --git a/libical/Makefile.am b/libical/Makefile.am index 9cca9b6582..66b37da052 100644 --- a/libical/Makefile.am +++ b/libical/Makefile.am @@ -1,8 +1,11 @@ -EXTRA_DIST = \ - CHANGES \ - README \ - TEST \ + +EXTRA_DIST = \ + ChangeLog \ + README \ + TEST \ TODO -SUBDIRS = src +SUBDIRS = design-data doc scripts test-data src + + diff --git a/libical/NEWS b/libical/NEWS index 45b983be36..d5fd9cb9cf 100644 --- a/libical/NEWS +++ b/libical/NEWS @@ -1 +1,250 @@ -hi +Version 0.16 5 April 00 ( cvs tag libical-0-16) +---------------------------------------------- + +Now using automake. + +Substantial changes to the parser. New interfaces let you parser +multiple components from a single stream by feading the parser object +one line at a time. + +Added a STRING value type. this type is like TEXT, but does not +backslash magic characters. It is used in PRODID and REQUEST-STATUS, +where the '/' and ';' are literal. + +Added several convience functions for REQUEST-STATUS to icalenums.c + +Addedd a routine to icalcomponent to convert X-LIC errors to +REQUEST-STATUS return values. + +Version 0.15a 5 Mar 00 (cvs tag libical-0-15a) +--------------------- + +Experimented with CVS + +Fixed icalvalue_set_text to convert escaped characters into the proper +values. + +Other minor code tweaks. + + +Version 0.15 7 Feb 00 +--------------------- + +Split the storage classess ( icalstore, icalcluster, icalcalendar ) +into a seperate library, libicalss + +Implemented restriction checking in file icalrestrictions.c. The +checking is not complete, but can handle the bulk of the restrictions +described in RFC 2446. + +Created a new value type, METHOD. Changed METHOD property to use the +new value. The METHOD value uses an enumeration. + + +Version 0.14b +------------- + +Implemented parsing of RECUR values, although it does not handle BYDAY +specs with numbers. + +Fixed error in icalparser_next_line that mangled lines longer than the +temp buffer (1024 chars.) The temp buffer is now 80 chars, and it can +handle (apparently) arbitrary length lines + +Fixed severe brokenness in a value, but I forgot which one. + +Cleaned cruft out of the distribution, so the tarfile is smaller. + + +Version 0.14a 14 Jan 00 +----------------------- + +Fixed bug in ROLE parameter -- missing '-' in the text of allowed values + +Fixed bug in X-parameters + +Version 0.14 11 Jan 00 +---------------------- + +Fixed wrong value type for TRIGGER property + +Added Calendar object. Calendar is an aggregate of two stores and two +clusters, and can store all of the inforamation associated with a +calendar. + +icalcomponent_add_property and icalcomponent_add_component will +complain if you try to add a component or property that is already +part of an other component. The *_free routines wil complain if you try +to free a linked component or property. + +More improvements to error handling. + +Parser is much more robust. + +Minor memory enhancements. + +Regression test runs without memory leaks. + +Version 0.13d 21Dec99 +--------------------- + +Seperated perl interface and library + +Added autoconf support + +Scripts that generate derived properties, values and parameters now +change source and header files inline. + +Changed icalstore to cluster all components with DTSTART in a month +into a single file. This should reduce number of file accesses by a +factor of 60. + +Ran code through Purify and fixed memory leaks. + + +Version 0.13 16Nov99 +--------------------- + +Yet more bug fixes! Yeah! + +Added better error handling. The Parser inserts X-LIC-*ERROR +properties to warn of parsing errors. + +The imip source/sink programs in /src/imip is demonstrably functional. + +Version 0.12b 17Oct99 +--------------------- + +More bug fixes, particularily in parse from string routines + +ICal::Store is mostly functional + +This is version is a checkpoint, not a release. + +Version 0.12a 10Oct99 +--------------------- + +Expanded perl interface: + Added 1/2 of Store module + Fixed bugs + Implemeted get_{first,next}_property + +Extended C interface + Made get_{first,next}_property work properly + Fixed bugs + + +This is version is a checkpoint, not a release. + +Version 0.12 27Aug99 +-------------------- + +Added a rudimentatry perl interface + +This is version is a checkpoint, not a release. + + +Version 0.11 11Aug99 +-------------------- + +Eliminated most use of flex/bison -- all parsing, except for the +values, is done in C. + +Cleaned up memory leaks. Purify claims that I got them all. + +Moved all derived component/prop/param/value code ( in .inc / .h +files) into main files ( icalcomponent.{c,h}, icalproperty.{c,h}, etc/ +) + +Implemented *_clone routines. + +Fixed a lot of bugs. + +Implemented more value types. Still unimplemeneted are BINARY and RECUR + +Included MacOS/Code Warior files from Graham Davison + + +Version 0.10 8Jul99 +------------------- + +Eliminated shift/reduce and reduce/reduce conflicts in the parser. +This version is almost feature complete -- it has the basic structure +for all of the library's functionality, and it will only require +implementing procedure shells and fixing bugs. I think that all of the +hard work is done... + +Version 0.09a,b 3,7 Jul99 +------------------------- + +Various improvements to the parser, added some functionality. The parser code +is mostly complete, and should be fully functional, except for a horde of +bugs. Also added support for X-Properties. + +Version 0.09 25Jun99 +-------------------- + +Added a parser in files src/comp/icalitip.{y,l} The lexer is mostly +functional, but the parser is not. + + +Version 0.08 2Jun99 +-------------------- + +All files now have MPL licensing + +Implement enough of the code to perform some rudimentary testing + + +Version 0.07 14May99 +-------------------- + +Remove all interfaces that construct object from a string + +Moved most code back into comp directory + +Implemented C files for most headers -- usecases.c now links. + +Many improvements to generation scripts. + + + +Version 0.06 25Apr99 +-------------------- + +Expanded distribution to include: + Directory structure that can accomodate future expansion + Several levels of Makefiles + This CHANGES file + +Added headers for irip and parse modules + +Added several files with design information + +Added scripts that I had used to generate much of the ical header code. + +Split C headers from CC headers + +Added data for iTIP and iCAL component restrictions in restrictions.csv + +Version 0.05 11Apr99 +---------------------- + +Changes to ical headers + + Added derived Property classes. + + Improved the interface to the derived property and parameter classes + + Added derived component classes. + + Created usecases.c and ccusecases.cc to demonstrate use + + C++ interface compile + + +Version 0.04 5Apr99 +------------------- + +Version 0.02 30Mar99 +-------------------- diff --git a/libical/README b/libical/README index 66c78995e1..e0f7641e1e 100644 --- a/libical/README +++ b/libical/README @@ -55,10 +55,28 @@ manipulating iCal objects. With it, you can parse text representations of iCal components, add and remove sub-components, properties, parameters and values, and print the components back out as strings. + +Notes for Libical Developers +------------------- + +If you don't want to use gcc as the compiler, and you got the sources +from CVS, you should set the CC variable to the path to the compiler +and run "automake --include-deps" to keep automake from using +gcc-specific automatic dependancy tracking. + + > CC=/pkg/SUNWspro/bin/cc; export CC + > automake --include-deps + > ./configure --prefix=/proj/local/ + > make + +You will not need to re-run automake unless you got the sources from CVS. + + Perl Library ------------ -There is a perl language binding of this library, LIBICAL. It is available from CPAN. or from http://www.softwarestudio.org/libical +There is a perl language binding of this library, LIBICAL. +It is available from http://www.softwarestudio.org/libical Parser ------ @@ -75,4 +93,4 @@ executable. For example, from the root of the distribution: Eric Busboom -eric@softwarestudio.org \ No newline at end of file +eric@softwarestudio.org diff --git a/libical/THANKS b/libical/THANKS new file mode 100644 index 0000000000..4130c35e23 --- /dev/null +++ b/libical/THANKS @@ -0,0 +1,6 @@ +Thanks to: + + +Graham Davison for MacOS support and miscelaneous code bits + +Seth Alves for the first cut at the Makefile.am files \ No newline at end of file diff --git a/libical/TODO b/libical/TODO index feb723d244..c5c85f6753 100644 --- a/libical/TODO +++ b/libical/TODO @@ -24,9 +24,5 @@ Error Handling RECUR values ignore integers in BYDAY clauses, ie 'FREQ=MONTHLY;BYDAY=-1SU' -REQUEST-STATUS propery is broken. The parser treats the value as -normal text, backslashing the ';' seperators. +Restrictions code does not catch lack of DTEND or DURATION -Some of the X-LIC-ERROR types overlap with REQUEST-STATUS -values. There should be a routine to turn property, parameter and -value parse errors into REQUEST-STATUS diff --git a/libical/acconfig.h b/libical/acconfig.h new file mode 100644 index 0000000000..e9383f73a4 --- /dev/null +++ b/libical/acconfig.h @@ -0,0 +1,7 @@ +/* Define to make icalerror_* calls abort instead of internally + signalling an error */ +#undef ICAL_ERRORS_ARE_FATAL + +/* Define to make icalcluster_commit() save to a temp file and mv to + the original file instead of writing to the orig file directly */ +#undef ICAL_SAFESAVES diff --git a/libical/configure.in b/libical/configure.in index 54e05e4ba4..fa4d090949 100644 --- a/libical/configure.in +++ b/libical/configure.in @@ -1,28 +1,48 @@ dnl Process this file with autoconf to produce a configure script. -AC_PREREQ(2.2) AC_INIT(src/libical/ical.h) AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE(libical,0.15a) +AM_INIT_AUTOMAKE(libical,0.16) dnl Checks for programs. -AC_PROG_CC -AC_STDC_HEADERS AC_PROG_YACC +AC_PROG_CC AM_PROG_LEX -AM_PROG_LIBTOOL +AC_PROG_LN_S +AC_PROG_RANLIB AC_PROG_INSTALL -AC_PROG_CPP -AC_PROG_MAKE_SET -AC_PATH_PROG(RM, rm, /bin/rm) -AC_PATH_PROG(MV, mv, /bin/mv) -AC_PATH_PROG(TAR, tar, /bin/tar) - -AC_SUBST(CFLAGS) -AC_SUBST(CPPFLAGS) -AC_SUBST(LDFLAGS) - -AC_OUTPUT([ -Makefile -src/Makefile -src/libical/Makefile -src/libicalss/Makefile]) + +AC_SUBST(AR) +AC_CHECK_PROGS(AR, ar aal, ar) + +AC_DEFINE(ICAL_ERRORS_ARE_FATAL,1) +AC_DEFINE(ICAL_SAFESAVES,1) + +dnl Checks for libraries. +dnl Replace `main' with a function in -lical: +dnl AC_CHECK_LIB(ical, main) + +dnl Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS(time.h sys/types.h assert.h) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_TYPE_SIZE_T +AC_STRUCT_TM + +dnl Checks for library functions. +AC_CHECK_FUNCS(strdup) + +AC_OUTPUT(\ +src/libical/icalversion.h \ +config.h \ +src/libical/Makefile \ +src/libicalss/Makefile \ +src/test/Makefile \ +src/Makefile \ +design-data/Makefile \ +doc/Makefile \ +scripts/Makefile \ +test-data/Makefile \ +src/Makefile \ +Makefile ) diff --git a/libical/design-data/.cvsignore b/libical/design-data/.cvsignore new file mode 100644 index 0000000000..70845e08eb --- /dev/null +++ b/libical/design-data/.cvsignore @@ -0,0 +1 @@ +Makefile.in diff --git a/libical/design-data/Makefile.am b/libical/design-data/Makefile.am new file mode 100644 index 0000000000..0548974160 --- /dev/null +++ b/libical/design-data/Makefile.am @@ -0,0 +1,10 @@ +EXTRA_DIST =\ + components.txt \ + param-c-types.txt \ + params-in-prop.txt \ + prop-to-value.txt \ + property-tokens.txt \ + restrictions.csv \ + status.txt \ + value-c-types.txt \ + value-mem-semantics.txt \ diff --git a/libical/design-data/components.txt b/libical/design-data/components.txt index 709c74ce13..15417eaf2f 100644 --- a/libical/design-data/components.txt +++ b/libical/design-data/components.txt @@ -17,4 +17,5 @@ VQUERY VCAR VCOMMAND XLICINVALID +ANY diff --git a/libical/design-data/prop-to-value.txt b/libical/design-data/prop-to-value.txt index 58a40c26cb..017c944983 100644 --- a/libical/design-data/prop-to-value.txt +++ b/libical/design-data/prop-to-value.txt @@ -36,7 +36,7 @@ LAST-MODIFIED DATE-TIME SEQUENCE INTEGER X-LIC-ERROR TEXT X-LIC-CLUSTERCOUNT INTEGER -REQUEST-STATUS TEXT +REQUEST-STATUS STRING ATTACH ATTACH # Non-std: URI or BINARY GEO GEO # Non-std: Two FLOATS DTEND DATE-TIME-DATE # Non-std: DATE-TIME or DATE diff --git a/libical/design-data/status.txt b/libical/design-data/status.txt index d3f2f1864d..9e7bbf83a7 100644 --- a/libical/design-data/status.txt +++ b/libical/design-data/status.txt @@ -1,32 +1,56 @@ -2.0 Success. -2.1 Success but fallback taken on one or more property values. -2.2 Success, invalid property ignored. -2.3 Success, invalid property parameter ignored. -2.4 Success, unknown non-standard property ignored. -2.5 Success, unknown non-standard property value ignored. -2.6 Success, invalid calendar component ignored. -2.7 Success, request forwarded to Calendar User. -2.8 Success, repeating event ignored. Scheduled as a single component. -2.9 Success, truncated end date time to date boundary. -2.10 Success, repeating VTODO ignored. Scheduled as a single VTODO. -2.11 Success, unbounded RRULE clipped at some finite number of instances -3.0 Invalid property name. -3.1 Invalid property value. -3.2 Invalid property parameter. -3.3 Invalid property parameter value. -3.4 Invalid calendar component sequence. -3.5 Invalid date or time. -3.6 Invalid rule. -3.7 Invalid Calendar User. -3.8 No authority. -3.9 Unsupported version. -3.10 Request entity too large. -3.11 Required component or property missing. -3.12 Unknown component or property found -3.13 Unsupported component or property found -3.14 Unsupported capability -4.0 Event conflict. Date/time is busy. -5.0 Request MAY supported. -5.1 Service unavailable. -5.2 Invalid calendar service. -5.3 No scheduling support for user. +2.0 STATOK Operation was successfully performed. +2.0.1 STARTSENDATA Start ICAL input; end with . +2.0.11 OKDATAFOLLOWS The request was processed successfully. Reply data follows on the next line and terminates with . +2.0.2 REPLYPENDING A timeout has occurred. The server is still working on the reply. Use CONTINUE to continue waiting for the reply or ABORT to terminate the command. +2.0.3 ABORTED The command currently underway was successsfully aborted. +2.0.4 WILLATTEMPT The specified Calendar is not here but an attempt will be made to deliver the request or reply to the Calendar anyway. +2.0.5 TRUSTEDWILLQUEUE The request or reply will be queued and delivered to the target calendar when its iRIP server contacts this server and issues the SWITCH command. +2.0.6 WILLATTEMPT The specified Calendar is not here but an attempt will be made to deliver the request or reply to the Calendar anyway. +2.0.7 QUEUED The message has been queued for delivery. +2.0.8 QUEUEEMPTY There are no more queued messages. +2.1 FALLBACK Success. Fallback taken on one or more property values. +2.2 NOCOMMANDINPROGRESS An ABORT or CONTINUE was received when no command was in progress +2.2 IGPROP Success. Invalid property ignored. +2.3 IGPARAM Success. invalid property parameter ignored. +2.4 IGXPROP Success. Unknown non-standard property ignored. +2.5 IGXPARAM Success. Unknown non standard property value ignored. +2.6 IGCOMP Success. Invalid calendar component ignored. +2.7 FORWARD Success. Request forwarded to Calendar User. +2.8 ONEEVENT Success. Repeating event ignored. Scheduled as a single component. +2.9 TRUNC Success. Truncated end date time to date boundary. +2.10 ONETODO Success. Repeating VTODO ignored. Scheduled as a single VTODO. +2.11 TRUNCRRULE Success. Unbounded RRULE clipped at some finite number of instances +3.0 INVPROPNAME Invalid property name. +3.1 INVPROPVAL Invalid property value. +3.2 INVPARAM Invalid property parameter. +3.3 INVPARAMVAL Invalid property parameter value. +3.4 INVCOMP Invalid calendar component sequence. +3.5 INVTIME Invalid date or time. +3.6 INVRULE Invalid rule. +3.7 INVCU Invalid Calendar User. +3.8 NOAUTH No authority. +3.9 BADVERSION Unsupported version. +3.10 TOOBIG Request entity too large. +3.11 MISSREQCOMP Required component or property missing. +3.12 UNKCOMP Unknown component or property found. +3.13 BADCOMP Unsupported component or property found +3.14 NOCAP Unsupported capability. +4.0 BUSY Event conflict. Date/time is busy. +5.0 MAYBE Request MAY supported. +5.1 UNAVAIL Service unavailable. +5.2 NOSERVICE Invalid calendar service. +5.3 NOSCHED No scheduling support for user. +6.1 AUTHENTICATEFAILURE Unsupported authentication mechanism, credentials rejected +6.2 AUTHENTICATIONABORTED Sender aborted authentication, authentication exchange cancelled +8.0 GENERALFAILURE A failure has occurred in the Receiver that prevents the operation from succeeding. +8.1 SERVERTOOBUSY The iRIP Receiver is too busy. +8.2 ICALOBJECTTOOBIG Object has exceeded the server's size limit. +8.3 DATETOOLARGE A DATETIME value was too far in the future to be represented on this Calendar. +8.4 DATETOOSMALL A DATETIME value was too far in the past to be represented on this Calendar. +9.0 INVALIDIRIPCOMMAND An unrecongnized command was received. +9.1 UNEXPECTEDCOMMAND The command is not allowed for the server's current state. +10.1 REFERRAL Accompanied by an alternate address. +10.2 SERVERSHUTDOWN The server is shutting down. +10.3 SERVERSTOPPING FLOOD 2 +10.4 EXCEEDEDQUOTAS The operation would cause a resource to exceed the allocated quota +10.5 QUEUEDTOOLONG The ITIP message has been queued too long. Delivery has been aborted. diff --git a/libical/design-data/value-c-types.txt b/libical/design-data/value-c-types.txt index 0bc8c9a7a0..c7dd26034f 100644 --- a/libical/design-data/value-c-types.txt +++ b/libical/design-data/value-c-types.txt @@ -13,6 +13,7 @@ INTEGER int METHOD icalproperty_method # Non-std PERIOD struct icalperiodtype RECUR struct icalrecurrencetype +STRING char* # Non-std TEXT char* TIME struct icaltimetype TRIGGER union icaltriggertype # Non-std diff --git a/libical/doc/.cvsignore b/libical/doc/.cvsignore new file mode 100644 index 0000000000..70845e08eb --- /dev/null +++ b/libical/doc/.cvsignore @@ -0,0 +1 @@ +Makefile.in diff --git a/libical/doc/Makefile.am b/libical/doc/Makefile.am new file mode 100644 index 0000000000..0df4f3f42d --- /dev/null +++ b/libical/doc/Makefile.am @@ -0,0 +1 @@ +EXTRA_DIST = UsingLibical.lyx UsingLibical.ps diff --git a/libical/doc/UsingLibical.lyx b/libical/doc/UsingLibical.lyx index 20eaffd288..b55cbb5909 100644 --- a/libical/doc/UsingLibical.lyx +++ b/libical/doc/UsingLibical.lyx @@ -1,4 +1,4 @@ -#This file was created by Mon Feb 7 20:19:42 2000 +#This file was created by Sat Feb 19 10:33:21 2000 #LyX 1.0 (C) 1995-1999 Matthias Ettrich and the LyX Team \lyxformat 2.15 \textclass linuxdoc @@ -47,13 +47,13 @@ Libical is an Open Source implementation of the iCalendar protocols and Libical implements the following specifications and protocols \layout Standard -\added_space_top 0.3cm \added_space_bottom 0.3cm \align center \LyXTable +\added_space_top 0.3cm \added_space_bottom 0.3cm \LyXTable multicol5 5 2 0 0 -1 -1 -1 -1 -1 1 0 0 -1 1 0 0 -1 1 0 0 -1 1 0 0 +1 0 0 0 +1 0 0 0 +1 0 0 0 +1 0 0 0 1 1 0 0 8 1 0 "" "" 8 1 1 "" "" @@ -89,12 +89,16 @@ CAP draft \layout Standard -(The current version, 0.14, does not implement iRip or CAP. +(The current version, 0.15, does not implement iRip or CAP. ) \layout Standard This documentation assumes that you are familiar with the iCalendar standards RFC2445 and RFC2446. + these specifications are online on the CALSCH webpage at: +\layout Verbatim + +http://www.imc.org/ietf-calendar/ \layout Subsection The libical project @@ -104,16 +108,16 @@ This code is under active development. If you would like to contribute to the project, you can contact me, Eric Busboom, at eric@softwarestudio.org. The project has a webpage at -\layout Quote +\layout Verbatim http://softwarestudio.org/libical/index.html \layout Standard and a mailing list that you can join by sending the following mail: -\layout Code +\layout Verbatim To: minimalist@softwarestudio.org -\layout Code +\layout Verbatim Subject: subscribe libical \layout Subsection @@ -140,12 +144,18 @@ Purpose & Goals \layout Subsection Document version -\layout Standard +\layout Verbatim -$Id: UsingLibical.lyx,v 1.1 2000/02/17 18:02:36 alves Exp $ +$Id: UsingLibical.lyx,v 1.2 2000/04/18 18:17:03 alves Exp $ \layout Section Building the Library +\layout Standard + +Libical uses autoconf to generate makefiles, although it uses none of the + autoconf flags to influence the compilation. + It should built with no adjustments on Linux, FreeBSD and Solaris. + \layout Section Structure @@ -160,7 +170,7 @@ Properties are the fundamental unit of information in iCal, and they work a bit like a hash entry, with a constant key and a variable value. Properties may also have modifiers, called parameters. In the iCal content line -\layout Code +\layout Verbatim ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com \layout Standard @@ -201,34 +211,114 @@ Components are groups of properties that represent the core objects of a The central goal of libical is to parse iTIP data into an internal representatio n of Components, Properties, Parameters an Values, and to allow the user - to manipulate the data in various ways + to manipulate the data in various ways +\layout Standard +\added_space_bottom 0.3cm +\begin_float fig +\layout Standard + + +\begin_inset Figure size 180 147 +file icaluml.eps +flags 13 + +\end_inset + + +\end_float +When a component is send across a network, if it is un-encrypted, it will + look something like: +\layout Code + +BEGIN:VEVENT +\layout Code + +DTSTAMP:19980309T231000Z +\layout Code + +UID:guid-1.host1.com +\layout Code + +ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com +\layout Code + +ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP: +\layout Code + + +\protected_separator + MAILTO:employee-A@host.com +\layout Code + +DESCRIPTION:Project XYZ Review Meeting +\layout Code + +CATEGORIES:MEETING +\layout Code + +CLASS:PUBLIC +\layout Code + +CREATED:19980309T130000Z +\layout Code + +SUMMARY:XYZ Project Review +\layout Code + +DTSTART;TZID=US-Eastern:19980312T083000 +\layout Code + +DTEND;TZID=US-Eastern:19980312T093000 +\layout Code + +LOCATION:1CP Conference Room 4350 +\layout Code + +END:VEVENT \layout Subsection +Core iCal classes +\layout Subsubsection + Components -\layout Subsection +\layout Subsubsection Properties -\layout Subsection +\layout Subsubsection Values -\layout Subsection +\layout Subsubsection Parameters \layout Subsection +Other elements of libical +\layout Standard + +In addition to the core iCal classes, libical has many other types, structures, + classes that aid in creating and using iCal components. + +\layout Subsubsection + Enumerations -\layout Subsection +\layout Subsubsection Types -\layout Subsection +\layout Subsubsection The Parser -\layout Subsection +\layout Subsubsection Restrictions -\layout Subsection +\layout Subsubsection + +Error objects +\layout Subsubsection Memory Management +\layout Subsubsection + +Storage classes \layout Section Differences From RFCs @@ -250,7 +340,8 @@ Libical defines components for groups of properties that look and act like components, but are not defined as components in the specification. XDAYLIGHT and XSTANDARD are notable examples. These pseudo components group properties within the VTIMEZONE components. - XDAYLIGHT starts with + For instanace, the timezone properties associated with daylight savings + time starts with \begin_inset Quotes eld \end_inset @@ -264,8 +355,25 @@ BEGIN:DAYLIGHT END:DAYLIGHT, just like other components, but is not defined as a component in RFC2445. - ( See RFC2445, page 61 ) In Libical, it is a component. - + ( See RFC2445, page 61 ) In Libical,this grouping is represented by the + XDAYLIGHT component. + Standard iCAL components all start with the letter +\begin_inset Quotes eld +\end_inset + +V, +\begin_inset Quotes erd +\end_inset + + while pseudo components start with +\begin_inset Quotes erd +\end_inset + +X. +\begin_inset Quotes erd +\end_inset + + \layout Standard There are also pseudo components that are conceptually derived classess @@ -346,16 +454,16 @@ S property can have multiple value instances. In libical, all properties have a single value, and multi-valued properties are broken down into multiple single valued properties during parsing. That is, an input line like, -\layout Code +\layout Verbatim CATEGORIES: work, home \layout Standard becomes in libical's internal representation -\layout Code +\layout Verbatim CATEGORIES: work -\layout Code +\layout Verbatim CATEGORIES: home \layout Standard @@ -392,186 +500,1615 @@ Using constructor interfaces, you create each of the objects seperately and them assemble them in to components: \layout Code +icalcomponent *event; +\layout Code + +icalproperty *prop; +\layout Code + +icalparameter *param; +\layout Code + +struct icaltimetype atime; +\layout Code + event = icalcomponent_new(ICAL_VEVENT_COMPONENT); \layout Code -icalcomponent_add_property(event, icalproperty_new_dtstamp(atime) ); +prop = icalproperty_new_dtstamp(atime) ; \layout Code -icalcomponent_add_property(event,icalproperty_new_uid(strdup("guid-1.host1.com")) - ); +icalcomponent_add_property(event, prop); \layout Code -property=icalproperty_new_organizer(strdup("mrbig@host.com")); +prop = icalproperty_new_uid(strdup("guid-1.host1.com")) ); \layout Code -icalproperty_add_parameter(property,icalparameter_new_role(ICAL_ROLE_CHAIR) - ); +icalcomponent_add_property(event,prop); \layout Code -icalcomponent_add_property(event,property); -\layout Subsubsection +prop=icalproperty_new_organizer(strdup("mrbig@host.com")); +\layout Code -vaargs Constructors -\layout Subsubsection +param = icalparameter_new_role(ICAL_ROLE_CHAIR) +\layout Code -Parsing Text Files -\layout Subsection +icalproperty_add_parameter(prop, param); +\layout Code -Accessing Components -\layout Subsubsection +icalcomponent_add_property(event,prop); +\layout Standard -Finding Components -\layout Subsubsection +While we are on this example, you should notice that libical uses a semi-object- +oriented style of interface. + Most things you work with are objects, that are instantiated with a constructor + that has +\begin_inset Quotes eld +\end_inset -Removing Components +new +\begin_inset Quotes erd +\end_inset + + in the name. + Also note that, other than the object reference, most structure data is + passed in to libical routines by value. + Strings, of course, are passed in by reference, but libical will take ownership + of the memory, so you had beter strdup() the data unless you want a core + dump when the memory is freed for the second time. + Libical has some complex bu very regular memory handling rules. + These are detailed in section +\begin_inset LatexCommand \ref{sec:memory} + +\end_inset + +. \layout Standard -Removing an element from a list while iterating through the list can cause - problems, since you will probably be removing the element that the internal - iterator points to. - This will result in the iteration loop terminating immediately after removing - the element. - To avoid the problem, you will need to step the iterator ahead of the element - you are going to remove, like this: -\layout Code +If any of the constructors fail, they will return 0. + If you try to insert 0 into a property or component, or use a zero-valued + object reference, libical will either silently ignore the error or will + abort with an error message. + This behavior is controlled by a compile time flag (ICAL_ERRORS_ARE_FATAL), + and will abort by default. + +\layout Subsubsection -for(c = icalcomponent_get_first_component(parent_comp,ICAL_ANY_COMPONENT); +vaargs Constructors +\layout Standard + +There is another way to create complex components, which is arguable more + elegant, if you are not horrified by vaargs. + The vaargs constructor interface all you to create intricate components + in a single block of text. \layout Code \protected_separator - -\protected_separator - + \protected_separator - + \protected_separator -c != 0; + calendar = \layout Code \protected_separator - + \protected_separator - + \protected_separator - + \protected_separator -c = next -\layout Code -{ -\layout Code +\protected_separator +\protected_separator \protected_separator - + \protected_separator - next = icalcomponent_get_next_component(parent_comp,ICAL_ANY_COMPONENT); +icalcomponent_vanew( \layout Code \protected_separator - + \protected_separator - icalcomponent_remove_component(parent_comp,c); -\layout Code -} -\layout Subsubsection +\protected_separator -Finding Properties -\layout Subsubsection +\protected_separator -Removing Properties -\layout Subsubsection +\protected_separator -Getting Values -\layout Subsubsection +\protected_separator -Setting Values -\layout Subsubsection +\protected_separator -Getting Parameters -\layout Subsubsection +\protected_separator -Setting Parameters -\layout Subsubsection +\protected_separator -Removing Parameters -\layout Subsubsection +\protected_separator -Checking Component Validity -\layout Subsection +\protected_separator + ICAL_VCALENDAR_COMPONENT, +\layout Code -Storing Objects -\layout Standard -The libical distribution inclues a seperate library, libicalss, that allows - you to store iCal component data to disk in a variety of ways. - This library is documented seperately. - -\layout Subsection +\protected_separator -Memory Management -\layout Standard +\protected_separator -Libical relies heavily on dynamic allocation for both the core objects and - for the strings used to hold values. - Some of this memory the library caller owns and must free, and some of - the memory is managed by the library. - Here is a summary of the memory rules. - -\layout Description +\protected_separator -1) If the function name has "new" in it, the caller gets control of the - memory. - ( such as icalcomponent_new(), or icalproperty_new_clone() ) -\layout Description +\protected_separator -2) If you got the memory from a routine with new in it, you must call the - corresponding *_free routine to free the memory. - ( Use icalcomponent_free() to free objects created with icalcomponent_new()) - -\layout Description +\protected_separator -3) If the function name has "add" in it, the caller is transfering control - of the memory to the routine. - ( icalproperty_add_parameter() ) -\layout Description +\protected_separator -4) If the function name has "remove" in it, the caller passes in a pointer - to an object and after the call returns, the caller owns the object. - So, before you call icalcomponent_remove_property(comp,foo), you do not - own "foo" and after the call returns, you do. - -\layout Description +\protected_separator -5) If the routine returns a string, libical owns the memory and will put - it on a ring buffer to reclaim later. - You'd better strdup() it if you want to keep it, and you don't have to - delete it. - -\layout Subsection +\protected_separator -Error Handling -\layout Standard +\protected_separator -icalerror_errno. - Return values. - #defines. - icalerror_stop_here -\layout Subsubsection +\protected_separator -Return values -\layout Subsubsection +\protected_separator + icalproperty_new_version(strdup("2.0")), +\layout Code -icalerrno -\layout Subsubsection -Component errors +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + icalproperty_new_prodid(strdup("-//RDU Software//NONSGML HandCal//EN")), +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + icalcomponent_vanew( +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator +ICAL_VEVENT_COMPONENT, +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator +icalproperty_new_dtstamp(atime), +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator +icalproperty_new_uid(strdup("guid-1.host1.com")), +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator +icalproperty_vanew_organizer( +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + strdup("mrbig@host.com"), +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + icalparameter_new_role(ICAL_ROLE_CHAIR), +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + 0 +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator +), +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator +icalproperty_vanew_attendee( +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + strdup("employee-A@host.com"), +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + icalparameter_new_role(ICAL_ROLE_REQPARTICIPANT), +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + icalparameter_new_rsvp(1), +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + icalparameter_new_cutype(ICAL_CUTYPE_GROUP), +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + 0 +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + ), +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator +icalproperty_new_location(strdup("1CP Conference Room 4350")), +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator +0 +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator +), +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + 0 +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + ); +\layout Standard + +This form is similar to the regular constructor, except that they have +\begin_inset Quotes eld +\end_inset + +vanew +\begin_inset Quotes erd +\end_inset + + instead of +\begin_inset Quotes eld +\end_inset + +new +\begin_inset Quotes erd +\end_inset + + in the name. + The arguments are similar too, except that the component contstructor can + have a list of properties, and the property constructor can have a list + or parameters. + Be sure to terminate every list with a '0', or your code will crash, if + you are lucky. + +\layout Subsubsection + +Parsing Text Files +\layout Standard + +The final way to create components will probably be the most common; you + can create components from RFC2445 compliant text. + If you have the string in memory, use +\layout Verbatim + +icalcomponent* icalparser_parse_string(char* str); +\layout Standard + +This may seem wasteful if you want to pull a large component off of the + network; you may prefer to parse the component line by line. + This is possible too, with +\layout Verbatim + +icalcomponent* icalparser_parse(char*(*line_gen_func)(char *s, size_t size, + void *d)); +\layout Standard + +This routine takes a pointer to a function that copies 'size' characters + to 's'. + The routine returns 's', similar to fgets(). + See string_line_generator in icalparser.c for an example. + +\layout Subsection + +Accessing Components +\layout Standard + +Given a reference to a component, you probably will want to access the propertie +s, parameters and values inside. + +\layout Subsubsection + +Finding Components +\layout Standard + +To find a sub-component of a component, use: +\layout Verbatim + +icalproperty* icalcomponent_get_first_component( +\layout Verbatim + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator +icalcomponent* component, +\layout Verbatim + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator +icalcomponent_kind kind); +\layout Standard + +This routine will return a reference to the first component of the type + 'kind.' The key kind values, listed in icalenums.h are: +\layout Code + +ICAL_ANY_COMPONENT +\layout Code + +ICAL_VEVENT_COMPONENT +\layout Code + +ICAL_VTODO_COMPONENT +\layout Code + +ICAL_VJOURNAL_COMPONENT +\layout Code + +ICAL_VCALENDAR_COMPONENT +\layout Code + +ICAL_VFREEBUSY_COMPONENT +\layout Code + +ICAL_VALARM_COMPONENT +\layout Standard + +These are only the most common components; there are many more listed in + icalenums.h. +\layout Standard + +As you might guess, if there is more than one subcomponent of the type you + have chosen, this routine will return only the first. + to get at the others, you need to iterate through the component. + +\layout Subsubsection + +Interating Through Components +\layout Standard + +Iteration requires a second routine to get the next subcomponent after the + first: +\layout Verbatim + +icalcomponent* icalcomponent_get_next_component(icalcomponent* component, + +\layout Verbatim + +icalcomponent_kind kind); +\layout Standard + +With the 'first' and 'next' routines, you can create a for loop to iterate + through all of a components subcomponents +\layout Code + + +\protected_separator + for(c = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT); +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator +c != 0; +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator +c = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT)) +\layout Code + +{ +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + do_something(c); +\layout Code + +} +\layout Standard + +This code bit wil iterate through all of the subcomponents in 'comp' but + you can select a specific type of component by changing ICAL_ANY_COMPONENT + to another component type. +\layout Subsubsection + +Removing Components +\layout Standard + +Libical component have internal iterators, so you can only have one iteration + over a component at a time. + Removing an element from a list while iterating through the list can cause + problems, since you will probably be removing the element that the internal + iterator points to. + This will result in the iteration loop terminating immediately after removing + the element. + To avoid the problem, you will need to step the iterator ahead of the element + you are going to remove, like this: +\layout Code + +for(c = icalcomponent_get_first_component(parent_comp,ICAL_ANY_COMPONENT); + +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator +c != 0; +\layout Code + + +\protected_separator + +\protected_separator + +\protected_separator + +\protected_separator +c = next +\layout Code + +{ +\protected_separator + +\protected_separator + +\layout Code + + +\protected_separator +next = icalcomponent_get_next_component(parent_comp,ICAL_ANY_COMPONENT); +\layout Code + + +\protected_separator + +\protected_separator + icalcomponent_remove_component(parent_comp,c); +\layout Code + +} +\layout Subsubsection + +Working with properties and parameters +\layout Standard + +Finding, iterating and removing properties works the same as it does for + components, using the property-specific or parameter-specific interfaces: + +\layout Verbatim + +icalproperty* icalcomponent_get_first_property( +\layout Verbatim + + +\protected_separator + +\protected_separator + +\protected_separator +icalcomponent* component, +\layout Verbatim + + +\protected_separator + +\protected_separator + +\protected_separator +icalproperty_kind kind); +\layout Verbatim + +icalproperty* icalcomponent_get_next_property( +\layout Verbatim + + +\protected_separator + +\protected_separator + +\protected_separator +icalcomponent* component, +\layout Verbatim + + +\protected_separator + +\protected_separator + +\protected_separator +icalproperty_kind kind); +\layout Verbatim + +void icalcomponent_add_property( +\layout Verbatim + + +\protected_separator + +\protected_separator + +\protected_separator +icalcomponent* component, +\layout Verbatim + + +\protected_separator + +\protected_separator + +\protected_separator +icalproperty* property); +\layout Verbatim + +void icalcomponent_remove_property( +\layout Verbatim + + +\protected_separator + +\protected_separator + +\protected_separator +icalcomponent* component, +\layout Verbatim + + +\protected_separator + +\protected_separator + +\protected_separator +icalproperty* property); +\layout Verbatim + +icalparameter* icalproperty_get_first_parameter( +\layout Verbatim + + +\protected_separator + +\protected_separator + +\protected_separator +icalproperty* prop, +\layout Verbatim + + +\protected_separator + +\protected_separator + +\protected_separator +icalparameter_kind kind); +\layout Verbatim + +icalparameter* icalproperty_get_next_parameter( +\layout Verbatim + + +\protected_separator + +\protected_separator + +\protected_separator +icalproperty* prop, +\layout Verbatim + + +\protected_separator + +\protected_separator + +\protected_separator +icalparameter_kind kind); +\layout Verbatim + +void icalproperty_add_parameter( +\layout Verbatim + + +\protected_separator + +\protected_separator + +\protected_separator +icalproperty* prop, +\layout Verbatim + + +\protected_separator + +\protected_separator + +\protected_separator +icalparameter* parameter); +\layout Verbatim + +void icalproperty_remove_parameter( +\layout Verbatim + + +\protected_separator + +\protected_separator + +\protected_separator +icalproperty* prop, +\layout Verbatim + + +\protected_separator + +\protected_separator + +\protected_separator +icalparameter_kind kind); +\layout Subsubsection + +Getting Values +\layout Subsubsection + +Setting Values +\layout Subsubsection + +Getting Parameters +\layout Subsubsection + +Setting Parameters +\layout Subsubsection + +Removing Parameters +\layout Subsubsection + +Checking Component Validity +\layout Subsection + +Storing Objects +\layout Standard + +The libical distribution inclues a seperate library, libicalss, that allows + you to store iCal component data to disk in a variety of ways. + This library is documented seperately. + +\layout Subsection + + +\begin_inset LatexCommand \label{sec:memory} + +\end_inset + +Memory Management +\layout Standard + +Libical relies heavily on dynamic allocation for both the core objects and + for the strings used to hold values. + Some of this memory the library caller owns and must free, and some of + the memory is managed by the library. + Here is a summary of the memory rules. + +\layout Description + +1) If the function name has "new" in it, the caller gets control of the + memory. + ( such as icalcomponent_new(), or icalproperty_new_clone() ) +\layout Description + +2) If you got the memory from a routine with new in it, you must call the + corresponding *_free routine to free the memory. + ( Use icalcomponent_free() to free objects created with icalcomponent_new()) + +\layout Description + +3) If the function name has "add" in it, the caller is transfering control + of the memory to the routine. + ( icalproperty_add_parameter() ) +\layout Description + +4) If the function name has "remove" in it, the caller passes in a pointer + to an object and after the call returns, the caller owns the object. + So, before you call icalcomponent_remove_property(comp,foo), you do not + own "foo" and after the call returns, you do. + +\layout Description + +5) If the routine returns a string, libical owns the memory and will put + it on a ring buffer to reclaim later. + You'd better strdup() it if you want to keep it, and you don't have to + delete it. + +\layout Subsection + +Error Handling +\layout Standard + +icalerror_errno. + Return values. + #defines. + icalerror_stop_here. + X-LIC-ERROR +\layout Subsubsection + +Return values +\layout Subsubsection + +icalerrno +\layout Subsubsection + +Component errors +\layout Subsubsection + +icalerror_stop_here +\layout Subsubsection + +X-LIC-ERROR \layout Subsection Naming Standard @@ -678,7 +2215,7 @@ _VALUE, \begin_inset Quotes eld \end_inset -_PAAMETER +_PARAMETER \begin_inset Quotes erd \end_inset @@ -701,7 +2238,7 @@ Iteration \layout Standard Copying components. - Remember that you must clone or remove an object before putting in on anothr + Remember that you must clone or remove an object before putting in on another list. \layout Standard diff --git a/libical/doc/UsingLibical.ps b/libical/doc/UsingLibical.ps new file mode 100644 index 0000000000..0417ded6a5 --- /dev/null +++ b/libical/doc/UsingLibical.ps @@ -0,0 +1,1308 @@ +%!PS-Adobe-2.0 +%%Creator: dvips(k) 5.85 Copyright 1999 Radical Eye Software +%%Title: UsingLibical.dvi +%%Pages: 6 +%%PageOrder: Ascend +%%BoundingBox: 0 0 612 792 +%%EndComments +%DVIPSWebPage: (www.radicaleye.com) +%DVIPSCommandLine: dvips -t letter -o +%+ /usr/local/home/eric/proj/FreeAssociation/libical/doc/UsingLibical.ps +%+ UsingLibical.dvi +%DVIPSParameters: dpi=600, compressed +%DVIPSSource: TeX output 2000.02.18:1517 +%%BeginProcSet: texc.pro +%! +/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S +N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 +mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 +0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ +landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize +mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ +matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round +exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ +statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] +N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin +/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array +/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 +array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N +df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A +definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get +}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} +B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr +1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 +1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx +0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx +sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ +rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp +gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B +/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ +/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ +A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy +get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} +ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp +fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 +{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add +chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ +1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} +forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn +/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put +}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ +bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A +mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ +SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ +userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X +1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 +index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N +/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ +/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) +(LaserWriter 16/600)]{A length product length le{A length product exch 0 +exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse +end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask +grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} +imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round +exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto +fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p +delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} +B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ +p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S +rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end + +%%EndProcSet +TeXDict begin 40258431 52099146 1000 600 600 (UsingLibical.dvi) +@start +%DVIPSBitmapFont: Fa ecbx1000 10 47 +/Fa 47 122 df<913A03FF8007FE027F9039F07FFF800103B500FDB512E0010F903A00FF +FE0FF0D93FF8ECF81F90267FE0019038F03FF849485A4816E014804816C00200ED1FF081 +F007C06F91C7FCA8B912E0A4000390C701C0C7FCB3ABB5D8FC3FEBFF80A43D3A7EB938> +27 D<12E07E127C7E7E7F6C7E6C7E12037F6C7E7F12007F137E137FA2EB3F80A214C013 +1F14E0A2130F14F0A4EB07F8A514FCB114F8A5EB0FF0A414E0131FA214C0133F1480A2EB +7F00A2137E13FE5B12015B485A5B1207485A485A90C7FC123E5A12F05A16537BBD25>41 +D46 +D<49B4FC011F13F0017F13FC9038FF83FE4848C67E4848EB7F804848EB3FC04848EB1FE0 +A2001F15F0A24848EB0FF8A3007F15FCA400FF15FEB3007F15FCA5003F15F86D131FA200 +1F15F0A26C6CEB3FE0000715C06C6CEB7F806C6CEBFF003900FF83FE6DB45A011F13F001 +0190C7FC27377CB530>48 D<141E143E14FE1307137FB5FCA3138FEA000FB3B3A5007FB6 +1280A4213679B530>IIII<001C15C0D81F80 +130701F8137F90B61280A216005D5D15F05D15804AC7FC14F090C9FCA7EB03FE90381FFF +E0017F13F89038FE07FC9038F003FFD9C0011380496C13C090C7FC000E15E0C8127F16F0 +A216F8A3121FEA3FC0487E12FF7FA316F05B15FFD87F8014E0007EC713C0003E5B003F49 +13806C6C481300390FF01FFE6CB512F8000114E06C6C1380D90FF8C7FC25377BB530>I< +EC0FF8ECFFFE0103EBFF8090390FF80FC090393FE003E090397F8001F09038FF000F48EC +1FF84848133F485A120F5B121FA2003FEC1FF0ED0FE0484890C7FCA31408EC7FF039FFF1 +FFFC01F313FFD9F78013809039FF007FC049EB3FE04914F0ED1FF85B16FCA34914FEA412 +7FA5123F16FCA26C7E16F8000F143F6D14F0000715E06C6CEB7FC03A01FF81FF806C90B5 +1200013F13FC010F13F00101138027377CB530>I<123C123EEA3FE090B71280A4170048 +5D5E5E5E5EA2007CC7EA0FC000784A5A4BC7FC00F8147E485C5D14014A5AC7485A4A5AA2 +4A5A143F4AC8FCA214FEA213015C1303A21307A2130F5CA2131FA5133FA96D5A6D5A6D5A +29397BB730>I<49B47E010F13F0013F13FC9038FE01FF3A01F8007F804848EB3FC04848 +EB1FE0150F484814F01507121FA27F7F7F6D130F01FF14E014C09138E01FC06CEBF83F91 +38FE7F806C9038FFFE005D6C14F06C14FC6C14FF6D14806D14C090B612E0D803FD14F026 +07F07F13F848487E261FC00F13FC383F8003007F010013FE90C7127F151F00FE14071503 +1501A21500A216FC7E6C14016D14F86C6C13036DEB07F06C6CEB0FE0D80FFEEB7FC00003 +B61200C614FC013F13F00103138027377CB530>II67 DI70 +DI73 D76 D80 +D82 DI<003FB91280A4D9F800EBF003D87FC09238007FC049 +161F007EC7150FA2007C1707A200781703A400F818E0481701A4C892C7FCB3AE010FB7FC +A43B387DB742>III97 +D<13FFB5FCA412077EAF4AB47E020F13F0023F13FC9138FE03FFDAF00013804AEB7FC002 +80EB3FE091C713F0EE1FF8A217FC160FA217FEAA17FCA3EE1FF8A217F06E133F6EEB7FE0 +6E14C0903AFDF001FF80903AF8FC07FE009039F03FFFF8D9E00F13E0D9C00390C7FC2F3A +7EB935>I<903801FFC0010F13FC017F13FFD9FF8013802603FE0013C048485AEA0FF812 +1F13F0123F6E13804848EB7F00151C92C7FC12FFA9127FA27F123FED01E06C7E15036C6C +EB07C06C6C14806C6C131FC69038C07E006DB45A010F13F00101138023257DA42A>II<903803FF8001 +1F13F0017F13FC3901FF83FE3A03FE007F804848133F484814C0001FEC1FE05B003FEC0F +F0A2485A16F8150712FFA290B6FCA301E0C8FCA4127FA36C7E1678121F6C6C14F86D14F0 +00071403D801FFEB0FE06C9038C07FC06DB51200010F13FC010113E025257DA42C>II<161FD907FE +EBFFC090387FFFE348B6EAEFE02607FE07138F260FF801131F48486C138F003F15CF4990 +387FC7C0EEC000007F81A6003F5DA26D13FF001F5D6C6C4890C7FC3907FE07FE48B512F8 +6D13E0261E07FEC8FC90CAFCA2123E123F7F6C7E90B512F8EDFF8016E06C15F86C816C81 +5A001F81393FC0000F48C8138048157F5A163FA36C157F6C16006D5C6C6C495AD81FF0EB +07FCD807FEEB3FF00001B612C06C6C91C7FC010713F02B377DA530>I<13FFB5FCA41207 +7EAFED7FC0913803FFF8020F13FE91381F03FFDA3C01138014784A7E4A14C05CA25CA291 +C7FCB3A3B5D8FC3F13FFA4303A7DB935>II<13FFB5FCA412077EAF92 +380FFFE0A4923803FC0016F0ED0FE0ED1F804BC7FC157E5DEC03F8EC07E04A5A141FEC7F +E04A7E8181A2ECCFFEEC0FFF496C7F806E7F6E7F82157F6F7E6F7E82150F82B5D8F83F13 +F8A42D3A7EB932>107 D<13FFB5FCA412077EB3B3ACB512FCA4163A7DB91B>I<01FED97F +E0EB0FFC00FF902601FFFC90383FFF80020701FF90B512E0DA1F81903983F03FF0DA3C00 +903887801F000749DACF007F00034914DE6D48D97FFC6D7E4A5CA24A5CA291C75BB3A3B5 +D8FC1FB50083B512F0A44C257DA451>I<01FEEB7FC000FF903803FFF8020F13FE91381F +03FFDA3C011380000713780003497E6D4814C05CA25CA291C7FCB3A3B5D8FC3F13FFA430 +257DA435>I<903801FFC0010F13F8017F13FFD9FF807F3A03FE003FE048486D7E48486D +7E48486D7EA2003F81491303007F81A300FF1680A9007F1600A3003F5D6D1307001F5DA2 +6C6C495A6C6C495A6C6C495A6C6C6CB45A6C6CB5C7FC011F13FC010113C029257DA430> +I<9039FF01FF80B5000F13F0023F13FC9138FE07FFDAF00113800003496C13C00280EB7F +E091C713F0EE3FF8A2EE1FFCA3EE0FFEAA17FC161FA217F8163F17F06E137F6E14E06EEB +FFC0DAF00313809139FC07FE0091383FFFF8020F13E0020390C7FC91C9FCACB512FCA42F +357EA435>I<9038FE03F000FFEB0FFEEC3FFF91387C7F809138F8FFC000075B6C6C5A5C +A29138807F80ED3F00150C92C7FC91C8FCB3A2B512FEA422257EA427>114 +D<90383FF0383903FFFEF8000F13FF381FC00F383F0003007E1301007C130012FC15787E +7E6D130013FCEBFFE06C13FCECFF806C14C06C14F06C14F81203C614FC131F9038007FFE +140700F0130114007E157E7E157C6C14FC6C14F8EB80019038F007F090B512C000F81400 +38E01FF81F257DA426>I<130FA55BA45BA25B5BA25A1207001FEBFFE0B6FCA3000390C7 +FCB21578A815F86CEB80F014816CEBC3E090383FFFC06D1380903803FE001D357EB425> +I<01FFEC3FC0B5EB3FFFA4000714016C80B3A35DA25DA26C5C6E4813E06CD9C03E13FF90 +387FFFFC011F13F00103138030257DA435>II120 DI E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fb ecbx1200 12 47 +/Fb 47 122 df<157F913803FFC0020F7F4A7F91383FE1F891387F80789138FF007C4914 +3C495A163E4948131EA3130FA3163E163C167C16786E13F84B5A4B5A15075E6D6C485A4B +C70003B512E0153E15FC6D5B5D4B91390007C0004B5E6D6D150F4FC7FC6D6D151E49173E +496D5D491778496D15F890261FBFFE4A5AD93F3F5E9026FE1FFF1403D801FC6E495A0003 +6D5E48486C6D130F000F6F49C8FC001F6D6D133E48486C6D133C187C007F6D6D5B6F6C48 +5A00FF6E6C485A6FEB87C06F13CFEFFF806F91C9FC6D6D5B6F49EC01E06F7F6C6CEC3FFF +706D13036C6C4A6DEB07C06C6C91B500F0130FDA800702FCEB1F806C9026E03FF89039FF +80FF00000390B5D8F03FEBFFFE6CDBC00F5C6C6CDA00035C011F01F8D9007F13E0010301 +80020790C7FC4B477BC557>38 D45 DI49 DII<163FA25E5E5D5DA25D5D5D5DA25D92B5FCEC01F7EC03E7 +140715C7EC0F87EC1F07143E147E147C14F8EB01F0EB03E0130714C0EB0F80EB1F00133E +5BA25B485A485A485A120F5B48C7FC123E5A12FCB91280A5C8000F90C7FCAC027FB61280 +A531417DC038>I<0007150301E0143F01FFEB07FF91B6FC5E5E5E5E5E16804BC7FC5D15 +E092C8FC01C0C9FCAAEC3FF001C1B5FC01C714C001DF14F09039FFE03FFC9138000FFE01 +FC6D7E01F06D13804915C0497F6C4815E0C8FC6F13F0A317F8A4EA0F80EA3FE0487E12FF +7FA317F05B5D6C4815E05B007EC74813C0123E003F4A1380D81FC0491300D80FF0495AD8 +07FEEBFFFC6CB612F0C65D013F1480010F01FCC7FC010113C02D427BC038>I<4AB47E02 +1F13F0027F13FC49B6FC01079038807F8090390FFC001FD93FF014C04948137F4948EBFF +E048495A5A1400485A120FA248486D13C0EE7F80EE1E00003F92C7FCA25B127FA2EC07FC +91381FFF8000FF017F13E091B512F89039F9F01FFC9039FBC007FE9039FF8003FF17804A +6C13C05B6F13E0A24915F0A317F85BA4127FA5123FA217F07F121FA2000F4A13E0A26C6C +15C06D4913806C018014006C6D485A6C9038E01FFC6DB55A011F5C010714C0010191C7FC +9038003FF02D427BC038>I<121E121F13FC90B712FEA45A17FC17F817F017E017C0A248 +1680007EC8EA3F00007C157E5E00785D15014B5A00F84A5A484A5A5E151FC848C7FC157E +5DA24A5A14035D14074A5AA2141F5D143FA2147F5D14FFA25BA35B92C8FCA35BA55BAA6D +5A6D5A6D5A2F447AC238>III65 +D67 +DII71 +DI76 DII<923807FFC092B512FE0207ECFFC0021F15F091267FFE0013FC90 +2601FFF0EB1FFF01070180010313C04990C76C7FD91FFC6E6C7E49486F7E49486F7E01FF +8348496F7E48496F1380A248496F13C0A24890C96C13E0A24819F04982003F19F8A3007F +19FC49177FA400FF19FEAD007F19FC6D17FFA3003F19F8A26D5E6C19F0A26E5D6C19E0A2 +6C6D4B13C06C19806E5D6C6D4B13006C6D4B5A6D6C4B5A6D6C4B5A6D6C4A5B6D01C00107 +5B6D01F0011F5B010101FE90B5C7FC6D90B65A023F15F8020715C002004AC8FC030713C0 +47467AC454>II82 DI<003FBA12E0A59026FE000FEB8003D87FE09338003FF049171F90C71607 +A2007E1803007C1801A300781800A400F819F8481978A5C81700B3B3A20107B8FCA54543 +7CC24E>I86 D<903801FFE0011F13FE017F6D7E48B612E03A03FE007F +F84848EB1FFC6D6D7E486C6D7EA26F7FA36F7F6C5A6C5AEA00F090C7FCA40203B5FC91B6 +FC1307013F13F19038FFFC01000313E0481380381FFE00485A5B127F5B12FF5BA35DA26D +5B6C6C5B4B13F0D83FFE013EEBFFC03A1FFF80FC7F0007EBFFF86CECE01FC66CEB8007D9 +0FFCC9FC322F7DAD36>97 DIII +I103 DI<137C48B4FC4813804813C0A24813E0A56C13C0A26C13806C1300EA007C90C7 +FCAAEB7FC0EA7FFFA512037EB3AFB6FCA518467CC520>II108 D<90277F8007FEEC0FFCB590263FFFC090387FFF8092B5D8F001B5 +12E002816E4880913D87F01FFC0FE03FF8913D8FC00FFE1F801FFC0003D99F009026FF3E +007F6C019E6D013C130F02BC5D02F86D496D7EA24A5D4A5DA34A5DB3A7B60081B60003B5 +12FEA5572D7CAC5E>I<90397F8007FEB590383FFF8092B512E0028114F8913987F03FFC +91388F801F000390399F000FFE6C139E14BC02F86D7E5CA25CA35CB3A7B60083B512FEA5 +372D7CAC3E>II<90397FC0 +0FF8B590B57E02C314E002CF14F89139DFC03FFC9139FF001FFE000301FCEB07FF6C496D +13804A15C04A6D13E05C7013F0A2EF7FF8A4EF3FFCACEF7FF8A318F017FFA24C13E06E15 +C06E5B6E4913806E4913006E495A9139DFC07FFC02CFB512F002C314C002C091C7FCED1F +F092C9FCADB67EA536407DAC3E>I<90387F807FB53881FFE0028313F0028F13F8ED8FFC +91389F1FFE000313BE6C13BC14F8A214F0ED0FFC9138E007F8ED01E092C7FCA35CB3A5B6 +12E0A5272D7DAC2E>114 D<90391FFC038090B51287000314FF120F381FF003383FC000 +49133F48C7121F127E00FE140FA215077EA27F01E090C7FC13FE387FFFF014FF6C14C015 +F06C14FC6C800003806C15806C7E010F14C0EB003F020313E0140000F0143FA26C141F15 +0FA27EA26C15C06C141FA26DEB3F8001E0EB7F009038F803FE90B55A00FC5CD8F03F13E0 +26E007FEC7FC232F7CAD2C>IIII121 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fc ectt1000 10 59 +/Fc 59 126 df<121FEA3F80EA7FC0EAFFE0B0EA7FC0AEEA1F00C7FCA7121FEA3F80EA7F +C0EAFFE0A5EA7FC0EA3F80EA1F000B3470B32C>33 D<003C131E007F137F481480A66C14 +00A6007E7FA6003E133EA3003C131E001C131C191977B32C>I<143814FC13011303EB07 +F8EB0FF0EB1FC0EB3F80EB7F0013FE485A485A5B12075B120F5B485AA2123F90C7FCA25A +127EA312FE5AAC7E127EA3127F7EA27F121FA26C7E7F12077F12037F6C7E6C7E137FEB3F +80EB1FC0EB0FF0EB07F8EB03FC130113001438164272B92C>40 D<127012FC7E7E6C7E6C +7EEA0FE06C7E6C7E6C7E6C7E137F7F1480131F14C0130FEB07E0A214F01303A214F81301 +A314FC1300AC130114F8A3130314F0A2130714E0A2EB0FC0131F1480133F14005B13FE48 +5A485A485A485AEA3FC0485A48C7FC5A5A1270164279B92C>I44 D<007FB512F0B612F8A36C14F01D0579942C>I<121FEA3F80EA +7FC0EAFFE0A5EA7FC0EA3F80EA1F000B0B708A2C>I<1507ED0F80A2151F16005D153E15 +7E157CA215FC5D14015D14035D14075D140F5D141F92C7FC5C143EA2147E147C14FC5C13 +015C13035C13075C130F5C131F91C8FC5B133EA2137E137C13FC5B12015B12035B12075B +120F5B121F90C9FCA25A123E127E127C12FC5AA2127021417BB92C>II<1307497EA2131FA2133F137F13FF5A1207127FB5FC13 +DF139FEA7C1F1200B3AE007FB512E0B612F0A36C14E01C3477B32C>I<121FEA3F80EA7F +C0EAFFE0A5EA7FC0EA3F80EA1F00C7FCAE121FEA3F80EA7FC0EAFFE0A5EA7FC0EA3F80EA +1F000B2470A32C>58 DI<007FB612F0B712F8A36C15F0CAFCA8007F +B612F0B712F8A36C15F025127DA12C>61 D64 +D<14FE497EA4497FA214EFA2130781A214C7A2010F7FA314C390381F83F0A590383F01F8 +A490387E00FCA549137E90B512FEA34880A29038F8003FA34848EB1F80A4000715C04913 +0FD87FFEEBFFFC6D5AB514FE6C15FC497E27347EB32C>I<02FF13700107EBE0F84913F9 +013F13FD4913FFEBFF813901FE007F4848131FD807F0130F1507485A491303485A150148 +C7FCA25A007EEC00F01600A212FE5AAB7E127EA3007F15F06CEC01F8A26C7EA26C6C1303 +6D14F06C6C130716E0D803FC131F6C6CEB3FC03A00FF81FF806DB512006D5B010F5B6D13 +F00100138025357DB32C>67 D<007FB612F0B712F8A37E3903F00001A7ED00F01600A4EC +01E04A7EA490B5FCA5EBF003A46E5A91C8FCA5163C167EA8007FB612FEB7FCA36C15FC27 +337EB22C>69 D<903901FC038090390FFF87C04913EF017F13FF90B6FC4813073803FC01 +497E4848137F4848133F49131F121F5B003F140F90C7FCA2127EED078092C7FCA212FE5A +A8913803FFF84A13FCA27E007E6D13F89138000FC0A36C141FA27F121F6D133F120F6D13 +7F6C7E6C6C13FF6D5A3801FF076C90B5FC6D13EF011F13CF6DEB0780D901FCC7FC26357D +B32C>71 DI<007FB512F8B612FCA36C14 +F839000FC000B3B3A5007FB512F8B612FCA36C14F81E3379B22C>I<387FFFE0B57EA36C +5BD803F0C8FCB3AE16F0ED01F8A8007FB6FCB7FCA36C15F025337DB22C>76 +DIII<007FB512C0B612F88115FF6C15802603F00013C0153FED0FE0ED07 +F0A2150316F81501A6150316F01507A2ED0FE0ED3FC015FF90B61280160015FC5D15C001 +F0C8FCB0387FFF80B57EA36C5B25337EB22C>I<387FFFFCB67E15E015F86C803907E007 +FE1401EC007F6F7E151FA26F7EA64B5AA2153F4BC7FCEC01FE140790B55A5D15E0818190 +38E007FCEC01FE1400157F81A8160FEE1F80A5D87FFEEB1FBFB5ECFF00815E6C486D5AC8 +EA01F029347EB22C>82 D<90381FF80790B5EA0F804814CF000714FF5A381FF01F383FC0 +03497E48C7FC007E147F00FE143F5A151FA46CEC0F00007E91C7FC127F7FEA3FE0EA1FFC +EBFFC06C13FC0003EBFFC06C14F06C6C7F01077F9038007FFEEC07FF02001380153FED1F +C0A2ED0FE0A20078140712FCA56CEC0FC0A26CEC1F806D133F01E0EB7F009038FE01FF90 +B55A5D00F914F0D8F83F13C0D8700790C7FC23357CB32C>I<007FB612FCB712FEA43AFC +007E007EA70078153CC71400B3AF90383FFFFCA2497F6D5BA227337EB22C>I86 D89 D<003FB612C04815E0A400 +7EC7EA1FC0ED3F80A2ED7F00157E15FE4A5A003C5CC712034A5AA24A5A4A5AA24A5A4AC7 +FCA214FE495AA2495A495AA2495A495AA2495A49C8FCA213FE485AA24848EB03C049EB07 +E01207485A5B121F485AA248C7FCB7FCA46C15C023337CB22C>I<007FB6FCB71280A46C +150021067B7D2C>95 D<3801FFF0000713FE001F6D7E15E048809038C01FF81407EC01FC +381F80000006C77EC8127EA3ECFFFE131F90B5FC1203120F48EB807E383FF800EA7FC090 +C7FC12FE5AA47E007F14FEEB8003383FE01F6CB612FC6C15FE6C14BF0001EBFE1F3A003F +F007FC27247CA32C>97 DI<903803FFE0011F13F8017F13FE48B5FC48804848C6FC +EA0FF0485A49137E4848131890C9FC5A127EA25AA8127EA2127F6C140F6DEB1F806C7E6D +133F6C6CEB7F003907FE03FF6CB55A6C5C6C6C5B011F13E0010390C7FC21247AA32C>I< +EC0FFE4A7EA380EC003FAAEB07F8EB3FFE90B512BF4814FF5A3807FC0F380FF00348487E +497E48487F90C7FC007E80A212FE5AA87E007E5CA2007F5C6C7E5C6C6C5A380FF0073807 +FC1F6CB612FC6CECBFFE6C143FEB3FFC90390FF01FFC27337DB22C>IIIII<1307EB1FC0A2497EA36D5AA20107C7FC90C8FCA7387FFFC080B5FC7E +A2EA0007B3A8007FB512FCB612FEA36C14FC1F3479B32C>I<140EEC3F80A2EC7FC0A3EC +3F80A2EC0E0091C7FCA748B512804814C0A37EC7120FB3B3A2141F003C1480007E133FB4 +14005CEB01FEEBFFFC6C5B5C001F5B000790C7FC1A467CB32C>II<387FFFE0B57EA37E +EA0003B3B3A5007FB61280B712C0A36C158022337BB22C>I<3A7F83F007E09039CFFC1F +F83AFFDFFE3FFCD87FFF13FF91B57E3A07FE1FFC3E01FCEBF83F496C487E01F013E001E0 +13C0A301C01380B33B7FFC3FF87FF0027F13FFD8FFFE6D13F8D87FFC4913F0023F137F2D +2481A32C>I<397FF01FE039FFF87FFC9038F9FFFE01FB7F6CB6FC00019038F03F80ECC0 +1F02807FEC000F5B5BA25BB3267FFFE0B5FCB500F11480A36C01E0140029247FA32C>I< +EB07FCEB1FFF017F13C048B512F048803907FC07FC390FF001FE48486C7E0180133F003F +158090C7121F007EEC0FC0A348EC07E0A76C140F007E15C0A2007F141F6C15806D133F6C +6CEB7F006D5B6C6C485A3907FC07FC6CB55A6C5C6C6C13C0011F90C7FCEB07FC23247CA3 +2C>I<397FF01FE039FFF8FFF801FB13FE90B6FC6C158000019038F07FC09138801FE091 +380007F049EB03F85BED01FC491300A216FE167EA816FE6D14FCA2ED01F86D13036DEB07 +F0150F9138801FE09138E07FC091B51280160001FB5B01F813F8EC3FC091C8FCAD387FFF +E0B57EA36C5B27367FA32C>I114 D<90387FF8700003B512F8120F5A5A387FC00F387E00034813015AA3 +6CEB00F0007F140013F0383FFFC06C13FE6CEBFF80000314E0C66C13F8010113FCEB0007 +EC00FE0078147F00FC143F151F7EA26C143F6D133E6D13FE9038F007FC90B5FC15F815E0 +00F8148039701FFC0020247AA32C>I<131E133FA9007FB6FCB71280A36C1500D8003FC8 +FCB1ED03C0ED07E0A5EC800F011FEB1FC0ECE07F6DB51280160001035B6D13F89038003F +E0232E7EAD2C>I<3A7FF003FF80486C487FA3007F7F0001EB000FB3A3151FA2153F6D13 +7F3900FE03FF90B7FC6D15807F6D13CF902603FE07130029247FA32C>I<3A7FFF01FFFC +B514FE148314016C15FC3A03E0000F80A26D131F00011500A26D5B0000143EA26D137E01 +7C137CA2017E13FC013E5BA2EB3F01011F5BA21483010F5BA214C701075BA214EF01035B +A214FF6D90C7FCA26D5A147C27247EA32C>II<3A3FFF03FFF048018713F8A36C010313F03A00FC007E005D90387E01F8013F5B +EB1F83EC87E090380FCFC0903807EF80EB03FF6D90C7FC5C6D5A147C14FE130180903803 +EF80903807CFC0EB0FC7EC83E090381F01F0013F7FEB7E00017C137C49137E0001803A7F +FF01FFFC1483B514FE6C15FC140127247EA32C>I<3A7FFF01FFFCB5008113FE14831481 +6C010113FC3A03E0000F806C7E151F6D140012005D6D133E137C017E137E013E137CA201 +3F13FC6D5BA2EB0F815DA2EB07C1ECC3E0A2EB03E3ECE7C0130114F75DEB00FFA292C7FC +80A2143EA2147E147CA214FC5CA2EA0C01003F5BEA7F83EB87E0EA7E0F495A387FFF806C +90C8FC6C5A6C5AEA07E027367EA32C>I<003FB612E04815F0A4007EC7EA1FE0ED3FC0ED +7F80EDFF004A5A003C495AC7485A4A5A4A5A4A5A4A5A4AC7FCEB01FC495AEB0FF0495A49 +5A495A49C8FC4848EB01E04848EB03F0485A485A485A485A485AB7FCA46C15E024247DA3 +2C>I<15FF02071380141F147F91B512004913C04AC7FCEB03F85CB31307EB1FE013FF00 +7F5BB55A49C8FC6D7E6C7FC67F131FEB07F01303B380EB01FEECFFC06D13FF6E1380141F +14070200130021417BB92C>I125 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fd ecbx1440 14.4 41 +/Fd 41 122 df27 +D<151E153E15FE1403140F147FEB07FF0003B5FCB6FCA3EBF87FEAFC00C7FCB3B3B3A600 +7FB712FCA52E4E76CD42>49 DI<913807FFC002 +7F13FC0103B67E010F15E090261FF80313F890267FC0007F01FEC7EA3FFE48488148486E +138013FE486C6C6D13C0804817E080A66C5B18C06C5B6C90C75AD80038168090C8FC4C13 +00A24C5A5F4C5A4B5B4B13C0030F5BDB7FFEC7FC91387FFFF816C016FCEEFF80DA000313 +E09238007FF8EE3FFE707E70138018C07013E018F07013F8A218FC82A218FEA3EA03C0EA +0FF0EA3FFC487EA2B5FCA218FCA25E18F8A26C4816F0495C4916E0D83FE04A13C06C485C +D80FF04A1380D807FE91387FFE003B03FFE003FFFC6C90B65A6C6C15E0010F92C7FC0101 +14FCD9001F1380374F7BCD42>I<17FC1601A216031607160FA2161F163F167FA216FF5D +5DA25D5D5D167F153E157E15FC15F8EC01F01403EC07E015C0EC0F80141FEC3F00143E5C +14FC495A5C495A1307495A5C49C7FC5B137E137C5B1201485A5B485A120F485A90C8FC12 +3E127E5ABA1280A5C901FCC7FCAF021FB71280A5394F7CCE42>I<486C150601F0153E01 +FEEC01FED9FFF0133F91B65A5F5F5F5F5F94C7FC16FC5E16E093C8FC15FC01F0138091CA +FCAC913807FF80023F13F891B512FE01F36E7E9026FFFC0113E09139E0007FF891C76C7E +496E7E01F86E7E5B7013804916C0C9FC18E08218F0A418F8A31203EA0FE0EA3FF8487EA2 +12FF7FA218F0A25B5E6C4816E05B01C016C06CC85A18806C6C4A13007FD80FF04A5A6C6C +ECFFFCD803FE4913F02701FFE00F5B6C6CB612806D92C7FC010F14F8010114C09026003F +FCC8FC354F7ACD42>II<121F7F7FEBFF8091B8FCA45A18FE18FC18 +F818F0A218E018C018804817000180C8123E007EC9127E5F007C4B5A4C5A5F16074C5A48 +4B5A4CC7FC167E167CC912FC4B5A4B5AA24B5A150F4B5AA24B5AA24BC8FC5DA25C5D1403 +A214075D140FA3141FA2143FA34A5AA414FFA65BAB6D5B6E5A6E5A6E5A385279D042>I< +913803FFC0023F13FC49B67E010715E090260FFC0013F8D93FE0EB1FFCD97F80EB07FE49 +C76C7E496E1380484880000317C049157F120718E0173F120FA27FA27F7F6E147F02E015 +C08002FC14FF6C01FF15806F481300EDE0036C9138F807FE6F485A6C9138FF1FF06CEDFF +E017806D4AC7FC7F010F6E7E6D81010115F06D81010315FE010F81D93FF71580D97FC115 +C02701FF807F14E048EB001F48486D14F04848010314F848481300496E13FC003F151F49 +1407007F6F13FE491400177F00FF163F49151F170F1707A21703A218FCA27F127F6DED07 +F8A26C6CED0FF07F6C6CED1FE06C6CED3FC06C6CEDFF806C01C0010313006C01FCEB3FFE +6C6CB612F8011F15E001071580010002FCC7FC020F13C0374F7BCD42>I<913807FF8002 +7F13F849B512FE01076E7E90261FFE0113E0903A7FF8003FF049486D7E48496D7E48496D +7E484980486F138091C7FC486F13C05A18E0485A18F0A27013F812FFA318FCA618FEA35E +127FA4003F5DA26C7E5E7E6C6D5B161E6C7F6C6D5B6C6C6C13F890393FFC03F06DB55A01 +074A13FC01001400EC1FF891C8FCA218F85EA301FC16F0487E2607FF8015E05E486D15C0 +A24C1380A24C13005F4A131F6C4B5A49C7485A494A5A6C48495B6D01075B2701FF803F90 +C7FC6C90B512FC013F5C6D14C0010791C8FC9038007FF0374F7BCD42>I66 D<932603FFF01407047F01FF140F0307B6 +00E0131F033F03F8133F92B700FE137F02039126C003FF13FF020F01F8C7EA3FC1023F01 +C0EC0FE391B5C80003B5FC4901FC814949814901E082011F498249498292CA7E49488349 +48835A4A83485B4885A24849187FA2485B1B3FA2485B1B1FA25AA21B0091CDFCA2B5FCAE +7EA280A36C1A1FA36C7FA21B3F6C7F1B3E6C7F1B7E6C6D187C6C1AFC6E18F86C19016D6C +EF03F06D7E6FEE07E06D6DEE0FC001076DEE1F806D01F8EE3F006D6D16FE6D01FF4B5A02 +3F01C0EC07F8020F01FCEC3FF00203903AFFC001FFC0020091B6C7FC033F15FC030715F0 +DB007F1480040301F0C8FC505479D25F>II70 +D72 DI76 +D80 +D82 DI85 D97 +DI<913803 +FFE0023F13FE91B67E010315E0010F9038003FF8D93FFCEB07FC4948497E4948131F4849 +497E485B485BA24890C7FC5A5B003F6F5A705A705A007F92C8FC5BA312FFAD127F7FA312 +3F7F6CEE0F80A26C6D141F18006C6D5C6C6D143E6C6D147E6C6D5C6D6C495A6DB4EB07F0 +010F9038C01FE06D90B5128001014AC7FCD9003F13F80203138031387CB63A>I<943803 +FF80040FB5FCA5EE003F170FB3A4913803FF80023F13F849B512FE0107ECFF8F011F9038 +C03FEF90273FFE0007B5FCD97FF8130149487F484980484980484980488291C8FC5A5B12 +3FA2127F5BA312FFAD127FA37F123FA3121F7F6C5E6C6D5C5F6C6D91B5FC6C6D5B6C6D49 +14E0D97FFCD90FEFEBFF80D91FFFEB7F8F010790B5120F010114FC6D6C13E00207010049 +C7FC41547CD249>I<913807FF80027F13F849B512FE01076E7E011F010313E0903A3FFC +007FF0D97FF06D7E49486D7E4849130F48496D7E48824890C77E1880485A82003F17C0A3 +485A18E082A212FFA290B8FCA401FCCAFCA6127FA37F123FA2EF03E06C7E17076C17C06C +6D140F18806C6D141F6C6DEC3F006C6D147ED97FFC495AD91FFFEB07F86D9038E03FF001 +0390B512C001005D023F01FCC7FC020113E033387CB63C>IIII<133FEBFFC0487F487FA2487FA66C5BA26C5B +6C5B013FC7FC90C8FCAEEB1FF8B5FCA512017EB3B3A6B612F0A51C547CD324>I107 DIII<913801FFC0023F13FE +91B67E010315E0010F018013F8903A3FFC001FFED97FF0EB07FF49486D7F48496D7F4849 +6D7F91C8127F4883488349153F001F83A2003F8349151FA2007F83A400FF1880AC007F18 +00A3003F5F6D153FA2001F5FA26C6C4B5AA26C6D4A5A6C5F6C6D495B6C6D495B6D6C4990 +C7FCD93FFCEB1FFE6DB46CB45A010790B512F0010115C0D9003F49C8FC020313E039387C +B642>II< +90393FF001FCB590380FFF804B13E0037F13F09238FE1FF89138F1F83F00019138F07FFC +6CEBF3E015C0ECF780A2ECFF00EE3FF84AEB1FF0EE0FE093C7FC5CA45CB3ABB612FEA52E +367DB535>114 D<903903FFC00E011FEBFC1E90B6127E000315FE3907FE003FD80FF013 +0F4848130348481301491300127F90C8127EA248153EA27FA27F01F091C7FC13FCEBFF80 +6C13FEECFFF06C14FE6F7E6C15E06C816C15FC6C81C681133F010F15801301D9000F14C0 +EC003F030713E0150100F880167F6C153FA2161F7EA217C07E6D143F17807F6DEC7F0001 +F85C6DEB03FE9039FF801FFC486CB512F0D8F81F14C0D8F00791C7FC39E0007FF02B387C +B634>I<147CA614FCA41301A31303A21307A2130F131F133F137F13FF1203000F90B512 +FEB7FCA426007FFCC8FCB3A9EE0F80ABEE1F006D7EA2011F143E806D6D5A6DEBC1F86DEB +FFF001005C023F1380DA03FEC7FC294D7ECB33>II121 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fe ecss2074 20.74 10 +/Fe 10 116 df76 +D85 +D<91380FFF8049B512F0010F14FC017F14FF48B712C0000782001F824882DAE0007F49C7 +EA3FFE01F8140FD81FC06E7E90C86C1380121E00186F13C0001081CAFCEF7FE0A318F017 +3FAD93B5FC157F0207B6FC143F49B7FC1307011F153F017FEBF80090B512804801F8C7FC +4813C04890C8FCEA0FFC485A485A5B485A5BA248C9FCA5177FA26D15FFA26C6C5C6D5C6D +140F6C6C5C01FF91B5FC6CEBE00791B612BF6CEDFE3F16FC6C15F06C15C06CECFE006C6C +13F0D91FFCC9FC344C77CA4C>97 DII103 D105 +D108 D110 +D<91380FFFC091B512FE0107ECFFC0011F15F8017F15FE90B812804817C05A489038F000 +3F4890C70003138049EC007FD81FF8151F491507003F16014992C7FCA2485AA77FA26C7E +7F7F6CB4FC6C13C014F86CEBFF806C14FC6CECFFE06C15FC6D14FF6D15C0010F81010315 +F8010081020F80DA007F7F03071480DB003F13C0160F040313E01600EF7FF0173FA2EF1F +F8A2170FA7EF1FF0A20070163F127C007FEE7FE001C015FF01F0020313C0B5020F138002 +F0137F91B712006C5E001F5E000716F0C65E011F1580010302FCC7FCD9000F13C0354C7C +CA3D>115 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Ff ecrm0700 7 1 +/Ff 1 66 df<140EA2141FA34A7EA3EC6FC0A2ECEFE014C7A290380183F0A390380301F8 +A201067F1400A249137EA2011C137F01187FA24980013FB5FCA2903960000FC0A201E080 +491307A248486D7EA200038115011207D81FC0497ED8FFF890383FFFE0A22B2A7EA931> +65 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fg ecrm1000 10 78 +/Fg 78 123 df21 D27 DIII<007C137C00FE13FEEAFF01A3EAFE00A7007E13FC +007C137CA8003C137800381338A700181330171E77BA2A>34 D<030C497EA2031C130303 +1891C7FCA303385B03301306A30370130E0360130CA303E0131C4B1318A3020114384B13 +30A30203147092C71260A34A14E0007FB91280BA12C0C7270C000180C7FCA2021C130302 +1891C8FCA402385B02301306A50270130E0260130CA2BA12C06C1880280001C00038C8FC +4A1330A30103147091C71260A34914E001065CA3010E1301010C5CA3011C1303011891C9 +FCA301385B01301306A30170130E0160130CA23A4A7BB945>II<121C +127FEAFF80A213C0A3127F121C1200A412011380A2120313005A1206120E5A5A5A12600A +1979B917>39 D<146014E0EB01C0EB0380EB0700130E131E5B5BA25B485AA2485AA21207 +5B120F90C7FCA25A121EA2123EA35AA65AB2127CA67EA3121EA2121F7EA27F12077F1203 +A26C7EA26C7E1378A27F7F130E7FEB0380EB01C0EB00E01460135278BD20>I<12C07E12 +707E7E7E120F6C7E6C7EA26C7E6C7EA21378A2137C133C133E131EA2131F7FA21480A3EB +07C0A6EB03E0B2EB07C0A6EB0F80A31400A25B131EA2133E133C137C1378A25BA2485A48 +5AA2485A48C7FC120E5A5A5A5A5A13527CBD20>II<121C127FEAFF80A213C0A3127F121C1200A4 +12011380A2120313005A1206120E5A5A5A12600A19798817>44 DI<121C127FEAFF80A5EA7F00121C0909798817>I<1506A2150E150CA2151C1518153815 +30A215701560A215E015C0A214011580A2140315005C1406A2140E140CA2141C1418A214 +381430A21470146014E05CA213015CA2130391C7FCA25B1306A2130E130C131C1318A213 +381330A213701360A213E05BA212015B120390C8FCA25A1206A2120E120CA2121C1218A2 +1238123012701260A212E05AA21F537BBD2A>IIIII<1538A2157815F8A2140114031407A2140F141F141B14331473146314C3 +13011483EB030313071306130C131C131813301370136013C01201EA038013005A120E12 +0C5A123812305A12E0B712F8A3C73803F800AA4A7E0103B512F8A325387EB72A>I<0006 +140CD80780133C9038F003F890B5FC5D5D158092C7FC14FC38067FE090C9FCAAEB07F8EB +1FFE9038780F809038E007E03907C003F0496C7E130000066D7E81C8FC8181A21680A412 +1C127F5A7FA390C713005D12FC00605C12704A5A6C5C6C1303001E495A6C6C485A3907E0 +3F800001B5C7FC38007FFCEB1FE021397CB62A>I +I<12301238123E003FB612E0A316C05A168016000070C712060060140E5D5D00E0143048 +14705D5DC712014A5A4AC7FC1406140E5CA25C1478147014F05C1301A213035C1307A213 +0FA3131F5CA2133FA5137FA96DC8FC131E233A7BB72A>II<121C127FEAFF80A5EA7F00121CC7FCB2121C127FEAFF80A5EA7F00121C092479A317> +58 D64 D<1538A3157CA315FEA34A7EA34A6C7EA202077FEC063FA2020E7F +EC0C1FA2021C7FEC180FA202387FEC3007A202707FEC6003A202C07F1501A2D901807F81 +A249C77F167FA20106810107B6FCA24981010CC7121FA2496E7EA3496E7EA3496E7EA213 +E0707E1201486C81D80FFC02071380B56C90B512FEA3373C7DBB3E>II<913A01FF800180020FEBE003027F13F8903A01FF807E07903A03FC000F0FD90FF0EB +039F4948EB01DFD93F80EB00FF49C8127F01FE153F12014848151F4848150FA248481507 +A2485A1703123F5B007F1601A35B00FF93C7FCAD127F6DED0180A3123F7F001F16031800 +6C7E5F6C7E17066C6C150E6C6C5D00001618017F15386D6C5CD91FE05C6D6CEB03C0D903 +FCEB0F80902701FF803FC7FC9039007FFFFC020F13F002011380313D7BBA3C>IIIIIII<013FB512E0A39039001FFC +00EC07F8B3B3A3123FEA7F80EAFFC0A44A5A1380D87F005B0070131F6C5C6C495A6C49C7 +FC380781FC3801FFF038007F80233B7DB82B>I +76 DIIIIIII<003FB812E0A3D9C003EB001F273E0001FE130348EE01F00078160000 +701770A300601730A400E01738481718A4C71600B3B0913807FF80011FB612E0A335397D +B83C>III<007FB590383FFFFCA3C6 +01F801071380D97FE0D903FCC7FC013FEC01F06D6C5C5F6D6C5C6D6C13034CC8FC6D6C13 +06160E6D6C5B6DEB8018163891387FC0306E6C5A16E06E6C5A91380FF18015FB6EB4C9FC +5D14036E7EA26E7F6F7EA24B7E15DF9138019FF09138038FF8150F91380607FC91380E03 +FE140C4A6C7EEC38000230804A6D7E14E04A6D7E49486D7E130391C76C7E01066E7E130E +010C6E7E011C1401013C8101FE822607FF80010713E0B500E0013FEBFF80A339397EB83E +>88 DI<003FB7FCA39039FC0001FE01 +C0130349495A003EC7FC003C4A5A5E0038141F00784A5A12704B5A5E006014FF4A90C7FC +A24A5A5DC712074A5AA24A5A5D143F4A5AA24A5A92C8FC5B495AA2495A5C130F4948EB01 +80A2495A5C137F495A16034890C7FC5B1203485AEE0700485A495C001F5D48485C5E4848 +495A49130FB8FCA329397BB833>I<007FB81280B912C0A26C17803204797041>95 +D97 DIIII<147E903803FF8090380FC1E0EB1F8790 +383F0FF0137EA213FCA23901F803C091C7FCADB512FCA3D801F8C7FCB3AB487E387FFFF8 +A31C3B7FBA19>IIII< +EB01C0EB07F0EB0FF8A5EB07F0EB01C090C7FCAAEB01F813FFA313071301B3B3A2123C12 +7E00FF13F01303A214E038FE07C0127C383C0F00EA0FFEEA03F8154984B719>III<2703F00FF0EB1FE000FFD93FFCEB7FF8913AF03F01E0 +7E903BF1C01F83803F3D0FF3800FC7001F802603F70013CE01FE14DC49D907F8EB0FC0A2 +495CA3495CB3A3486C496CEB1FE0B500C1B50083B5FCA340257EA445>I<3903F00FF000 +FFEB3FFCECF03F9039F1C01F803A0FF3800FC03803F70013FE496D7EA25BA35BB3A3486C +497EB500C1B51280A329257EA42E>II<3903F01FE000FFEB7FF89038 +F1E07E9039F3801F803A07F7000FC0D803FEEB07E049EB03F04914F849130116FC150016 +FEA3167FAA16FEA3ED01FCA26DEB03F816F06D13076DEB0FE001F614C09039F7803F0090 +38F1E07E9038F0FFF8EC1FC091C8FCAB487EB512C0A328357EA42E>II<3807E01F00 +FFEB7FC09038E1E3E09038E387F0380FE707EA03E613EE9038EC03E09038FC0080491300 +A45BB3A2487EB512F0A31C257EA421>II<1318A51338A31378A313F8120112031207001FB5FCB6FC +A2D801F8C7FCB215C0A93800FC011580EB7C03017E13006D5AEB0FFEEB01F81A347FB220 +>IIIIII<003FB512FCA2EB8003D83E0013F8003CEB07F00038EB0FE012300070EB +1FC0EC3F800060137F150014FE495AA2C6485A495AA2495A495A495AA290387F000613FE +A2485A485A0007140E5B4848130C4848131CA24848133C48C7127C48EB03FC90B5FCA21F +247EA325>I E +%EndDVIPSBitmapFont +end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 600dpi +TeXDict begin +%%BeginPaperSize: Letter +letter +%%EndPaperSize + +%%EndSetup +%%Page: 1 1 +1 0 bop 0 162 a Fg(11)17 b(11)h(T)249 180 y(E)295 162 +y(X)h(L)398 145 y Ff(A)435 162 y Fg(T)481 180 y(E)527 +162 y(X)0 353 y Fe(Using)54 b(Libical)p 0 467 3900 24 +v 0 580 a Fg(Eric)28 b(Busb)r(o)r(om)f(\(eric@soft)n(w)n +(arestudio.org\))1921 b(Jan)n(uary)25 b(2000)0 1217 y +Fd(1)131 b(In)l(tro)t(duction)0 1456 y Fg(Libical)23 +b(is)f(an)h(Op)r(en)g(Source)f(implemen)n(tation)h(of)g(the)g +(iCalendar)f(proto)r(cols)f(and)i(proto)r(col)e(data)i(units.)35 +b(The)23 b(iCalendar)0 1570 y(sp)r(eci\034cation)k(describ)r(es)g(ho)n +(w)f(calendar)g(clien)n(ts)i(can)f(comm)n(unicate)f(with)i(calendar)e +(serv)n(ers)f(for)i(users)g(can)g(store)f(their)0 1683 +y(calendar)g(data)h(and)h(arrange)d(meetings)i(with)h(other)f(users.)0 +1840 y(Libical)g(implemen)n(ts)h(the)g(follo)n(wing)e(sp)r +(eci\034cations)h(and)h(proto)r(cols)0 1996 y(iCal)f(Core)g(2445)e +(iTIP)k(2446)c(iMIP)j(2447)e(iRIP)i(draft)g(CAP)g(draft)0 +2153 y(\(The)g(curren)n(t)f(v)n(ersion,)f(0.15,)g(do)r(es)h(not)h +(implemen)n(t)g(iRip)g(or)e(CAP)-7 b(.)29 b(\))0 2309 +y(This)j(do)r(cumen)n(tation)g(assumes)g(that)g(y)n(ou)g(are)f +(familiar)h(with)h(the)f(iCalendar)f(standards)g(RF)n(C2445)g(and)h(RF) +n(C2446.)0 2423 y(these)c(sp)r(eci\034cations)e(are)h(online)g(on)h +(the)g(CALSCH)g(w)n(ebpage)e(at:)p 0 2475 3900 4 v 0 +2617 a Fc(http://www.imc.o)o(rg)o(/ie)o(tf)o(-c)o(ale)o(nd)o(ar)o(/)p +0 2776 V 0 2996 a Fb(1.1)112 b(The)38 b(libical)c(pro)6 +b(ject)0 3207 y Fg(This)29 b(co)r(de)g(is)g(under)g(activ)n(e)f(dev)n +(elopmen)n(t.)40 b(If)30 b(y)n(ou)e(w)n(ould)h(lik)n(e)f(to)h(con)n +(tribute)g(to)g(the)g(pro)5 b(ject,)29 b(y)n(ou)f(can)h(con)n(tact)f +(me,)0 3320 y(Eric)g(Busb)r(o)r(om,)f(at)g(eric@soft)n(w)n +(arestudio.org.)33 b(The)27 b(pro)5 b(ject)27 b(has)g(a)g(w)n(ebpage)g +(at)332 3518 y(h)n(ttp://soft)n(w)n(arestudio.org/libical/index.h)n +(tml)0 3716 y(and)g(a)h(mailing)f(list)g(that)h(y)n(ou)f(can)g(join)h +(b)n(y)f(sending)g(the)h(follo)n(wing)f(mail:)p 0 3769 +V 0 3904 a Fc(To:)42 b(minimalist@softwa)o(re)o(st)o(udi)o(o.)o(or)o(g) +0 4017 y(Subject:)e(subscribe)g(libical)p 0 4176 V 0 +4396 a Fb(1.2)112 b(License)0 4607 y Fg(The)60 b(co)r(de)f(and)h +(data\034les)f(in)h(this)g(distribution)g(are)e(licensed)i(under)g(the) +g(Mozilla)f(Public)h(License.)133 b(See)0 4720 y(h)n +(ttp://www.mozilla.org/NPL/MPL-1.0.h)n(tml)37 b(for)j(a)h(cop)n(y)f(of) +g(the)i(license.)76 b(Alternately)-7 b(,)44 b(y)n(ou)c(ma)n(y)g(use)g +(libical)0 4834 y(under)32 b(the)g(terms)g(of)g(the)g(GNU)h(Library)d +(General)h(Public)i(License.)50 b(See)32 b(h)n(ttp://www.fsf.org/cop)n +(yleft/lesser.h)n(tml)0 4947 y(for)27 b(a)g(cop)n(y)g(of)g(the)h(LGPL.) +0 5104 y(This)j(dual)g(license)f(ensures)h(that)g(the)g(library)f(can)g +(b)r(e)i(incorp)r(orated)d(in)n(to)i(b)r(oth)g(proprietary)e(co)r(de)i +(and)f(GPL'd)i(pro-)0 5217 y(grams,)23 b(and)h(will)h(b)r(ene\034t)g +(from)f(impro)n(v)n(emen)n(ts)e(made)i(b)n(y)g(programmers)e(in)i(b)r +(oth)h(realms.)34 b(I)25 b(will)f(only)g(accept)g(c)n(hanges)0 +5331 y(in)n(to)j(m)n(y)h(v)n(ersion)e(of)h(the)h(library)e(if)i(they)g +(are)f(similarly)f(dual-licensed.)0 5615 y Fb(1.3)112 +b(Purp)s(ose)38 b(&)f(Goals)0 5844 y(1.4)112 b(Do)s(cumen)m(t)37 +b(v)m(ersion)0 6054 y Fg($Id:)g(UsingLibical.lyx,v)26 +b(1.4)h(2000/02/18)22 b(23:06:04)j(eric)i(Exp)h(eric)f($)0 +6386 y Fd(2)131 b(Building)46 b(the)e(Library)0 6624 +y Fg(Libical)37 b(uses)g(auto)r(conf)h(to)f(generate)f(mak)n(e\034les,) +k(although)c(it)i(uses)g(none)f(of)h(the)g(auto)r(conf)f(\035ags)f(to)i +(in\035uence)g(the)0 6738 y(compilation.)e(It)28 b(should)f(built)i +(with)f(no)f(adjustmen)n(ts)h(on)f(Lin)n(ux,)g(F)-7 b(reeBSD)28 +b(and)f(Solaris.)0 7069 y Fd(3)131 b(Structure)0 7308 +y Fg(The)28 b(iCal)f(calendar)f(mo)r(del)i(is)f(based)g(on)h(four)f(t)n +(yp)r(es)g(of)h(ob)5 b(jects:)36 b(comp)r(onen)n(ts,)27 +b(prop)r(erties,)g(v)-5 b(alues)27 b(and)g(parameters.)0 +7464 y(Prop)r(erties)32 b(are)f(the)i(fundamen)n(tal)f(unit)i(of)e +(information)g(in)g(iCal,)i(and)e(they)g(w)n(ork)f(a)h(bit)h(lik)n(e)f +(a)g(hash)g(en)n(try)-7 b(,)34 b(with)e(a)0 7578 y(constan)n(t)21 +b(k)n(ey)h(and)g(a)f(v)-5 b(ariable)21 b(v)-5 b(alue.)35 +b(Prop)r(erties)21 b(ma)n(y)h(also)f(ha)n(v)n(e)g(mo)r(di\034ers,)h +(called)g(parameters.)33 b(In)22 b(the)h(iCal)f(con)n(ten)n(t)0 +7691 y(line)p 0 7728 V 0 7863 a Fc(ORGANIZER;ROLE=C)o(HA)o(IR:)o(MA)o +(IL)o(TO:)o(mr)o(bi)o(g@h)o(os)o(t.)o(com)p eop +%%Page: 2 2 +2 1 bop 0 -167 3900 5 v 0 -200 a Fa(4.)73 b(Di\033erences)31 +b(F)-8 b(rom)31 b(RF)m(Cs)2732 b Fg(2)p 0 162 3900 4 +v 0 312 a(The)34 b(prop)r(ert)n(y)f(name)h(is)g("OR)n(GANIZER,")g(the)g +(v)-5 b(alue)34 b(of)h(the)f(prop)r(ert)n(y)f(is)h("mrbig@host.com")e +(and)i(the)g("R)n(OLE")0 425 y(parameter)26 b(sp)r(eci\034es)h(that)h +(Mr)g(Big)f(is)g(the)h(c)n(hair)e(of)i(the)g(meetings)f(asso)r(ciated)f +(with)i(this)g(prop)r(ert)n(y)-7 b(.)0 582 y(Comp)r(onen)n(ts)26 +b(are)f(groups)g(of)h(prop)r(erties)f(that)i(represen)n(t)e(the)i(core) +e(ob)5 b(jects)26 b(of)g(a)g(calendar)f(system,)h(suc)n(h)g(as)g(ev)n +(en)n(ts)f(or)0 695 y(timezones.)0 852 y(The)k(cen)n(tral)f(goal)g(of)h +(libical)g(is)g(to)g(parse)f(iTIP)i(data)e(in)n(to)h(an)g(in)n(ternal)f +(represen)n(tation)g(of)h(Comp)r(onen)n(ts,)g(Prop)r(erties,)0 +965 y(P)n(arameters)d(an)h(V)-7 b(alues,)27 b(and)h(to)f(allo)n(w)g +(the)h(user)f(to)g(manipulate)g(the)h(data)g(in)f(v)-5 +b(arious)27 b(w)n(a)n(ys)0 1257 y Fb(3.1)112 b(Comp)s(onen)m(ts)0 +1486 y(3.2)g(Prop)s(erties)0 1715 y(3.3)g(V)-9 b(alues)0 +1944 y(3.4)112 b(P)m(arameters)0 2173 y(3.5)g(En)m(umerations)0 +2402 y(3.6)g(T)m(yp)s(es)0 2631 y(3.7)g(The)38 b(P)m(arser)0 +2860 y(3.8)112 b(Restrictions)0 3089 y(3.9)g(Memory)37 +b(Managemen)m(t)0 3356 y Fd(4)131 b(Di\033erences)44 +b(F)-11 b(rom)43 b(RF)l(Cs)0 3594 y Fg(Libical)c(has)f(b)r(een)h +(designed)g(to)f(follo)n(w)h(the)g(standards)e(as)i(closely)f(as)g(p)r +(ossible,)j(so)e(that)g(the)g(k)n(ey)f(ob)5 b(jects)39 +b(in)g(the)0 3708 y(standards)30 b(are)g(also)g(k)n(eey)g(ob)5 +b(jects)31 b(in)h(the)f(library)-7 b(.)47 b(Ho)n(w)n(ev)n(er,)30 +b(there)h(are)f(a)h(few)g(areas)e(where)i(the)h(sp)r(eci\034cations)e +(are)0 3821 y(\(arguably\))g(irregular,)h(and)g(follo)n(wing)g(them)h +(exactly)f(w)n(ould)g(result)h(in)g(an)f(unfriendly)h(in)n(terface.)49 +b(These)31 b(deviations)0 3935 y(mak)n(e)c(libical)g(easier)f(to)i(use) +f(b)n(y)h(main)n(taining)e(a)h(self-similar)g(in)n(terface.)0 +4227 y Fb(4.1)112 b(Pseudo)38 b(Comp)s(onen)m(ts)0 4437 +y Fg(Libical)g(de\034nes)g(comp)r(onen)n(ts)g(for)g(groups)f(of)i(prop) +r(erties)e(that)i(lo)r(ok)e(and)i(act)f(lik)n(e)g(comp)r(onen)n(ts,)i +(but)f(are)f(not)g(de-)0 4550 y(\034ned)c(as)f(comp)r(onen)n(ts)g(in)h +(the)g(sp)r(eci\034cation.)54 b(XD)n(A)-7 b(YLIGHT)35 +b(and)e(XST)-7 b(AND)n(ARD)36 b(are)c(notable)h(examples.)54 +b(These)0 4664 y(pseudo)23 b(comp)r(onen)n(ts)g(group)g(prop)r(erties)g +(within)h(the)g(VTIMEZONE)h(comp)r(onen)n(ts.)35 b(XD)n(A)-7 +b(YLIGHT)25 b(starts)d(with)j("BE-)0 4777 y(GIN:D)n(A)-7 +b(YLIGHT")35 b(and)f(ends)g(with)g("END:D)n(A)-7 b(YLIGHT,)36 +b(just)e(lik)n(e)g(other)f(comp)r(onen)n(ts,)i(but)g(is)f(not)g +(de\034ned)g(as)f(a)0 4891 y(comp)r(onen)n(t)27 b(in)h(RF)n(C2445.)35 +b(\()28 b(See)f(RF)n(C2445,)f(page)h(61)f(\))i(In)g(Libical,)f(it)h(is) +g(a)f(comp)r(onen)n(t.)0 5047 y(There)35 b(are)g(also)g(pseudo)h(comp)r +(onen)n(ts)f(that)i(are)e(conceptually)g(deriv)n(ed)g(classess)f(of)i +(V)-9 b(ALARM.)37 b(RF)n(C2446)d(de\034nes)0 5161 y(what)d(prop)r +(erties)f(ma)n(y)g(b)r(e)h(included)g(in)g(eac)n(h)f(comp)r(onen)n(t,)i +(and)e(for)h(V)-9 b(ALARM,)31 b(the)g(set)g(of)g(prop)r(erties)f(it)h +(ma)n(y)f(ha)n(v)n(e)0 5275 y(dep)r(ends)e(on)f(the)h(v)-5 +b(alue)28 b(of)f(the)h(A)n(CTION)f(prop)r(ert)n(y)-7 +b(.)0 5431 y(F)g(or)19 b(instance,)j(if)e(a)g(V)-9 b(ALARM)20 +b(comp)r(onen)n(t)g(has)f(an)h(A)n(CTION)g(prop)r(ert)n(y)e(with)j(the) +f(v)-5 b(alue)20 b(of)g("A)n(UDIO,")f(the)h(comp)r(onen)n(t)0 +5545 y(m)n(ust)h(also)g(ha)n(v)n(e)f(an)h("A)-7 b(TT)g(A)n(CH")21 +b(prop)r(ert)n(y)-7 b(.)34 b(Ho)n(w)n(ev)n(er,)20 b(if)i(the)g(A)n +(CTION)f(v)-5 b(alue)21 b(is)g("DISPLA)-7 b(Y,")22 b(the)g(comp)r(onen) +n(t)f(m)n(ust)0 5658 y(ha)n(v)n(e)26 b(a)i(DESCRIPTION)g(prop)r(ert)n +(y)-7 b(.)p eop +%%Page: 3 3 +3 2 bop 0 -167 3900 5 v 0 -200 a Fa(5.)73 b(Implemen)m(tation)29 +b(Limitations)2539 b Fg(3)0 162 y(T)-7 b(o)28 b(handle)g(these)g(v)-5 +b(arious,)27 b(complex)h(restrictions,)f(libical)h(has)g(pseudo)g(comp) +r(onen)n(ts)f(for)h(eac)n(h)f(t)n(yp)r(e)i(of)f(alarm:)37 +b(XA)n(U-)0 275 y(DIO)n(ALARM,)28 b(XDISPLA)-7 b(Y)g(ALARM,)30 +b(XEMAILALARM)f(and)f(XPR)n(OCEDUREALARM.)0 567 y Fb(4.2)112 +b(Com)m(bined)37 b(V)-9 b(alues)0 777 y Fg(Man)n(y)34 +b(v)-5 b(alues)34 b(can)g(tak)n(e)g(more)g(than)g(one)h(t)n(yp)r(e.)58 +b(TRIGGER,)35 b(for)f(instance,)i(can)e(ha)n(v)n(e)g(a)g(v)-5 +b(alue)34 b(t)n(yp)r(e)h(of)g(with)g(DU-)0 890 y(RA)-7 +b(TION)32 b(or)f(of)h(D)n(A)-7 b(TE-TIME.)33 b(These)f(m)n(ultiple)g(t) +n(yp)r(es)g(mak)n(e)f(it)i(di\036cult)g(to)e(create)g(routines)h(to)f +(return)h(the)g(v)-5 b(alue)0 1004 y(asso)r(ciated)26 +b(with)i(a)f(prop)r(ert)n(y)-7 b(.)0 1161 y(It)30 b(is)g(natural)g(to)f +(ha)n(v)n(e)g(in)n(terfaces)g(that)i(w)n(ould)e(return)h(the)g(v)-5 +b(alue)30 b(of)g(a)g(prop)r(ert)n(y)-7 b(,)29 b(but)i(it)f(is)g(cum)n +(b)r(ersone)f(for)h(a)g(single)0 1274 y(routine)i(to)g(return)g(m)n +(ultiple)h(t)n(yp)r(es.)51 b(So,)33 b(in)g(libical,)g(prop)r(erties)e +(that)i(can)f(ha)n(v)n(e)f(m)n(ultiple)i(t)n(yp)r(es)f(are)f(giv)n(en)h +(a)g(single)0 1388 y(t)n(yp)r(e)26 b(that)g(is)g(the)g(union)g(of)g +(their)g(RF)n(C2445)e(t)n(yp)r(es.)36 b(F)-7 b(or)26 +b(instance,)g(in)g(libical,)g(the)g(v)-5 b(alue)26 b(of)g(the)g +(TRIGGER)h(prop)r(ert)n(y)0 1501 y(resolv)n(es)e(to)j(struct)f +(icaltriggert)n(yp)r(e.)35 b(This)28 b(t)n(yp)r(e)f(is)h(a)f(union)h +(of)f(a)g(DURA)-7 b(TION)29 b(and)e(a)g(D)n(A)-7 b(TE-TIME.)0 +1793 y Fb(4.3)112 b(Multi-V)-9 b(alued)36 b(Prop)s(erties)0 +2003 y Fg(Some)31 b(prop)r(erties,)h(suc)n(h)f(as)g(CA)-7 +b(TEGORIES)33 b(ha)n(v)n(e)d(only)h(one)g(v)-5 b(alue)32 +b(t)n(yp)r(e,)h(but)f(eac)n(h)e(CA)-7 b(TEGORIES)33 b(prop)r(ert)n(y)d +(can)0 2116 y(ha)n(v)n(e)24 b(m)n(ultiple)h(v)-5 b(alue)25 +b(instances.)35 b(This)25 b(also)f(results)g(in)h(a)g(cum)n(b)r(ersome) +f(in)n(terface)g(\025)g(CA)-7 b(TEGORIES)26 b(accessors)d(w)n(ould)0 +2230 y(ha)n(v)n(e)k(to)i(return)f(a)g(list)g(while)h(all)f(other)g +(accessors)e(returned)i(a)g(single)g(v)-5 b(alue.)39 +b(In)29 b(libical,)g(all)f(prop)r(erties)f(ha)n(v)n(e)h(a)g(single)0 +2344 y(v)-5 b(alue,)35 b(and)e(m)n(ulti-v)-5 b(alued)33 +b(prop)r(erties)f(are)h(brok)n(en)f(do)n(wn)g(in)n(to)h(m)n(ultiple)h +(single)f(v)-5 b(alued)33 b(prop)r(erties)g(during)f(parsing.)0 +2457 y(That)c(is,)f(an)g(input)i(line)e(lik)n(e,)p 0 +2526 3900 4 v 0 2703 a Fc(CATEGORIES:)39 b(work,)i(home)p +0 2903 V 0 3053 a Fg(b)r(ecomes)27 b(in)h(libical's)f(in)n(ternal)g +(represen)n(tation)p 0 3122 V 0 3299 a Fc(CATEGORIES:)39 +b(work)0 3412 y(CATEGORIES:)g(home)p 0 3612 V 0 3767 +a Fg(Oddly)-7 b(,)34 b(RF)n(C2445)d(allo)n(ws)g(some)h(m)n(ulti-v)-5 +b(alued)33 b(prop)r(erties)f(\()h(lik)n(e)g(FREEBUSY)h(\))f(to)g(exist) +g(as)f(b)r(oth)h(a)f(m)n(ulti-v)-5 b(alues)0 3881 y(prop)r(ert)n(y)24 +b(and)h(as)f(m)n(ultiple)h(single)g(v)-5 b(alue)24 b(prop)r(erties,)h +(while)g(others)f(\()i(lik)n(e)e(CA)-7 b(TEGORIES)26 +b(\))f(can)g(only)g(exist)f(as)h(single)0 3994 y(m)n(ulti-v)-5 +b(alued)32 b(prop)r(erties.)48 b(This)31 b(mak)n(es)g(the)h(in)n +(ternal)f(represen)n(tation)e(for)i(CA)-7 b(TEGORIES)33 +b(illegal.)48 b(Ho)n(w)n(ev)n(er)30 b(when)0 4108 y(y)n(ou)d(con)n(v)n +(ert)f(a)h(comp)r(onen)n(t)g(to)h(a)f(string,)g(the)h(library)e(will)i +(collect)f(all)g(of)h(the)g(CA)-7 b(TEGORIES)28 b(prop)r(erties)f(in)n +(to)g(one.)0 4446 y Fd(5)131 b(Implemen)l(tation)44 b(Limitations)0 +4742 y(6)131 b(Using)44 b(libical)0 4999 y Fb(6.1)112 +b(Creating)37 b(Comp)s(onen)m(ts)0 5209 y Fg(There)e(are)g(three)h(w)n +(a)n(ys)e(to)i(create)e(comp)r(onen)n(ts)i(in)g(Libical:)53 +b(creating)34 b(individual)i(ob)5 b(jects)35 b(and)h(assem)n(bling)e +(them,)0 5323 y(building)28 b(en)n(tire)f(ob)5 b(jects)27 +b(in)h(massiv)n(e)e(v)-5 b(aargs)26 b(calls,)h(and)g(parsing)f(a)h +(text)h(\034le)g(con)n(taining)e(iCalendar)h(data.)p +eop +%%Page: 4 4 +4 3 bop 0 -167 3900 5 v 0 -200 a Fa(6.)73 b(Using)32 +b(libical)3190 b Fg(4)0 162 y Fa(6.1.1)94 b(Constructor)32 +b(In)m(terfaces)0 372 y Fg(Using)d(constructor)f(in)n(terfaces,)h(y)n +(ou)f(create)h(eac)n(h)f(of)i(the)f(ob)5 b(jects)29 b(sep)r(erately)g +(and)g(them)h(assem)n(ble)e(them)i(in)g(to)f(com-)0 485 +y(p)r(onen)n(ts:)p 0 555 3900 4 v 0 738 a Fc(event)41 +b(=)j(icalcomponent_n)o(ew)o(\(IC)o(AL)o(_V)o(EVE)o(NT)o(_C)o(OMP)o(ON) +o(EN)o(T\);)0 852 y(icalcomponent_ad)o(d_)o(pro)o(pe)o(rt)o(y\(e)o(ve)o +(nt)o(,)38 b(icalproperty_ne)o(w_)o(dts)o(ta)o(mp)o(\(at)o(im)o(e\))f +(\);)0 965 y(icalcomponent_ad)o(d_)o(pro)o(pe)o(rt)o(y\(e)o(ve)o(nt)o +(,ic)o(al)o(pr)o(ope)o(rt)o(y_)o(new)o(_u)o(id\()o(st)o(rd)o(up\()o("g) +o(ui)o(d-1)o(.h)o(os)o(t1.)o(co)o(m")o(\)\))g(\);)0 1079 +y(property=icalpro)o(pe)o(rty)o(_n)o(ew)o(_or)o(ga)o(ni)o(zer)o(\(s)o +(tr)o(dup)o(\(")o(mr)o(big)o(@h)o(ost)o(.c)o(om)o("\)\))o(;)0 +1192 y(icalproperty_add)o(_p)o(ara)o(me)o(te)o(r\(p)o(ro)o(pe)o(rty)o +(,i)o(ca)o(lpa)o(ra)o(me)o(ter)o(_n)o(ew_)o(ro)o(le)o(\(IC)o(AL)o(_R)o +(OLE)o(_C)o(HA)o(IR\))g(\);)0 1306 y(icalcomponent_ad)o(d_)o(pro)o(pe)o +(rt)o(y\(e)o(ve)o(nt)o(,pr)o(op)o(er)o(ty\))o(;)p 0 1506 +V 0 1722 a Fa(6.1.2)94 b(v)-5 b(aargs)32 b(Constructors)0 +1932 y(6.1.3)94 b(P)m(arsing)32 b(T)-8 b(ext)32 b(Files)0 +2161 y Fb(6.2)112 b(A)m(ccessing)37 b(Comp)s(onen)m(ts)0 +2371 y Fa(6.2.1)94 b(Finding)30 b(Comp)s(onen)m(ts)0 +2582 y(6.2.2)94 b(Remo)m(ving)29 b(Comp)s(onen)m(ts)0 +2792 y Fg(Remo)n(ving)23 b(an)h(elemen)n(t)h(from)f(a)g(list)g(while)h +(iterating)e(through)h(the)h(list)f(can)g(cause)g(problems,)g(since)g +(y)n(ou)g(will)g(probably)0 2905 y(b)r(e)e(remo)n(ving)e(the)i(elemen)n +(t)g(that)g(the)g(in)n(ternal)f(iterator)f(p)r(oin)n(ts)i(to.)34 +b(This)22 b(will)g(result)f(in)h(the)g(iteration)f(lo)r(op)h +(terminating)0 3019 y(immediately)29 b(after)f(remo)n(ving)g(the)h +(elemen)n(t.)41 b(T)-7 b(o)28 b(a)n(v)n(oid)g(the)h(problem,)f(y)n(ou)h +(will)g(need)g(to)f(step)h(the)h(iterator)d(ahead)h(of)0 +3132 y(the)g(elemen)n(t)g(y)n(ou)e(are)h(going)f(to)i(remo)n(v)n(e,)e +(lik)n(e)h(this:)p 0 3202 V 0 3385 a Fc(for\(c)41 b(=)j +(icalcomponent_g)o(et)o(_fi)o(rs)o(t_)o(com)o(po)o(ne)o(nt\()o(pa)o(re) +o(nt_)o(co)o(mp,)o(IC)o(AL)o(_AN)o(Y_)o(CO)o(MPO)o(NE)o(NT)o(\);)305 +3499 y(c)f(!=)g(0;)305 3612 y(c)g(=)g(next)0 3726 y({)174 +3839 y(next)f(=)h(icalcomponent_get)o(_n)o(ex)o(t_c)o(om)o(po)o(nen)o +(t\()o(pa)o(ren)o(t_)o(com)o(p,)o(IC)o(AL_)o(AN)o(Y_)o(COM)o(PO)o(NE)o +(NT\))o(;)174 3953 y(icalcomponent_rem)o(ov)o(e_)o(com)o(po)o(ne)o +(nt\()o(pa)o(re)o(nt_)o(co)o(mp)o(,c\))o(;)0 4067 y(})p +0 4267 V eop +%%Page: 5 5 +5 4 bop 0 -167 3900 5 v 0 -200 a Fa(6.)73 b(Using)32 +b(libical)3190 b Fg(5)0 162 y Fa(6.2.3)94 b(Finding)30 +b(Prop)s(erties)0 372 y(6.2.4)94 b(Remo)m(ving)29 b(Prop)s(erties)0 +582 y(6.2.5)94 b(Getting)31 b(V)-8 b(alues)0 792 y(6.2.6)94 +b(Setting)31 b(V)-8 b(alues)0 1002 y(6.2.7)94 b(Getting)31 +b(P)m(arameters)0 1212 y(6.2.8)94 b(Setting)31 b(P)m(arameters)0 +1422 y(6.2.9)94 b(Remo)m(ving)29 b(P)m(arameters)0 1632 +y(6.2.10)93 b(Chec)m(king)32 b(Comp)s(onen)m(t)e(V)-8 +b(alidit)m(y)0 1861 y Fb(6.3)112 b(Storing)37 b(Ob)6 +b(jects)0 2071 y Fg(The)27 b(libical)g(distribution)h(inclues)f(a)g +(sep)r(erate)f(library)-7 b(,)26 b(libicalss,)h(that)g(allo)n(ws)f(y)n +(ou)g(to)i(store)e(iCal)h(comp)r(onen)n(t)g(data)f(to)0 +2185 y(disk)h(in)h(a)f(v)-5 b(ariet)n(y)27 b(of)h(w)n(a)n(ys.)35 +b(This)27 b(library)g(is)g(do)r(cumen)n(ted)h(sep)r(erately)-7 +b(.)0 2476 y Fb(6.4)112 b(Memory)37 b(Managemen)m(t)0 +2686 y Fg(Libical)25 b(relies)f(hea)n(vily)g(on)h(dynamic)g(allo)r +(cation)f(for)h(b)r(oth)h(the)f(core)f(ob)5 b(jects)25 +b(and)g(for)f(the)i(strings)e(used)h(to)g(hold)g(v)-5 +b(alues.)0 2800 y(Some)34 b(of)f(this)h(memory)f(the)h(library)f +(caller)g(o)n(wns)g(and)g(m)n(ust)h(free,)h(and)f(some)f(of)h(the)g +(memory)f(is)h(managed)e(b)n(y)i(the)0 2914 y(library)-7 +b(.)36 b(Here)27 b(is)g(a)g(summary)g(of)h(the)g(memory)e(rules.)0 +3153 y Fa(1\))208 3300 y Fg(If)k(the)g(function)g(name)g(has)f +Fc(")p Fg(new)p Fc(")g Fg(in)h(it,)h(the)f(caller)f(gets)g(con)n(trol)g +(of)h(the)g(memory)-7 b(.)42 b(\()31 b(suc)n(h)e(as)g(icalcomp)r(onen-) +208 3413 y(t_new\(\),)f(or)e(icalprop)r(ert)n(y_new_clone\(\))f(\))0 +3593 y Fa(2\))208 3740 y Fg(If)j(y)n(ou)g(got)g(the)h(memory)f(from)g +(a)g(routine)g(with)h(new)f(in)h(it,)g(y)n(ou)f(m)n(ust)h(call)f(the)h +(corresp)r(onding)d(*_free)i(routine)208 3854 y(to)f(free)g(the)h +(memory)-7 b(.)36 b(\()28 b(Use)g(icalcomp)r(onen)n(t_free\(\))e(to)i +(free)f(ob)5 b(jects)27 b(created)g(with)h(icalcomp)r(onen)n +(t_new\(\)\))0 4034 y Fa(3\))208 4181 y Fg(If)h(the)g(function)g(name)f +(has)g Fc(")p Fg(add)p Fc(")g Fg(in)h(it,)g(the)g(caller)e(is)i +(transfering)e(con)n(trol)g(of)i(the)g(memory)f(to)g(the)h(routine.)40 +b(\()208 4294 y(icalprop)r(ert)n(y_add_parameter\(\))23 +b(\))0 4474 y Fa(4\))208 4621 y Fg(If)29 b(the)h(function)g(name)f(has) +g Fc(")p Fg(remo)n(v)n(e)p Fc(")e Fg(in)j(it,)g(the)g(caller)f(passes)f +(in)i(a)f(p)r(oin)n(ter)g(to)g(an)g(ob)5 b(ject)29 b(and)h(after)f(the) +g(call)208 4735 y(returns,)j(the)h(caller)e(o)n(wns)g(the)h(ob)5 +b(ject.)50 b(So,)33 b(b)r(efore)f(y)n(ou)f(call)h(icalcomp)r(onen)n +(t_remo)n(v)n(e_prop)r(ert)n(y\(comp,fo)r(o\),)208 4848 +y(y)n(ou)26 b(do)i(not)f(o)n(wn)g Fc(")p Fg(fo)r(o)p +Fc(")g Fg(and)g(after)g(the)h(call)f(returns,)g(y)n(ou)g(do.)0 +5028 y Fa(5\))208 5175 y Fg(If)d(the)g(routine)f(returns)g(a)g(string,) +h(libical)g(o)n(wns)f(the)h(memory)f(and)g(will)h(put)g(it)h(on)e(a)g +(ring)g(bu\033er)h(to)g(reclaim)f(later.)208 5288 y(Y)-7 +b(ou'd)27 b(b)r(etter)h(strdup\(\))g(it)g(if)g(y)n(ou)f(w)n(an)n(t)g +(to)h(k)n(eep)f(it,)h(and)f(y)n(ou)g(don't)h(ha)n(v)n(e)e(to)h(delete)h +(it.)0 5580 y Fb(6.5)112 b(Error)36 b(Handling)0 5790 +y Fg(icalerror_errno.)c(Return)c(v)-5 b(alues.)37 b(#de\034nes.)g +(icalerror_stop_here)p eop +%%Page: 6 6 +6 5 bop 0 -167 3900 5 v 0 -200 a Fa(7.)73 b(Useful)32 +b(Recipies)3067 b Fg(6)0 162 y Fa(6.5.1)94 b(Return)31 +b(v)-5 b(alues)0 372 y(6.5.2)94 b(icalerrno)0 582 y(6.5.3)g(Comp)s +(onen)m(t)29 b(errors)0 811 y Fb(6.6)112 b(Naming)36 +b(Standard)0 1021 y Fg(Structures)26 b(that)i(y)n(ou)e(access)f(with)j +(the)f("struct")f(k)n(eyw)n(ord,)f(suc)n(h)h(as)h("struct)f(icaltimet)n +(yp)r(e")g(are)g(things)h(that)g(y)n(ou)f(are)0 1134 +y(allo)n(w)n(ed)g(to)i(see)f(inside)g(and)h(p)r(ok)n(e)f(at.)0 +1291 y(Structures)33 b(that)h(y)n(ou)e(access)g(though)i(a)f(t)n(yp)r +(edef,)i(suc)n(h)e(as)g("icalcomp)r(onen)n(t")e(are)i(things)g(where)g +(all)g(of)h(the)f(data)g(is)0 1405 y(hidden.)0 1561 y(Comp)r(onen)n(t) +28 b(names)g(that)h(start)f(with)h("V")f(are)f(part)h(of)h(RF)n(C)f +(2445)f(or)g(another)h(iCal)g(standard.)38 b(Comp)r(onen)n(t)29 +b(names)0 1675 y(that)h(start)f(with)i("X")e(are)g(also)g(part)g(of)h +(the)g(sp)r(ec,)g(but)h(they)f(are)f(not)h(actually)f(comp)r(onen)n(ts) +g(in)h(the)g(sp)r(ec.)44 b(Ho)n(w)n(ev)n(er,)0 1788 y(they)34 +b(lo)r(ok)f(and)g(act)h(lik)n(e)f(comp)r(onen)n(ts,)h(so)f(they)h(are)f +(comp)r(onen)n(ts)g(in)h(libical.)55 b(Names)33 b(that)h(start)f(with)h +("XLIC")f(or)0 1902 y("X-LIC")26 b(are)h(not)h(part)f(of)g(an)n(y)g +(iCal)g(sp)r(ec.)37 b(They)27 b(are)g(used)h(in)n(ternally)e(b)n(y)i +(libical.)0 2058 y(En)n(ums)d(that)f(iden)n(tify)h(a)f(comp)r(onen)n +(t,)h(prop)r(ert)n(y)-7 b(,)24 b(v)-5 b(alue)24 b(or)g(parameter)e(end) +j(with)g("_COMPONENT,")e("_PR)n(OPER-)0 2172 y(TY,")k("_V)-9 +b(ALUE,")28 b(or)e("_P)-7 b(AAMETER"s)0 2328 y(En)n(ums)31 +b(that)f(iden)n(tify)h(a)f(parameter)f(v)-5 b(alue)30 +b(ha)n(v)n(e)f(the)i(name)f(of)h(the)f(parameter)f(as)h(the)h(second)e +(w)n(ord.)45 b(F)-7 b(or)29 b(instance:)0 2442 y(ICAL_R)n(OLE_REQP)-7 +b(AR)g(TICIP)g(ANT)29 b(or)d(ICAL_P)-7 b(AR)g(TST)g(A)g(T_A)n(CCEPTED.) +0 2598 y(The)28 b(en)n(ums)f(for)g(the)h(parts)f(of)g(a)g(recurarance)e +(rule)j(and)f(request)g(statuses)g(are)f(irregular.)0 +2937 y Fd(7)131 b(Useful)44 b(Recipies)0 3175 y Fg(Iteration)0 +3332 y(Cop)n(ying)26 b(comp)r(onen)n(ts.)37 b(Remem)n(b)r(er)27 +b(that)h(y)n(ou)f(m)n(ust)g(clone)g(or)g(remo)n(v)n(e)f(an)h(ob)5 +b(ject)28 b(b)r(efore)f(putting)h(in)g(on)f(anothr)g(list.)0 +3488 y(Finding)h(compliance)f(errors)0 3827 y Fd(8)131 +b(P)l(erformance)0 4065 y Fg(Chec)n(king)27 b(restrictions)f(is)h +(computationally)g(exp)r(ensiv)n(e)0 4404 y Fd(9)131 +b(Hac)l(ks)45 b(and)e(Bugs)p eop +%%Trailer +end +userdict /end-hook known{end-hook}if +%%EOF diff --git a/libical/missing b/libical/missing new file mode 100755 index 0000000000..7789652e87 --- /dev/null +++ b/libical/missing @@ -0,0 +1,190 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright (C) 1996, 1997 Free Software Foundation, Inc. +# Franc,ois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing - GNU libit 0.0" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`configure.in'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`configure.in'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acconfig.h' or \`configure.in'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequirements for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 diff --git a/libical/mkinstalldirs b/libical/mkinstalldirs new file mode 100644 index 0000000000..09c7184cfa --- /dev/null +++ b/libical/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id: mkinstalldirs,v 1.1 2000/04/18 18:17:02 alves Exp $ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" 1>&2 + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here \ No newline at end of file diff --git a/libical/scripts/.cvsignore b/libical/scripts/.cvsignore new file mode 100644 index 0000000000..70845e08eb --- /dev/null +++ b/libical/scripts/.cvsignore @@ -0,0 +1 @@ +Makefile.in diff --git a/libical/scripts/Makefile.am b/libical/scripts/Makefile.am new file mode 100644 index 0000000000..fd1b053cb6 --- /dev/null +++ b/libical/scripts/Makefile.am @@ -0,0 +1,8 @@ +EXTRA_DIST = \ +mkderivedcomponents.pl \ +mkderivedparameters.pl \ +mkderivedproperties.pl \ +mkderivedvalues.pl \ +mkparameterrestrictions.pl \ +mkrestrictionrecords.pl \ +mkrestrictiontable.pl diff --git a/libical/scripts/mkderivedcomponents.pl b/libical/scripts/mkderivedcomponents.pl index 3599a8d465..ac4e472250 100755 --- a/libical/scripts/mkderivedcomponents.pl +++ b/libical/scripts/mkderivedcomponents.pl @@ -1,7 +1,7 @@ #!/usr/local/bin/perl use Getopt::Std; -getopts('chsp'); +getopts('chspi:'); # ARG 0 is components.txt @@ -11,6 +11,8 @@ my @components; while (){ + s/#.*//; + chop; push(@components,$_); @@ -19,7 +21,32 @@ while (){ close PV; -if ($opt_c or $opt_h){ +# Write the file inline by copying everything before a demarcation +# line, and putting the generated data after the demarcation + +if ($opt_i) { + + open(IN,$opt_i) || die "Can't open input file \"$opt_i\""; + + while(){ + + if (/Do not edit/){ + last; + } + + print; + + } + + if($opt_i){ + print "# Everything below this line is machine generated. Do not edit. \n"; + } else { + print "/* Everything below this line is machine generated. Do not edit. */\n"; + } + +} + +if ($opt_c or $opt_h and !$opt_i){ print <){ my $set_code; my $pointer_check; my $new_pointer_check; + my $new_pointer_check_v; + my $xrange; - $new_pointer_check = "icalerror_check_arg_rz( (v!=0),\"v\");" if $type=~/char/; + if ($type=~/char/){ + $new_pointer_check = "icalerror_check_arg_rz( (v!=0),\"v\");"; + $new_pointer_check_v = "icalerror_check_arg_rv( (v!=0),\"v\");"; + } if ($type=~/char/ ) { @@ -177,7 +186,7 @@ $charorenum void icalparameter_set_${lc}(icalparameter* param, ${type} v) { - $new_pointer_check + $new_pointer_check_v icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -215,8 +224,8 @@ EOM # $param -package ICal::Parameter::${ucf}; -\@ISA=qw(ICal::Parameter); +package Net::ICal::Parameter::${ucf}; +\@ISA=qw(Net::ICal::Parameter); sub new { @@ -226,14 +235,15 @@ sub new bless \$self, \$package; - my \$p = ICal::icalparameter_new(\$ICal::ICAL_${uc}_PARAMETER); - - \$self->[0] = \$p; + my \$p; if (\$value) { - \$self->set(\$value); + \$p = Net::ICal::icalparameter_new_from_string(\$Net::ICal::ICAL_${uc}_PARAMETER,\$value); + } else { + \$p = Net::ICal::icalparameter_new(\$Net::ICal::ICAL_${uc}_PARAMETER); } + \$self->[0] = \$p; return \$self; } @@ -243,19 +253,14 @@ sub get my \$self = shift; my \$impl = \$self->_impl(); - return ICal::icalparameter_as_ical_string(\$impl); + return Net::ICal::icalparameter_as_ical_string(\$impl); } sub set { - - my \$self = shift; - my \$v = shift; - - my \$impl = \$self->_impl(); - - ICal::icalparameter_set_${lc}(\$impl,\$v) unless !\$v; + # This is hard to implement, so I've punted for now. + die "Set is not implemented"; } EOM diff --git a/libical/src/Makefile.am b/libical/src/Makefile.am index ef64080346..37dc5e39cb 100644 --- a/libical/src/Makefile.am +++ b/libical/src/Makefile.am @@ -1 +1 @@ -SUBDIRS = libical libicalss +SUBDIRS = libical libicalss test diff --git a/libical/src/libical/.cvsignore b/libical/src/libical/.cvsignore index 9dc64874d6..3bd9f3bca3 100644 --- a/libical/src/libical/.cvsignore +++ b/libical/src/libical/.cvsignore @@ -3,6 +3,9 @@ Makefile.in icalitipy.c icalitipy.h icalitipl.c +icallexer.c +icalyacc.c +icalyacc.h *.lo *.la .libs diff --git a/libical/src/libical/Makefile.am b/libical/src/libical/Makefile.am index 4e74c8c207..54c66b58ec 100644 --- a/libical/src/libical/Makefile.am +++ b/libical/src/libical/Makefile.am @@ -1,39 +1,85 @@ -lib_LTLIBRARIES = libical.la - -CFLAGS=-g - -libical_la_SOURCES = \ - ical.h \ - icalcomponent.c \ - icalcomponent.h \ - icalenums.c \ - icalenums.h \ - icalerror.c \ - icalerror.h \ - icalirip.h \ - icalitipy.y \ - icalitipl.l \ - icalmemory.c \ - icalmemory.h \ - icalparameter.c \ - icalparameter.h \ - icalparser.c \ - icalparser.h \ - icalproperty.c \ - icalproperty.h \ - icalrestriction.c \ - icalrestriction.h \ - icaltypes.c \ - icaltypes.h \ - icalvalue.c \ - icalvalue.h \ - icalvcal.h \ - locking.c \ - pvl.c \ +#AUTOMAKE_OPTIONS = no-dependencies + +#noinst_LTLIBRARIES = libical.la +lib_LIBRARIES = libical.a + +YFLAGS =-d -v -t + +libical_a_SOURCES = \ + ical.h \ + icalcomponent.c \ + icalcomponent.h \ + icalenums.c \ + icalenums.h \ + icalerror.c \ + icalerror.h \ + icalyacc.y \ + icallexer.l \ + icalmemory.c \ + icalmemory.h \ + icalparameter.c \ + icalparameter.h \ + icalparser.c \ + icalparser.h \ + icalproperty.c \ + icalproperty.h \ + icalrestriction.c \ + icalrestriction.h \ + icaltypes.c \ + icaltypes.h \ + icalvalue.c \ + icalvalue.h \ + icalvcal.h \ + pvl.c \ + pvl.h + +include_HEADERS=\ + ical.h \ + icalcomponent.h \ + icalenums.h \ + icalerror.h \ + icalmemory.h \ + icalparameter.h \ + icalparser.h \ + icalproperty.h \ + icalrestriction.h \ + icaltypes.h \ + icalvalue.h \ + icalvcal.h \ + icalversion.h \ pvl.h -EXTRA_DIST = .gdbinit base64.c filelock.c filelock.h -YFLAGS=-picalparser_yy -d -LFLAGS=-Picalparser_yy -olex.yy.c + +EXTRA_DIST = icallexer.c icalyacc.c icalyacc.h + +CONFIG_CLEAN_FILES = y.output *~ + +DESIGNDATA = ../../design-data +ICALSCRIPTS = ../../scripts +derived: icalproperty icalparameter icalvalue + +icalproperty: + $(ICALSCRIPTS)/mkderivedproperties.pl -i icalproperty.h -h $(DESIGNDATA)/prop-to-value.txt ${DESIGNDATA}/value-c-types.txt > icalproperty.newh + mv icalproperty.newh icalproperty.h + + $(ICALSCRIPTS)/mkderivedproperties.pl -i icalproperty.c -c $(DESIGNDATA)/prop-to-value.txt ${DESIGNDATA}/value-c-types.txt > icalproperty.newc + mv icalproperty.newc icalproperty.c + + +icalparameter: + $(ICALSCRIPTS)/mkderivedparameters.pl -i icalparameter.h -h $(DESIGNDATA)/param-c-types.txt > icalparameter.newh + mv icalparameter.newh icalparameter.h + + $(ICALSCRIPTS)/mkderivedparameters.pl -i icalparameter.c -c $(DESIGNDATA)/param-c-types.txt > icalparameter.newc + mv icalparameter.newc icalparameter.c + +icalvalue: + $(ICALSCRIPTS)/mkderivedvalues.pl -i icalvalue.h -h $(DESIGNDATA)/value-c-types.txt > icalvalue.newh + mv icalvalue.newh icalvalue.h + + $(ICALSCRIPTS)/mkderivedvalues.pl -i icalvalue.c -c $(DESIGNDATA)/value-c-types.txt > icalvalue.newc + mv icalvalue.newc icalvalue.c + + diff --git a/libical/src/libical/ical.h b/libical/src/libical/ical.h index cd5ca31dd5..d0f33cd1a1 100644 --- a/libical/src/libical/ical.h +++ b/libical/src/libical/ical.h @@ -25,6 +25,7 @@ #ifndef ICAL_H #define ICAL_H +#include "icalversion.h" #include "icalenums.h" #include "icalvalue.h" #include "icalparameter.h" @@ -36,7 +37,6 @@ #include "icalerror.h" #include "icalrestriction.h" - #endif /* !ICAL_H */ diff --git a/libical/src/libical/icalcomponent.c b/libical/src/libical/icalcomponent.c index a1a2535e7a..bd2b13189c 100644 --- a/libical/src/libical/icalcomponent.c +++ b/libical/src/libical/icalcomponent.c @@ -24,6 +24,11 @@ ======================================================================*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "ical.h" #include "pvl.h" /* "Pointer-to-void list" */ #include /* for malloc */ @@ -35,6 +40,8 @@ #include "icalmemory.h" #include "icalenums.h" +#define MAX_TMP 1024 + /* icalproperty functions that only components get to use */ void icalproperty_set_parent(icalproperty* property, @@ -85,7 +92,6 @@ icalcomponent_new_impl (icalcomponent_kind kind) if ( ( comp = (struct icalcomponent_impl*) malloc(sizeof(struct icalcomponent_impl))) == 0) { - errno = ENOMEM; icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } @@ -236,6 +242,12 @@ icalcomponent_as_ical_string (icalcomponent* component) char* tmp_buf; size_t buf_size = 1024; char* buf_ptr = 0; + +#ifdef ICAL_UNIX_NEWLINE + char newline[] = "\n"; +#else + char newline[] = "\r\n"; +#endif icalcomponent *c; icalproperty *p; @@ -255,7 +267,7 @@ icalcomponent_as_ical_string (icalcomponent* component) icalmemory_append_string(&buf, &buf_ptr, &buf_size, "BEGIN:"); icalmemory_append_string(&buf, &buf_ptr, &buf_size, kind_string); - icalmemory_append_string(&buf, &buf_ptr, &buf_size, "\n"); + icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); for(p = icalcomponent_get_first_property(component,ICAL_ANY_PROPERTY); @@ -281,7 +293,7 @@ icalcomponent_as_ical_string (icalcomponent* component) icalmemory_append_string(&buf, &buf_ptr, &buf_size, "END:"); icalmemory_append_string(&buf, &buf_ptr, &buf_size, icalenum_component_kind_to_string(kind)); - icalmemory_append_string(&buf, &buf_ptr, &buf_size, "\n"); + icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); out_buf = icalmemory_tmp_copy(buf); free(buf); @@ -680,9 +692,79 @@ void icalcomponent_strip_errors(icalcomponent* component) icalcomponent_strip_errors(c); } +} + + +void icalcomponent_convert_errors(icalcomponent* component) +{ + icalproperty *p, *next_p; + icalcomponent *c; + + for(p = icalcomponent_get_first_property(component,ICAL_ANY_PROPERTY); + p != 0; + p = next_p){ + + next_p = icalcomponent_get_next_property(component,ICAL_ANY_PROPERTY); + + if(icalproperty_isa(p) == ICAL_XLICERROR_PROPERTY) + { + struct icalreqstattype rst; + char tmp[MAX_TMP]; + icalparameter *param = icalproperty_get_first_parameter + (p,ICAL_XLICERRORTYPE_PARAMETER); + + rst.code = ICAL_UNKNOWN_STATUS; + rst.desc = 0; + + switch(icalparameter_get_xlicerrortype(param)){ + + case ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR: { + rst.code = ICAL_3_2_INVPARAM_STATUS; + break; + } + case ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR: { + rst.code = ICAL_3_3_INVPARAMVAL_STATUS; + break; + } + case ICAL_XLICERRORTYPE_PROPERTYPARSEERROR: { + rst.code = ICAL_3_0_INVPROPNAME_STATUS; + break; + } + case ICAL_XLICERRORTYPE_VALUEPARSEERROR: { + rst.code = ICAL_3_1_INVPROPVAL_STATUS; + break; + } + case ICAL_XLICERRORTYPE_COMPONENTPARSEERROR: { + rst.code = ICAL_3_4_INVCOMP_STATUS; + break; + } + + default: { + } + } + if (rst.code != ICAL_UNKNOWN_STATUS){ + + rst.debug = icalproperty_get_xlicerror(p); + icalcomponent_add_property(component, + icalproperty_new_requeststatus( + icalreqstattype_as_string(rst) + ) + ); + + icalcomponent_remove_property(component,p); + } + } + } + for(c = icalcomponent_get_first_component(component,ICAL_ANY_COMPONENT); + c != 0; + c = icalcomponent_get_next_component(component,ICAL_ANY_COMPONENT)){ + + icalcomponent_convert_errors(c); + } } + icalcomponent* icalcomponent_get_parent(icalcomponent* component) { struct icalcomponent_impl *c = (struct icalcomponent_impl*)component; diff --git a/libical/src/libical/icalcomponent.h b/libical/src/libical/icalcomponent.h index 9e0e9f5a9f..8d9f22ca76 100644 --- a/libical/src/libical/icalcomponent.h +++ b/libical/src/libical/icalcomponent.h @@ -101,8 +101,12 @@ icalproperty** icalcomponent_get_component(icalcomponent* component, /* Working with embedded error properties */ int icalcomponent_count_errors(icalcomponent* component); + +/* Remove all X-LIC-ERROR properties*/ void icalcomponent_strip_errors(icalcomponent* component); +/* Convert some X-LIC-ERROR properties into RETURN-STATUS properties*/ +void icalcomponent_convert_errors(icalcomponent* component); /* Internal operations. You don't see these... */ icalcomponent* icalcomponent_get_parent(icalcomponent* component); diff --git a/libical/src/libical/icalenums.c b/libical/src/libical/icalenums.c index 70931d03d0..95f308eec6 100644 --- a/libical/src/libical/icalenums.c +++ b/libical/src/libical/icalenums.c @@ -24,6 +24,11 @@ ======================================================================*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "icalenums.h" struct icalproperty_kind_map { @@ -224,6 +229,7 @@ static struct icalvalue_kind_map value_map[] = { ICAL_TIME_VALUE, "TIME"}, { ICAL_URI_VALUE, "URI"}, { ICAL_UTCOFFSET_VALUE, "UTC-OFFSET"}, + { ICAL_METHOD_VALUE, "METHOD"}, /* Not an RFC2445 type */ { ICAL_GEO_VALUE, "FLOAT"}, /* Not an RFC2445 type */ { ICAL_ATTACH_VALUE, "XATTACH"}, /* Not an RFC2445 type */ { ICAL_DATETIMEDATE_VALUE, "XDATETIMEDATE"}, /* Not an RFC2445 type */ @@ -281,7 +287,8 @@ static struct icalcomponent_kind_map component_map[] = /* libical private components */ { ICAL_XLICINVALID_COMPONENT, "X-LIC-UNKNOWN" }, - { ICAL_XROOT_COMPONENT, "ROOT" }, + { ICAL_ANY_COMPONENT, "ANY" }, + { ICAL_XROOT_COMPONENT, "XROOT" }, /* End of list */ { ICAL_NO_COMPONENT, "" }, @@ -326,7 +333,7 @@ struct icalproperty_kind_value_map { static struct icalproperty_kind_value_map propval_map[] = { { ICAL_CALSCALE_PROPERTY, ICAL_TEXT_VALUE }, - { ICAL_METHOD_PROPERTY, ICAL_TEXT_VALUE }, + { ICAL_METHOD_PROPERTY, ICAL_METHOD_VALUE }, { ICAL_PRODID_PROPERTY, ICAL_TEXT_VALUE }, { ICAL_VERSION_PROPERTY, ICAL_TEXT_VALUE }, { ICAL_CATEGORIES_PROPERTY, ICAL_TEXT_VALUE }, @@ -481,7 +488,7 @@ struct { {ICAL_3_1_INVPROPVAL_STATUS, 3,1,"Invalid property value."}, {ICAL_3_2_INVPARAM_STATUS, 3,2,"Invalid property parameter."}, {ICAL_3_3_INVPARAMVAL_STATUS, 3,3,"Invalid property parameter value."}, - {ICAL_3_4_INVCOMP_STATUS, 3,4,"Invalid calendar component sequence."}, + {ICAL_3_4_INVCOMP_STATUS, 3,4,"Invalid calendar component."}, {ICAL_3_5_INVTIME_STATUS, 3,5,"Invalid date or time."}, {ICAL_3_6_INVRULE_STATUS, 3,6,"Invalid rule."}, {ICAL_3_7_INVCU_STATUS, 3,7,"Invalid Calendar User."}, @@ -496,9 +503,65 @@ struct { {ICAL_5_0_MAYBE_STATUS, 5,0,"Request MAY supported."}, {ICAL_5_1_UNAVAIL_STATUS, 5,1,"Service unavailable."}, {ICAL_5_2_NOSERVICE_STATUS, 5,2,"Invalid calendar service."}, - {ICAL_5_3_NOSCHED_STATUS, 5,3,"No scheduling support for user."} + {ICAL_5_3_NOSCHED_STATUS, 5,3,"No scheduling support for user."}, + {ICAL_UNKNOWN_STATUS, 0,0,"Error: Unknown request status"} }; + +char* icalenum_reqstat_desc(icalrequeststatus stat) +{ + + int i; + + for (i=0; status_map[i].kind != ICAL_UNKNOWN_STATUS; i++) { + if ( status_map[i].kind == stat) { + return status_map[i].str; + } + } + + return 0; +} + + +short icalenum_reqstat_major(icalrequeststatus stat) +{ + int i; + + for (i=0; status_map[i].kind != ICAL_UNKNOWN_STATUS; i++) { + if ( status_map[i].kind == stat) { + return status_map[i].major; + } + } + return -1; +} + +short icalenum_reqstat_minor(icalrequeststatus stat) +{ + int i; + + for (i=0; status_map[i].kind != ICAL_UNKNOWN_STATUS; i++) { + if ( status_map[i].kind == stat) { + return status_map[i].minor; + } + } + return -1; +} + + +icalrequeststatus icalenum_num_to_reqstat(short major, short minor) +{ + int i; + + for (i=0; status_map[i].kind != ICAL_UNKNOWN_STATUS; i++) { + if ( status_map[i].major == major && status_map[i].minor == minor) { + return status_map[i].kind; + } + } + return 0; +} + + + struct {icalproperty_method method; char* str;} method_map[] = { {ICAL_METHOD_PUBLISH,"PUBLISH"}, {ICAL_METHOD_REQUEST,"REQUEST"}, @@ -537,6 +600,11 @@ icalproperty_method icalenum_string_to_method(char* str) { int i; + while(*str == ' '){ + str++; + } + + for (i=0; method_map[i].method != ICAL_METHOD_NONE; i++) { if ( strcmp(method_map[i].str, str) == 0) { return method_map[i].method; diff --git a/libical/src/libical/icalenums.h b/libical/src/libical/icalenums.h index e60d230854..ff7cee486e 100644 --- a/libical/src/libical/icalenums.h +++ b/libical/src/libical/icalenums.h @@ -36,8 +36,8 @@ typedef enum icalcomponent_kind { ICAL_NO_COMPONENT, - ICAL_ANY_COMPONENT, /* Used in get_components to select all components*/ - ICAL_XROOT_COMPONENT, /* Root component returned by parser */ + ICAL_ANY_COMPONENT, /* Used to select all components*/ + ICAL_XROOT_COMPONENT, ICAL_XATTACH_COMPONENT, /* MIME attached data, returned by parser. */ ICAL_VEVENT_COMPONENT, ICAL_VTODO_COMPONENT, @@ -210,9 +210,10 @@ typedef enum icalvalue_kind { ICAL_FLOAT_VALUE, ICAL_GEO_VALUE, /* Non-Standard */ ICAL_INTEGER_VALUE, - ICAL_METHOD_VALUE, + ICAL_METHOD_VALUE, /* Non-Standard */ ICAL_PERIOD_VALUE, ICAL_RECUR_VALUE, + ICAL_STRING_VALUE, /* Non-Standard */ ICAL_TEXT_VALUE, ICAL_TIME_VALUE, ICAL_TRIGGER_VALUE, /* Non-Standard */ @@ -318,7 +319,8 @@ typedef enum icalparameter_role { typedef enum icalparameter_xlicerrortype { ICAL_XLICERRORTYPE_COMPONENTPARSEERROR, - ICAL_XLICERRORTYPE_PARAMETERPARSEERROR, + ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR, + ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR, ICAL_XLICERRORTYPE_PROPERTYPARSEERROR, ICAL_XLICERRORTYPE_VALUEPARSEERROR, ICAL_XLICERRORTYPE_INVALIDITIP @@ -396,6 +398,7 @@ char* icalenum_weekday_to_string(icalrecurrencetype_weekday kind); **********************************************************************/ typedef enum icalrequeststatus { + ICAL_UNKNOWN_STATUS, ICAL_2_0_SUCCESS_STATUS, ICAL_2_1_FALLBACK_STATUS, ICAL_2_2_IGPROP_STATUS, @@ -431,6 +434,10 @@ typedef enum icalrequeststatus { } icalrequeststatus; +char* icalenum_reqstat_desc(icalrequeststatus stat); +short icalenum_reqstat_major(icalrequeststatus stat); +short icalenum_reqstat_minor(icalrequeststatus stat); +icalrequeststatus icalenum_num_to_reqstat(short major, short minor); /*********************************************************************** * Conversion functions diff --git a/libical/src/libical/icalerror.c b/libical/src/libical/icalerror.c index d84c288d3a..fb9e152b16 100644 --- a/libical/src/libical/icalerror.c +++ b/libical/src/libical/icalerror.c @@ -25,6 +25,11 @@ ======================================================================*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "icalerror.h" icalerrorenum icalerrno; @@ -35,6 +40,15 @@ void icalerror_stop_here(void) foo++; /* Keep optimizers from removing routine */ } +void icalerror_crash_here(void) +{ + int *p=0; + *p = 1; + + assert( *p); +} + + void icalerror_clear_errno() { icalerrno = ICAL_NO_ERROR; diff --git a/libical/src/libical/icalerror.h b/libical/src/libical/icalerror.h index 429d680022..124699c21b 100644 --- a/libical/src/libical/icalerror.h +++ b/libical/src/libical/icalerror.h @@ -36,6 +36,8 @@ below */ void icalerror_stop_here(void); +void icalerror_crash_here(void); + #ifdef ICAL_ERRORS_ARE_FATAL #undef NDEBUG #endif diff --git a/libical/src/libical/icallexer.l b/libical/src/libical/icallexer.l new file mode 100644 index 0000000000..9026b9ae41 --- /dev/null +++ b/libical/src/libical/icallexer.l @@ -0,0 +1,282 @@ +%{ +/* -*- Mode: C -*- + ====================================================================== + FILE: icallexer.l + CREATOR: eric 10 June 1999 + + DESCRIPTION: + + $Id: icallexer.l,v 1.1 2000/04/18 18:17:04 alves 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 icalitip.y + + + + ======================================================================*/ +#include "icalyacc.h" +#include "icalparser.h" +#include "icalenums.h" +#include "icalmemory.h" +#include "assert.h" + +#include /* For strdup() */ + +int icalparser_flex_input(char* buf, int max_size); +void icalparser_clear_flex_input(); + + +#define ICAL_MAX_STR_CONST 1024 + +#undef YY_INPUT +#define YY_INPUT(b,r,ms) ( r= icalparser_flex_input(b,ms)) +#undef yywrap + +#undef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yyerror(msg) + +icalvalue_kind value_kind=ICAL_NO_VALUE; +void set_parser_value_state(); +extern int yydebug; + +void yyerror(char *s); + +void init_str_buf(); + +int last_state; + +char *str_buf; +char *str_buf_p; +size_t buf_sz; /* = ICAL_MAX_STR_CONST;*/ + + +%} + +crlf \x0D?\x0A +space [ ] +qsafechar [^\x00-\x1F\"] +safechar [^\x00-\x1F\"\:\;\,] +tsafechar [\x20-\x21\x23-\x2B\x2D-\x39\x3C-\x5B\x5D-\x7E] +valuechar [^\x00-\x08\x10-\x1F] +xname X-[a-zA-Z0-9\-]+ +xname2 [a-zA-Z0-9\-\ ] +paramtext {safechar}+ +value {valuechar}+ +quotedstring \"{qsafechar}+\" +digit [0-9] + +%array /* Make yytext an array. Slow, but handy. HACK */ + +%option caseless + +%s quoted_string +%s binary_value boolean_value uri_value time_value duration_value number_value period_value recur_value text_value utcoffset_value +%s enum_param_value string_param_value stringlist_param_value keyword line_start component seperator parameter end_of_value paramtext + + + +%% + +%{ +%} + + +{ +.* { yylval.v_string= icalmemory_tmp_copy(yytext); + return STRING;} +{crlf} { return EOL;} + +} + +{ +. { return CHARACTER; } +{crlf} { return EOL;} + +} + +{ +.* { yylval.v_string= icalmemory_tmp_copy(yytext); + return STRING;} +{crlf} { return EOL;} + +} + + +{ +{digit}* { yylval.v_string= icalmemory_tmp_copy(yytext); + return DIGITS; } +T { return TIME_CHAR; } +Z { return UTC_CHAR; } +{crlf} { return EOL;} +} + +{ +{digit}+ { yylval.v_string =icalmemory_tmp_copy(yytext); + return DIGITS; } +T { return TIME_CHAR; } +[\+\-PTWHMSD] { return yytext[0]; } +{crlf} { return EOL;} + +} + +{ +[\+\-\.0-9]+ { yylval.v_int=atoi(yytext); return INTNUMBER; } +{crlf} { return EOL;} +} + +{ +{digit}+ { yylval.v_string =icalmemory_tmp_copy(yytext) ; + return DIGITS; } +T { return TIME_CHAR; } +Z { return UTC_CHAR; } +[\/\+\-PWHMSD] { return yytext[0]; } +{crlf} { return EOL;} + +} + +{ +INTERVAL { return INTERVAL; } +COUNT { return COUNT; } +UNTIL { return UNTIL; } +FREQ { return FREQ; } +BYDAY { return BYDAY; } +BYHOUR { return BYHOUR; } +BYMINUTE { return BYMINUTE; } +BYMONTH { return BYMONTH; } +BYMONTHDAY { return BYMONTHDAY; } +BYSECOND { return BYSECOND; } +BYSETPOS { return BYSETPOS; } +BYWEEKNO { return BYWEEKNO; } +BYYEARDAY { return BYYEARDAY; } +DAILY { return DAILY; } +SECONDLY { return SECONDLY; } +MINUTELY { return MINUTELY; } +HOURLY { return HOURLY; } +MONTHLY { return MONTHLY; } +WEEKLY { return WEEKLY; } +YEARLY { return YEARLY; } +WKST { return WKST; } +MO { return MO; } +SA { return SA; } +SU { return SU; } +TU { return TU; } +WE { return WE; } +TH { return TH; } +FR { return FR; } += { return EQUALS; } +, { return COMMA; } +; { return SEMICOLON; } +[\-\+0-9]+ { yylval.v_string= icalmemory_tmp_copy(yytext); + return DIGITS; } +T { return TIME_CHAR; } +Z { return UTC_CHAR; } +{crlf} { return EOL;} +} + +{ +{crlf} { return EOL;} +\-|\+ { return yytext[0]; } +{digit}{digit} { yylval.v_int=atoi(yytext); return INTNUMBER; } + +} + +{ +. { return CHARACTER; } +{crlf} { return EOL;} + +} + +{ +, { BEGIN(last_state); return COMMA; } +} + + +%% + +int yywrap() +{ + return 1; +} + + +void set_parser_value_state(icalvalue_kind kind) +{ + + switch (kind){ + + case ICAL_ATTACH_VALUE: + case ICAL_BINARY_VALUE: + {BEGIN(binary_value);break;} + + case ICAL_BOOLEAN_VALUE: + case ICAL_INTEGER_VALUE: + case ICAL_FLOAT_VALUE: + {BEGIN(number_value);break;} + + case ICAL_UTCOFFSET_VALUE: + {BEGIN(utcoffset_value);break;} + + case ICAL_TEXT_VALUE: + {BEGIN(text_value); + init_str_buf(); + break;} + + case ICAL_CALADDRESS_VALUE: + case ICAL_URI_VALUE: + {BEGIN(uri_value);break;} + + case ICAL_DATE_VALUE: + case ICAL_DATETIME_VALUE: + case ICAL_DATETIMEDATE_VALUE: + case ICAL_DATETIMEPERIOD_VALUE: + case ICAL_TIME_VALUE: + {BEGIN(time_value);break;} + + case ICAL_DURATION_VALUE: + {BEGIN(duration_value);break;} + + case ICAL_PERIOD_VALUE: + {BEGIN(period_value);break;} + + case ICAL_GEO_VALUE: + case ICAL_QUERY_VALUE: + {BEGIN(text_value);break;} + + case ICAL_RECUR_VALUE: + {BEGIN(recur_value);break;} + + case ICAL_NO_VALUE: + { + /* The value is probably actually a component name */ + {BEGIN(component); break;} + } + default: + { + assert(1==0); + } + } +} + +void init_str_buf() +{ + str_buf = icalmemory_tmp_buffer(ICAL_MAX_STR_CONST); + str_buf_p = str_buf; + buf_sz = ICAL_MAX_STR_CONST; + + +} + diff --git a/libical/src/libical/icalmemory.c b/libical/src/libical/icalmemory.c index 7d99eb62b3..e89451fbce 100644 --- a/libical/src/libical/icalmemory.c +++ b/libical/src/libical/icalmemory.c @@ -35,14 +35,19 @@ * several buffers active simultaneously, which is handy when creating * string representations of components. */ - #define ICALMEMORY_C +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + #include "icalmemory.h" #include "icalerror.h" #include /* for printf (debugging) */ #include /* for malloc, realloc */ +#include /* for memset() */ #define BUFFER_RING_SIZE 25 #define MIN_BUFFER_SIZE 200 diff --git a/libical/src/libical/icalparameter.c b/libical/src/libical/icalparameter.c index ff9c76f79c..cf37eb07b2 100644 --- a/libical/src/libical/icalparameter.c +++ b/libical/src/libical/icalparameter.c @@ -28,6 +28,10 @@ ======================================================================*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "ical.h" #include "icalerror.h" #include /* for malloc() */ @@ -68,7 +72,6 @@ struct icalparameter_impl* icalparameter_new_impl(icalparameter_kind kind) if ( ( v = (struct icalparameter_impl*) malloc(sizeof(struct icalparameter_impl))) == 0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); - errno = ENOMEM; return 0; } @@ -412,8 +415,11 @@ icalparameter* icalparameter_new_from_string(icalparameter_kind kind, char* val) else if(strcmp(val,"PROPERTY_PARSE_ERROR") == 0){ param = icalparameter_new_xlicerrortype(ICAL_XLICERRORTYPE_PROPERTYPARSEERROR); } - else if(strcmp(val,"PARAMETER_PARSE_ERROR") == 0){ - param = icalparameter_new_xlicerrortype(ICAL_XLICERRORTYPE_PARAMETERPARSEERROR); + else if(strcmp(val,"PARAMETER_NAME_PARSE_ERROR") == 0){ + param = icalparameter_new_xlicerrortype(ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR); + } + else if(strcmp(val,"PARAMETER_VALUE_PARSE_ERROR") == 0){ + param = icalparameter_new_xlicerrortype(ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR); } else if(strcmp(val,"VALUE_PARSE_ERROR") == 0){ param = icalparameter_new_xlicerrortype(ICAL_XLICERRORTYPE_VALUEPARSEERROR); @@ -423,6 +429,37 @@ icalparameter* icalparameter_new_from_string(icalparameter_kind kind, char* val) } break; } + + case ICAL_XLICCOMPARETYPE_PARAMETER: + { + + if(strcmp(val,"EQUAL") == 0){ + param = icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_EQUAL); + } + else if(strcmp(val,"NOTEQUAL") == 0){ + param = icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_NOTEQUAL); + } + else if(strcmp(val,"LESS") == 0){ + param = icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_LESS); + } + else if(strcmp(val,"GREATER") == 0){ + param = icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_GREATER); + } + else if(strcmp(val,"LESSEQUAL") == 0){ + param = icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_LESSEQUAL); + } + else if(strcmp(val,"GREATEREQUAL") == 0){ + param = icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_GREATEREQUAL); + } + else if(strcmp(val,"REGEX") == 0){ + param = icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_REGEX); + } else { + param = 0; + } + break; + } + + case ICAL_X_PARAMETER: { param = icalparameter_new(ICAL_FBTYPE_PARAMETER); @@ -767,7 +804,7 @@ icalparameter_as_ical_string (icalparameter* parameter) strcpy(tend,impl->string);break; } default:{ - strcpy(tend,"ERROR");break; + strcpy(tend,"ERROR"); icalerror_set_errno(ICAL_BADARG_ERROR);break; } } @@ -786,9 +823,13 @@ icalparameter_as_ical_string (icalparameter* parameter) { strcpy(tend,"PROPERTY_PARSE_ERROR");break; } - case ICAL_XLICERRORTYPE_PARAMETERPARSEERROR: + case ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR: + { + strcpy(tend,"PARAMETER_NAME_PARSE_ERROR");break; + } + case ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR: { - strcpy(tend,"PARAMETER_PARSE_ERROR");break; + strcpy(tend,"PARAMETER_VALUE_PARSE_ERROR");break; } case ICAL_XLICERRORTYPE_VALUEPARSEERROR: { @@ -1026,7 +1067,7 @@ char* icalparameter_get_altrep(icalparameter* param) void icalparameter_set_altrep(icalparameter* param, char* v) { - icalerror_check_arg_rz( (v!=0),"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -1062,7 +1103,7 @@ char* icalparameter_get_cn(icalparameter* param) void icalparameter_set_cn(icalparameter* param, char* v) { - icalerror_check_arg_rz( (v!=0),"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -1139,7 +1180,7 @@ char* icalparameter_get_delegatedfrom(icalparameter* param) void icalparameter_set_delegatedfrom(icalparameter* param, char* v) { - icalerror_check_arg_rz( (v!=0),"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -1175,7 +1216,7 @@ char* icalparameter_get_delegatedto(icalparameter* param) void icalparameter_set_delegatedto(icalparameter* param, char* v) { - icalerror_check_arg_rz( (v!=0),"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -1211,7 +1252,7 @@ char* icalparameter_get_dir(icalparameter* param) void icalparameter_set_dir(icalparameter* param, char* v) { - icalerror_check_arg_rz( (v!=0),"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -1329,7 +1370,7 @@ char* icalparameter_get_fmttype(icalparameter* param) void icalparameter_set_fmttype(icalparameter* param, char* v) { - icalerror_check_arg_rz( (v!=0),"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -1365,7 +1406,7 @@ char* icalparameter_get_language(icalparameter* param) void icalparameter_set_language(icalparameter* param, char* v) { - icalerror_check_arg_rz( (v!=0),"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -1401,7 +1442,7 @@ char* icalparameter_get_member(icalparameter* param) void icalparameter_set_member(icalparameter* param, char* v) { - icalerror_check_arg_rz( (v!=0),"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -1473,9 +1514,6 @@ icalparameter_range icalparameter_get_range(icalparameter* param) { icalerror_clear_errno(); icalerror_check_arg( (param!=0), "param"); - if ( ((struct icalparameter_impl*)param)->string != 0){ - return ICAL_PARTSTAT_XNAME; - } return ((struct icalparameter_impl*)param)->data.v_range; @@ -1514,9 +1552,6 @@ icalparameter_related icalparameter_get_related(icalparameter* param) { icalerror_clear_errno(); icalerror_check_arg( (param!=0), "param"); - if ( ((struct icalparameter_impl*)param)->string != 0){ - return ICAL_PARTSTAT_XNAME; - } return ((struct icalparameter_impl*)param)->data.v_related; @@ -1637,9 +1672,6 @@ int icalparameter_get_rsvp(icalparameter* param) { icalerror_clear_errno(); icalerror_check_arg( (param!=0), "param"); - if ( ((struct icalparameter_impl*)param)->string != 0){ - return ICAL_ROLE_XNAME; - } return ((struct icalparameter_impl*)param)->data.v_rsvp; @@ -1683,7 +1715,7 @@ char* icalparameter_get_sentby(icalparameter* param) void icalparameter_set_sentby(icalparameter* param, char* v) { - icalerror_check_arg_rz( (v!=0),"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -1719,7 +1751,7 @@ char* icalparameter_get_tzid(icalparameter* param) void icalparameter_set_tzid(icalparameter* param, char* v) { - icalerror_check_arg_rz( (v!=0),"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -1796,7 +1828,7 @@ char* icalparameter_get_x(icalparameter* param) void icalparameter_set_x(icalparameter* param, char* v) { - icalerror_check_arg_rz( (v!=0),"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -1827,9 +1859,6 @@ icalparameter_xlicerrortype icalparameter_get_xlicerrortype(icalparameter* param { icalerror_clear_errno(); icalerror_check_arg( (param!=0), "param"); - if ( ((struct icalparameter_impl*)param)->string != 0){ - return ICAL_VALUE_XNAME; - } return ((struct icalparameter_impl*)param)->data.v_xlicerrortype; @@ -1868,9 +1897,6 @@ icalparameter_xliccomparetype icalparameter_get_xliccomparetype(icalparameter* p { icalerror_clear_errno(); icalerror_check_arg( (param!=0), "param"); - if ( ((struct icalparameter_impl*)param)->string != 0){ - return ICAL_VALUE_XNAME; - } return ((struct icalparameter_impl*)param)->data.v_xliccomparetype; diff --git a/libical/src/libical/icalparser.c b/libical/src/libical/icalparser.c index b4c1822a68..8541ae4fab 100644 --- a/libical/src/libical/icalparser.c +++ b/libical/src/libical/icalparser.c @@ -16,25 +16,30 @@ 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 + The Initial Developer of the Original Code is Eric Busboom (C) COPYRIGHT 1999 The Software Studio. http://www.softwarestudio.org ======================================================================*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + #include "ical.h" #include "pvl.h" #include "icalparser.h" #include "icalmemory.h" -#include /* For strncpy */ +#include /* For strncpy & size_t */ #include /* For FILE and fgets and sprintf */ #include /* for free */ extern icalvalue* icalparser_yy_value; void set_parser_value_state(icalvalue_kind kind); -int icalparser_yyparse(void); +int ical_yy_parse(void); char* icalparser_get_next_char(char c, char *str); char* icalparser_get_next_parameter(char* line,char** end); @@ -42,7 +47,77 @@ char* icalparser_get_next_value(char* line, char **end, icalvalue_kind kind); char* icalparser_get_prop_name(char* line, char** end); char* icalparser_get_param_name(char* line, char **end); -icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind, char* str, icalproperty **error); +#define TMP_BUF_SIZE 80 + +struct icalparser_impl +{ + int buffer_full; + size_t tmp_buf_size; + char temp[TMP_BUF_SIZE]; + icalcomponent *root_component; + icalcomponent *tail; + int version; + int level; + int lineno; + icalparser_state state; + pvl_list components; + + void *line_gen_data; + +}; + + +icalparser* icalparser_new() +{ + struct icalparser_impl* impl = 0; + + if ( ( impl = (struct icalparser_impl*) + malloc(sizeof(struct icalparser_impl))) == 0) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return 0; + } + + impl->root_component = 0; + impl->components = pvl_newlist(); + impl->level = 0; + impl->state = ICALPARSER_SUCCESS; + + impl->tmp_buf_size = TMP_BUF_SIZE; + impl->buffer_full = 0; + impl->lineno = 0; + + memset(impl->temp,0, TMP_BUF_SIZE); + + return (icalparser*)impl; +} + +void icalparser_free(icalparser* parser) +{ + struct icalparser_impl* impl = (struct icalparser_impl*)parser; + icalcomponent *c; + + if (impl->root_component != 0){ + icalcomponent_free(impl->root_component); + } + + while( (c=pvl_pop(impl->components)) != 0){ + icalcomponent_free(c); + } + + pvl_free(impl->components); +} + +void icalparser_set_gen_data(icalparser* parser, void* data) +{ + struct icalparser_impl* impl = (struct icalparser_impl*)parser; + + impl->line_gen_data = data; +} + + +icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind, + char* str, + icalproperty **error); @@ -114,7 +189,7 @@ void icalparser_clear_flex_input() /* Cal the flex parser to parse a complex value */ icalvalue* icalparser_parse_value(icalvalue_kind kind, - char* str, icalproperty** error) + char* str, icalproperty** error) { int r; input_buffer_p = input_buffer = str; @@ -122,7 +197,7 @@ icalvalue* icalparser_parse_value(icalvalue_kind kind, set_parser_value_state(kind); icalparser_yy_value = 0; - r = icalparser_yyparse(); + r = ical_yy_parse(); /* Error. Parse failed */ if( icalparser_yy_value == 0 || r != 0){ @@ -176,7 +251,7 @@ char* icalparser_get_param_name(char* line, char **end) next = icalparser_get_next_char('=',line); if (next == 0) { - return 0; + return 0; } str = make_segment(line,next); @@ -223,50 +298,50 @@ char* icalparser_get_next_value(char* line, char **end, icalvalue_kind kind) p = line; while(1){ - next = icalparser_get_next_char(',',p); + next = icalparser_get_next_char(',',p); - /* Unforunately, RFC2445 says that for the RECUR value, COMMA - can both seperate digits in a list, and it can seperate - multiple recurrence specifications. This is not a friendly - part of the spec. This weirdness tries to - distinguish the two uses. it is probably a HACK*/ + /* Unforunately, RFC2445 says that for the RECUR value, COMMA + can both seperate digits in a list, and it can seperate + multiple recurrence specifications. This is not a friendly + part of the spec. This weirdness tries to + distinguish the two uses. it is probably a HACK*/ - if( kind == ICAL_RECUR_VALUE ) { - if ( next != 0 && - (*end+length) > next+5 && - strncmp(next,"FREQ",4) == 0 - ) { - /* The COMMA was followed by 'FREQ', is it a real seperator*/ - /* Fall through */ - printf("%s\n",next); - } else if (next != 0){ - /* Not real, get the next COMMA */ - p = next+1; - next = 0; - continue; - } - } - - /* If the comma is preceeded by a '\', then it is a literal and - not a value seperator*/ + if( kind == ICAL_RECUR_VALUE ) { + if ( next != 0 && + (*end+length) > next+5 && + strncmp(next,"FREQ",4) == 0 + ) { + /* The COMMA was followed by 'FREQ', is it a real seperator*/ + /* Fall through */ + printf("%s\n",next); + } else if (next != 0){ + /* Not real, get the next COMMA */ + p = next+1; + next = 0; + continue; + } + } + + /* If the comma is preceeded by a '\', then it is a literal and + not a value seperator*/ - if ( (next!=0 && *(next-1) == '\\') || - (next!=0 && *(next-3) == '\\') - ) - /*second clause for '/' is on prev line. HACK may be out of bounds */ - { - p = next+1; - } else { - break; - } + if ( (next!=0 && *(next-1) == '\\') || + (next!=0 && *(next-3) == '\\') + ) + /*second clause for '/' is on prev line. HACK may be out of bounds */ + { + p = next+1; + } else { + break; + } } if (next == 0){ next = (char*)(size_t)line+length; - *end = next; + *end = next; } else { - *end = next+1; + *end = next+1; } if (next == line){ @@ -305,22 +380,18 @@ char* icalparser_get_next_parameter(char* line,char** end) } } -/* HACK. This is not threadsafe */ -int buffer_full=0; -size_t tmp_buf_size = 80; -char temp[80]; - - /* Get a single property line, from the property name through the final new line, and include any continuation lines */ -char* icalparser_get_line(char* (*line_gen_func)(char *s, size_t size, void *d), int *lineno) +char* icalparser_get_line(icalparser *parser, + char* (*line_gen_func)(char *s, size_t size, void *d)) { char *line; char *line_p; - size_t buf_size = tmp_buf_size; - + struct icalparser_impl* impl = (struct icalparser_impl*)parser; + size_t buf_size = impl->tmp_buf_size; + line_p = line = icalmemory_new_buffer(buf_size); line[0] = '\0'; @@ -328,43 +399,63 @@ char* icalparser_get_line(char* (*line_gen_func)(char *s, size_t size, void *d), /* The buffer is not clear, so transfer the data in it to the output. This may be left over from a previous call */ - if (temp[0] != '\0' ) { - if (temp[tmp_buf_size-1] == 0){ - buffer_full = 1; + if (impl->temp[0] != '\0' ) { + + /* If the last position in the temp buffer is occupied, + mark the buffer as full. The means we will do another + read later, because the line is not finished */ + if (impl->temp[impl->tmp_buf_size-1] == 0){ + impl->buffer_full = 1; } else { - buffer_full = 0; + impl->buffer_full = 0; } - icalmemory_append_string(&line,&line_p,&buf_size,temp); - temp[0] = '\0' ; + + /* Copy the temp to the output and clear the temp buffer. */ + icalmemory_append_string(&line,&line_p,&buf_size,impl->temp); + impl->temp[0] = '\0' ; } - temp[tmp_buf_size-1] = 1; /* Mark end of buffer */ + impl->temp[impl->tmp_buf_size-1] = 1; /* Mark end of buffer */ + + if ((*line_gen_func)(impl->temp,impl->tmp_buf_size,impl->line_gen_data) + ==0){/* Get more data */ + + /* If the first position is clear, it means we didn't get + any more data from the last call to line_ge_func*/ + if (impl->temp[0] == '\0'){ - if ((*line_gen_func)(temp,tmp_buf_size,0)==0){/* Get more data */ - if (temp[0] == '\0'){ if(line[0] != '\0'){ + /* There is data in the output, so fall trhough and process it*/ break; } else { + /* No data in output; return and signal that there + is no more input*/ free(line); return 0; } } } + + + /* If the output line ends in a '\n' and the temp buffer + begins with a ' ', then the buffer holds a continuation + line, so keep reading. */ - if ( line_p > line+1 && *(line_p-1) == '\n' && temp[0] == ' ') { - - /* If the output line ends in a '\n' and the temp buffer - begins with a ' ', then the buffer holds a continuation - line, so keep reading. */ + if ( line_p > line+1 && *(line_p-1) == '\n' && impl->temp[0] == ' ') { /* back up the pointer to erase the continuation characters */ line_p--; + if ( *(line_p-1) == '\r'){ + line_p--; + } + /* shift the temp buffer down to eliminate the leading space*/ - memmove(&(temp[0]),&(temp[1]),tmp_buf_size); - temp[tmp_buf_size-1] = temp[tmp_buf_size-2]; + memmove(&(impl->temp[0]),&(impl->temp[1]),impl->tmp_buf_size); + + impl->temp[impl->tmp_buf_size-1] = impl->temp[impl->tmp_buf_size-2]; - } else if ( buffer_full == 1 ) { + } else if ( impl->buffer_full == 1 ) { /* The buffer was filled on the last read, so read again */ @@ -377,10 +468,13 @@ char* icalparser_get_line(char* (*line_gen_func)(char *s, size_t size, void *d), } - /* Erase the final newline */ - if ( line_p > line+1 && *(line_p-1) == '\n') { - + /* Erase the final newline and/or carriage return*/ + if ( line_p > line+1 && *(line_p-1) == '\n') { *(line_p-1) = '\0'; + if ( *(line_p-2) == '\r'){ + *(line_p-2) = '\0'; + } + } else { *(line_p) = '\0'; } @@ -389,111 +483,6 @@ char* icalparser_get_line(char* (*line_gen_func)(char *s, size_t size, void *d), } -#if 0 -char* icalparser_old_get_line(char* (*line_gen_func)(char *s, size_t size, void *d), int *lineno) -{ - char *line, *output_line; - char *line_p; - char last_line = 0; - size_t buf_size = tmp_buf_size; - int break_flag = 0; - - line_p = line = icalmemory_new_buffer(buf_size); - - /* If the hold buffer is empty, read a line. Otherwise, use the data that - is still in 'temp'*/ - if (hold == 1){ - /* Do nothing */ - } else { - temp[tmp_buf_size-1] = 1; /* Mark end of buffer */ - (*line_gen_func)(temp,tmp_buf_size,0); - } - - /* Append the hold buffer or new line into the output */ - icalmemory_append_string(&line,&line_p,&buf_size,temp); - - if ( temp[tmp_buf_size-1] == 0 ) { /* Check if mark was overwritten */ - buffer_full = 1; - } else { - buffer_full = 0; - } - - /* Try to suck up any continuation lines */ - while(last_line == 0){ - - temp[tmp_buf_size-1] = 1; /* Mark end of buffer */ - if ((*line_gen_func)(temp,tmp_buf_size,0) == 0){ - /* No more lines -- we are finished */ - if (hold == 1) { - hold = 0; - break_flag = 1; - } else { - icalmemory_free_buffer(line); - return 0; - } - } else { - if ( temp[tmp_buf_size-1] == 0 ) { - buffer_full = 1; - } else { - buffer_full = 0; - } - } - - /* keep track of line numbers */ - if (lineno != 0){ - (*lineno)++; - } - - - /* Determine wether to copy the line to the output, or - save it in the hold buffer */ - - if ( line_p > line+1 && *(line_p-1) == '\n' && temp[0] == ' ') { - - /* If the last line ( in the 'line' string ) ends in a '\n' - and the current line begins with a ' ', then the current line - is a continuation line, so append it. */ - - /* back up the pointer to erase the continuation characters */ - line_p--; - icalmemory_append_string(&line,&line_p,&buf_size,&(temp[1])); - - hold = 0; - buffer_full= 0; - - } else if (buffer_full == 1) { - - /* The last line that was read filled up the read - buffer. Append it and read again */ - - icalmemory_append_string(&line,&line_p,&buf_size,temp); - - hold = 0; - - } else if (break_flag != 1 ){ - /* Nope -- the line was not a continuation line. - Save the line for the next call */ - - hold =1; - break; - } else { - break; - } - } - - /* Erase the final newline */ - if ( line_p > line+1 && *(line_p-1) == '\n') { - - *(line_p-1) = '\0'; - } - - output_line = icalmemory_tmp_copy(line); - icalmemory_free_buffer(line); - - return output_line; -} -#endif - void insert_error(icalcomponent* comp, char* text, char* message, icalparameter_xlicerrortype type) { @@ -513,389 +502,489 @@ void insert_error(icalcomponent* comp, char* text, 0)); } -icalcomponent* icalparser_parse(char* (*line_gen_func)(char *s, size_t size, void* d)) +icalcomponent* icalparser_parse(icalparser *parser, + char* (*line_gen_func)(char *s, size_t size, + void* d)) { - char *line = 0; + char* line; + icalcomponent *c=0; + icalcomponent *root_component=0; + + icalerror_check_arg_rz((parser !=0),"parser"); + + do{ + line = icalparser_get_line(parser, line_gen_func); + + if ((c = icalparser_add_line(parser,line)) != 0){ + if (root_component == 0){ + /* Just one component */ + icalparser_claim(parser); + root_component = c; + } else if(icalcomponent_isa(root_component) + != ICAL_XROOT_COMPONENT) { + /*Got a second component, so move the two components under + an XROOT container */ + icalcomponent *tempc; + tempc = icalcomponent_new(ICAL_XROOT_COMPONENT); + icalcomponent_add_component(tempc, root_component); + icalparser_claim(parser); + icalcomponent_add_component(tempc, c); + root_component = tempc; + } else { + /* Already have an XROOT container, so add the component + to it*/ + icalcomponent_add_component(root_component, c); + icalparser_claim(parser); + } + } + } while ( line != 0); + + return root_component; + +} + +icalcomponent* icalparser_add_line(icalparser* parser, + char* line) +{ char *p; char *str; char *end; - int lineno = 0; - int vcount = 0; - - icalcomponent *root_component = 0; - icalcomponent *tail = 0; icalproperty *prop; icalvalue *value; + icalvalue_kind value_kind = ICAL_NO_VALUE; - icalvalue_kind value_kind; - - pvl_list components = pvl_newlist(); - - do { - value_kind = ICAL_NO_VALUE; + struct icalparser_impl *impl = (struct icalparser_impl*)parser; + icalerror_check_arg_rz((parser != 0),"parser"); - /* Get a single property line, from a property name through a - newline */ - if (line!=0){ - free(line); - } - - line = icalparser_get_line(line_gen_func,&lineno); - if (line == 0){ - continue; - } + if (line == 0) + { + impl->state = ICALPARSER_ERROR; + return 0; + } - end = 0; + /* Begin by getting the property name at the start of the line. The + property name may end up being "BEGIN" or "END" in which case it + is not really a property, but the market for the start or end of + a component */ - str = icalparser_get_prop_name(line, &end); + end = 0; + str = icalparser_get_prop_name(line, &end); - if (str == 0){ - tail = pvl_data(pvl_tail(components)); + if (str == 0){ + /* Could not get a property name */ + icalcomponent *tail = pvl_data(pvl_tail(impl->components)); - if (tail){ - insert_error(tail,line, - "Got a data line, but could not find a property name or component begin tag", - ICAL_XLICERRORTYPE_COMPONENTPARSEERROR); - } - tail = 0; - continue; + if (tail){ + insert_error(tail,line, + "Got a data line, but could not find a property name or component begin tag", + ICAL_XLICERRORTYPE_COMPONENTPARSEERROR); } + tail = 0; + impl->state = ICALPARSER_ERROR; + return 0; + } -/********************************************************************** - * Handle begin and end of components - **********************************************************************/ + /********************************************************************** + * Handle begin and end of components + **********************************************************************/ - /* If the property name is BEGIN or END, we are actually - starting or ending a new component */ + /* If the property name is BEGIN or END, we are actually + starting or ending a new component */ - if(strcmp(str,"BEGIN") == 0){ - icalcomponent *c; ; + if(strcmp(str,"BEGIN") == 0){ + icalcomponent *c; - str = icalparser_get_next_value(end,&end, value_kind); + impl->level++; + str = icalparser_get_next_value(end,&end, value_kind); - c = icalcomponent_new_from_string(str); + c = icalcomponent_new_from_string(str); - if (c == 0){ - c = icalcomponent_new(ICAL_XLICINVALID_COMPONENT); - insert_error(c,str,"Parse error in component name", - ICAL_XLICERRORTYPE_COMPONENTPARSEERROR); - } + if (c == 0){ + c = icalcomponent_new(ICAL_XLICINVALID_COMPONENT); + insert_error(c,str,"Parse error in component name", + ICAL_XLICERRORTYPE_COMPONENTPARSEERROR); + } - pvl_push(components,c); + pvl_push(impl->components,c); - continue; - } else if (strcmp(str,"END") == 0 ) { + impl->state = ICALPARSER_BEGIN_COMP; + return 0; - str = icalparser_get_next_value(end,&end, value_kind); + } else if (strcmp(str,"END") == 0 ) { + icalcomponent* tail; - root_component = pvl_pop(components); + impl->level--; + str = icalparser_get_next_value(end,&end, value_kind); - tail = pvl_data(pvl_tail(components)); + impl->root_component = pvl_pop(impl->components); - if(tail != 0){ - icalcomponent_add_component(tail,root_component); - } + tail = pvl_data(pvl_tail(impl->components)); - tail = 0; - continue; + if(tail != 0){ + icalcomponent_add_component(tail,impl->root_component); } + tail = 0; - /* There is no point in continuing if we have not seen a - component yet */ - - if(pvl_data(pvl_tail(components)) == 0){ - continue; + /* Return the component if we are back to the 0th level */ + if (impl->level == 0){ + impl->state = ICALPARSER_SUCCESS; + return impl->root_component; + } else { + impl->state = ICALPARSER_END_COMP; + return 0; } + } + + + /* There is no point in continuing if we have not seen a + component yet */ + if(pvl_data(pvl_tail(impl->components)) == 0){ + impl->state = ICALPARSER_ERROR; + return 0; + } -/********************************************************************** - * Handle property names - **********************************************************************/ - /* At this point, the property name really is a property name, - (Not a component name) so make a new property and add it to - the component */ - prop = icalproperty_new_from_string(str); + /********************************************************************** + * Handle property names + **********************************************************************/ + /* At this point, the property name really is a property name, + (Not a component name) so make a new property and add it to + the component */ - if (prop != 0){ - tail = pvl_data(pvl_tail(components)); + prop = icalproperty_new_from_string(str); - icalcomponent_add_property(tail, prop); + if (prop != 0){ + icalcomponent *tail = pvl_data(pvl_tail(impl->components)); - /* Set the value kind for the default for this type of - property. This may be re-set by a VALUE parameter */ - value_kind = - icalenum_property_kind_to_value_kind( - icalproperty_isa(prop)); - } else { - icalcomponent* tail = pvl_data(pvl_tail(components)); + icalcomponent_add_property(tail, prop); + + /* Set the value kind for the default for this type of + property. This may be re-set by a VALUE parameter */ + value_kind = + icalenum_property_kind_to_value_kind( + icalproperty_isa(prop)); - insert_error(tail,str,"Parse error in property name", - ICAL_XLICERRORTYPE_PROPERTYPARSEERROR); + } else { + icalcomponent* tail = pvl_data(pvl_tail(impl->components)); + + insert_error(tail,str,"Parse error in property name", + ICAL_XLICERRORTYPE_PROPERTYPARSEERROR); - tail = 0; - continue; - } + tail = 0; + impl->state = ICALPARSER_ERROR; + return 0; + } -/********************************************************************** - * Handle parameter values - **********************************************************************/ + /********************************************************************** + * Handle parameter values + **********************************************************************/ - /* Now, add any parameters to the last property */ + /* Now, add any parameters to the last property */ - p = 0; - while(1) { + p = 0; + while(1) { - if (*(end-1) == ':'){ - /* if the last seperator was a ":" and the value is a - URL, icalparser_get_next_parameter will find the - ':' in the URL, so better break now. */ - break; - } + if (*(end-1) == ':'){ + /* if the last seperator was a ":" and the value is a + URL, icalparser_get_next_parameter will find the + ':' in the URL, so better break now. */ + break; + } - str = icalparser_get_next_parameter(end,&end); + str = icalparser_get_next_parameter(end,&end); - if (str != 0){ - char* name; - char* pvalue; - icalparameter *param = 0; - icalparameter_kind kind; - - tail = pvl_data(pvl_tail(components)); + if (str != 0){ + char* name; + char* pvalue; + + icalparameter *param = 0; + icalparameter_kind kind; + icalcomponent *tail = pvl_data(pvl_tail(impl->components)); - name = icalparser_get_param_name(str,&pvalue); + name = icalparser_get_param_name(str,&pvalue); - if (name == 0){ - insert_error(tail, str, "Can't parse parameter name", - ICAL_XLICERRORTYPE_PARAMETERPARSEERROR); - tail = 0; - break; - } + if (name == 0){ + /* 'tail' defined above */ + insert_error(tail, str, "Can't parse parameter name", + ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR); + tail = 0; + break; + } - kind = icalenum_string_to_parameter_kind(name); - if (kind != ICAL_NO_PARAMETER){ - param = icalparameter_new_from_string(kind,pvalue); - } else { + kind = icalenum_string_to_parameter_kind(name); - /* Error. Failed to parse the parameter*/ - insert_error(tail, str, "Can't parse parameter name", - ICAL_XLICERRORTYPE_PARAMETERPARSEERROR); - tail = 0; - continue; - } + if (kind != ICAL_NO_PARAMETER){ + param = icalparameter_new_from_string(kind,pvalue); + } else { + /* Error. Failed to parse the parameter*/ + /* 'tail' defined above */ + insert_error(tail, str, "Can't parse parameter name", + ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR); + tail = 0; + impl->state = ICALPARSER_ERROR; + return 0; + } - if (param == 0){ - insert_error(tail,str,"Can't parse parameter value", - ICAL_XLICERRORTYPE_PARAMETERPARSEERROR); + if (param == 0){ + /* 'tail' defined above */ + insert_error(tail,str,"Can't parse parameter value", + ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR); - tail = 0; - continue; - } + tail = 0; + impl->state = ICALPARSER_ERROR; + continue; + } - /* If it is a VALUE parameter, set the kind of value*/ - if (icalparameter_isa(param)==ICAL_VALUE_PARAMETER){ + /* If it is a VALUE parameter, set the kind of value*/ + if (icalparameter_isa(param)==ICAL_VALUE_PARAMETER){ - value_kind = (icalvalue_kind) - icalparameter_get_value(param); + value_kind = (icalvalue_kind) + icalparameter_get_value(param); - if (value_kind == ICAL_NO_VALUE){ + if (value_kind == ICAL_NO_VALUE){ - /* Ooops, could not parse the value of the - parameter ( it was not one of the defined - values ), so reset the value_kind */ + /* Ooops, could not parse the value of the + parameter ( it was not one of the defined + values ), so reset the value_kind */ - icalcomponent* tail - = pvl_data(pvl_tail(components)); + insert_error( + tail, str, + "Got a VALUE parameter with an unknown type", + ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR); + icalparameter_free(param); - insert_error( - tail, str, - "Got a VALUE parameter with an unknown type", - ICAL_XLICERRORTYPE_PARAMETERPARSEERROR); - icalparameter_free(param); + value_kind = + icalenum_property_kind_to_value_kind( + icalproperty_isa(prop)); - value_kind = - icalenum_property_kind_to_value_kind( - icalproperty_isa(prop)); - - icalparameter_free(param); - tail = 0; - continue; - } - } + icalparameter_free(param); + tail = 0; + impl->state = ICALPARSER_ERROR; + return 0; + } + } - /* Everything is OK, so add the parameter */ - icalproperty_add_parameter(prop,param); - tail = 0; + /* Everything is OK, so add the parameter */ + icalproperty_add_parameter(prop,param); + tail = 0; - } else { - /* If we did not get a param string, go on to looking - for a value */ - break; - } - } + } else { /* if ( str != 0) */ + /* If we did not get a param string, go on to looking + for a value */ + break; + } /* if ( str != 0) */ + + } /* while(1) */ -/********************************************************************** - * Handle values - **********************************************************************/ + /********************************************************************** + * Handle values + **********************************************************************/ - /* Look for values. If there are ',' characters in the values, - then there are multiple values, so clone the current - parameter and add one part of the value to each clone */ + /* Look for values. If there are ',' characters in the values, + then there are multiple values, so clone the current + parameter and add one part of the value to each clone */ - vcount=0; - while(1) { - str = icalparser_get_next_value(end,&end, value_kind); + vcount=0; + while(1) { + str = icalparser_get_next_value(end,&end, value_kind); - if (str != 0){ + if (str != 0){ - if (vcount > 0){ - /* Actually, only clone after the second value */ - icalproperty* clone = icalproperty_new_clone(prop); - tail = pvl_data(pvl_tail(components)); + if (vcount > 0){ + /* Actually, only clone after the second value */ + icalproperty* clone = icalproperty_new_clone(prop); + icalcomponent* tail = pvl_data(pvl_tail(impl->components)); - icalcomponent_add_property(tail, clone); - prop = clone; - tail = 0; - } + icalcomponent_add_property(tail, clone); + prop = clone; + tail = 0; + } - value = icalvalue_new_from_string(value_kind, str); + value = icalvalue_new_from_string(value_kind, str); - /* Don't add properties without value */ - if (value == 0){ - char temp[1024]; + /* Don't add properties without value */ + if (value == 0){ + char temp[200]; /* HACK */ - icalproperty_kind prop_kind = icalproperty_isa(prop); - tail = pvl_data(pvl_tail(components)); + icalproperty_kind prop_kind = icalproperty_isa(prop); + icalcomponent* tail = pvl_data(pvl_tail(impl->components)); - sprintf(temp,"Can't parse as %s value in %s property. Removing entire property", - icalenum_value_kind_to_string(value_kind), - icalenum_property_kind_to_string(prop_kind)); + sprintf(temp,"Can't parse as %s value in %s property. Removing entire property", + icalenum_value_kind_to_string(value_kind), + icalenum_property_kind_to_string(prop_kind)); - insert_error(tail, str, temp, - ICAL_XLICERRORTYPE_VALUEPARSEERROR); + insert_error(tail, str, temp, + ICAL_XLICERRORTYPE_VALUEPARSEERROR); - /* Remove the troublesome property */ - icalcomponent_remove_property(tail,prop); - icalproperty_free(prop); - prop = 0; - tail = 0; - break; + /* Remove the troublesome property */ + icalcomponent_remove_property(tail,prop); + icalproperty_free(prop); + prop = 0; + tail = 0; + impl->state = ICALPARSER_ERROR; + return 0; - } else { - vcount++; - icalproperty_set_value(prop, value); - } + } else { + vcount++; + icalproperty_set_value(prop, value); + } - } else { + } else { + if (vcount == 0){ + char temp[200]; /* HACK */ + icalproperty_kind prop_kind = icalproperty_isa(prop); + icalcomponent *tail = pvl_data(pvl_tail(impl->components)); + + sprintf(temp,"No value for %s property. Removing entire property", + icalenum_property_kind_to_string(prop_kind)); + + insert_error(tail, str, temp, + ICAL_XLICERRORTYPE_VALUEPARSEERROR); + + /* Remove the troublesome property */ + icalcomponent_remove_property(tail,prop); + icalproperty_free(prop); + prop = 0; + tail = 0; + impl->state = ICALPARSER_ERROR; + return 0; + } else { + break; } } + } - } while( !feof(stdin) && line !=0 ); + /**************************************************************** + * End of component parsing. + *****************************************************************/ - - if (pvl_data(pvl_tail(components)) == 0){ - /* A nice, clean exit */ - pvl_free(components); - free(line); - return root_component; + if (pvl_data(pvl_tail(impl->components)) == 0 && + impl->level == 0){ + impl->state = ICALPARSER_SUCCESS; + return impl->root_component; + } else { + impl->state = ICALPARSER_IN_PROGRESS; + return 0; } - /* Clear off any component that may be left in the list */ - /* This will happen if some components did not have an "END" tag*/ +} + +icalparser_state icalparser_get_state(icalparser* parser) +{ + struct icalparser_impl* impl = (struct icalparser_impl*) parser; + return impl->state; + +} + +icalcomponent* icalparser_claim(icalparser* parser) +{ + struct icalparser_impl* impl = (struct icalparser_impl*) parser; + icalcomponent *c = impl->root_component; + + impl->root_component = 0; + + return c; + +} + + +icalcomponent* icalparser_clean(icalparser* parser) +{ + struct icalparser_impl* impl = (struct icalparser_impl*) parser; + icalcomponent *tail = pvl_data(pvl_tail(impl->components)); - while((tail=pvl_data(pvl_tail(components))) != 0){ + icalerror_check_arg_rz((parser != 0 ),"parser"); + + /* We won't get a clean exit if some components did not have an + "END" tag. Clear off any component that may be left in the list */ + + + while((tail=pvl_data(pvl_tail(impl->components))) != 0){ insert_error(tail," ", "Missing END tag for this component. Closing component at end of input.", ICAL_XLICERRORTYPE_COMPONENTPARSEERROR); - root_component = pvl_pop(components); - tail=pvl_data(pvl_tail(components)); + impl->root_component = pvl_pop(impl->components); + tail=pvl_data(pvl_tail(impl->components)); if(tail != 0){ - icalcomponent_add_component(tail,root_component); + icalcomponent_add_component(tail,impl->root_component); } } - free(line); - return root_component; + return impl->root_component; + } -char* string_line_generator_pos=0; -char* string_line_generator_str; +struct slg_data { + char* pos; + char* str; +}; + char* string_line_generator(char *out, size_t buf_size, void *d) { char *n; - - if(string_line_generator_pos==0){ - string_line_generator_pos=string_line_generator_str; + size_t size; + struct slg_data* data = (struct slg_data*)d; + + if(data->pos==0){ + data->pos=data->str; } /* If the pointer is at the end of the string, we are done */ - if (*string_line_generator_pos ==0){ + if (*(data->pos)==0){ return 0; } - n = strchr(string_line_generator_pos,'\n'); + n = strchr(data->pos,'\n'); - /* If no newline, take the rest of the string, and leave the - pointer at the \0 */ - - if (n == 0) { - n = string_line_generator_pos + strlen(string_line_generator_pos); + if (n == 0){ + size = strlen(data->pos); } else { - n++; + n++; /* include newline in output */ + size = (n-data->pos); } - strncpy(out,string_line_generator_pos,(n-string_line_generator_pos)); - - *(out+(n-string_line_generator_pos)) = '\0'; - - string_line_generator_pos = n; - - return out; + if (size > buf_size-1){ + size = buf_size-1; + } -} -void _test_string_line_generator(char* str) -{ - char *line; - int lineno=0; - string_line_generator_str = str; - string_line_generator_pos = 0; - - while((line = icalparser_get_line(string_line_generator,&lineno))){ - printf("#%d: %s\n",lineno,line); - } + strncpy(out,data->pos,size); + *(out+size) = '\0'; - string_line_generator_pos = 0; - string_line_generator_str = 0; -} - + data->pos += size; + return out; +} icalcomponent* icalparser_parse_string(char* str) { - icalcomponent *c; - - string_line_generator_str = str; - string_line_generator_pos = 0; - c = icalparser_parse(string_line_generator); - string_line_generator_pos = 0; - string_line_generator_str = 0; - + struct slg_data d; + icalparser *p; + + d.pos = 0; + d.str = str; + + p = icalparser_new(); + icalparser_set_gen_data(p,&d); + c = icalparser_parse(p,string_line_generator); + icalparser_free(p); + return c; } diff --git a/libical/src/libical/icalparser.h b/libical/src/libical/icalparser.h index 9e47e38bfb..25c07eca9f 100644 --- a/libical/src/libical/icalparser.h +++ b/libical/src/libical/icalparser.h @@ -31,6 +31,16 @@ #include "ical.h" #include /* For FILE* */ +typedef void* icalparser; +typedef enum icalparser_state { + ICALPARSER_ERROR, + ICALPARSER_SUCCESS, + ICALPARSER_BEGIN_COMP, + ICALPARSER_END_COMP, + ICALPARSER_IN_PROGRESS +} icalparser_state; + + /*********************************************************************** * Message oriented parsing. icalparser_parse takes a string that * holds the text ( in RFC 2445 format ) and returns a pointer to an @@ -38,29 +48,28 @@ * pointer to a function that returns one content line per invocation **********************************************************************/ -icalcomponent* icalparser_parse(char* (*line_gen_func)()); +icalcomponent* icalparser_parse(icalparser *parser, + char* (*line_gen_func)(char *s, size_t size, void *d)); -/* Parse directly from a string */ +/* A simple, and incorrect interface - can only return one component*/ icalcomponent* icalparser_parse_string(char* str); -/* icalparser_flex_input is the routine that is called from the macro - YYINPUT in the flex lexer. */ -int icalparser_flex_input(char* buf, int max_size); -void icalparser_clear_flex_input(); /*********************************************************************** * Line-oriented parsing. * * Create a new parser via icalparse_new_parser, then add ines one at - * a time with icalparse_add_line(). After adding the last line, call - * icalparse_close() to return the parsed component. + * a time with icalparse_add_line(). icalparser_add_line() will return + * non-zero when it has finished with a component. ***********************************************************************/ -/* These are not implemented yet */ -typedef void* icalparser; -icalparser icalparse_new_parser(); -void icalparse_add_line(icalparser* parser ); -icalcomponent* icalparse_close(icalparser* parser); +icalparser* icalparser_new(); +void icalparser_set_gen_data(icalparser* parser, void* data); +icalcomponent* icalparser_add_line(icalparser* parser, char* str ); +icalcomponent* icalparser_claim(icalparser* parser); +icalcomponent* icalparser_clean(icalparser* parser); +icalparser_state icalparser_get_state(icalparser* parser); +void icalparser_free(icalparser* parser); /*********************************************************************** * Parser support functions @@ -69,11 +78,17 @@ icalcomponent* icalparse_close(icalparser* parser); /* Use the flex/bison parser to turn a string into a value type */ icalvalue* icalparser_parse_value(icalvalue_kind kind, char* str, icalcomponent** errors); -char* icalparser_get_line(char* (*line_gen_func)(char *s, size_t size, void *d), int *lineno); - +/* Given a line generator function, return a single iCal content line.*/ +char* icalparser_get_line(icalparser* parser, char* (*line_gen_func)(char *s, size_t size, void *d)); -/* a line_gen_function that returns lines from a string */ +/* a line_gen_function that returns lines from a string. To use it, + set string_line_generator_str to point to the input string, and set + string_line_generator_pos to 0. These globals make the routine not + thead-safe. */ +extern char* string_line_generator_str; +extern char* string_line_generator_pos; +char* string_line_generator(char *out, size_t buf_size, void *d); #endif /* !ICALPARSE_H */ diff --git a/libical/src/libical/icalproperty.c b/libical/src/libical/icalproperty.c index 3dd761b1f8..c3fe7c9073 100644 --- a/libical/src/libical/icalproperty.c +++ b/libical/src/libical/icalproperty.c @@ -25,6 +25,10 @@ ======================================================================*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include /* For strdup, rindex */ #include #include @@ -38,6 +42,8 @@ #include "icalerror.h" #include "icalmemory.h" +#define TMP_BUF_SIZE 1024 + /* Private routines for icalproperty */ void icalvalue_set_parent(icalvalue* value, icalproperty* property); @@ -89,7 +95,6 @@ icalproperty_new_impl (icalproperty_kind kind) if ( ( prop = (struct icalproperty_impl*) malloc(sizeof(struct icalproperty_impl))) == 0) { - errno = ENOMEM; icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } @@ -196,7 +201,7 @@ icalproperty_free (icalproperty* prop) icalparameter* param; - icalerror_check_arg_re((prop!=0),"prop",ICAL_BADARG_ERROR); + icalerror_check_arg_rv((prop!=0),"prop"); p = (struct icalproperty_impl*)prop; @@ -254,6 +259,12 @@ icalproperty_as_ical_string (icalproperty* prop) icalvalue* value; char *out_buf; +#ifdef ICAL_UNIX_NEWLINE + char newline[] = "\n"; +#else + char newline[] = "\r\n"; +#endif + struct icalproperty_impl *impl = (struct icalproperty_impl*)prop; icalerror_check_arg_rz( (prop!=0),"prop"); @@ -275,7 +286,7 @@ icalproperty_as_ical_string (icalproperty* prop) icalmemory_append_string(&buf, &buf_ptr, &buf_size, property_name); - icalmemory_append_string(&buf, &buf_ptr, &buf_size, "\n"); + icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); /* Append parameters */ for(param = icalproperty_get_first_parameter(prop,ICAL_ANY_PARAMETER); @@ -285,15 +296,15 @@ icalproperty_as_ical_string (icalproperty* prop) char* kind_string = icalparameter_as_ical_string(param); if (kind_string == 0 ) { - char temp[1024]; - sprintf(temp, "Got a parameter of unknown kind in %s property",property_name); + char temp[TMP_BUF_SIZE]; + snprintf(temp, TMP_BUF_SIZE,"Got a parameter of unknown kind in %s property",property_name); icalerror_warn(temp); continue; } icalmemory_append_string(&buf, &buf_ptr, &buf_size, " ;"); icalmemory_append_string(&buf, &buf_ptr, &buf_size, kind_string); - icalmemory_append_string(&buf, &buf_ptr, &buf_size, "\n"); + icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); } @@ -311,7 +322,7 @@ icalproperty_as_ical_string (icalproperty* prop) } - icalmemory_append_string(&buf, &buf_ptr, &buf_size, "\n"); + icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); /* Now, copy the buffer to a tmp_buffer, which is safe to give to the caller without worring about de-allocating it. */ @@ -1740,7 +1751,7 @@ void icalproperty_set_requeststatus(icalproperty* prop, char* v) icalerror_check_arg_rv( (prop!=0),"prop"); - value = icalvalue_new_text(v); + value = icalvalue_new_string(v); icalproperty_set_value(prop,value); @@ -1753,7 +1764,7 @@ char* icalproperty_get_requeststatus(icalproperty* prop) value = icalproperty_get_value(prop); - return icalvalue_get_text(value); + return icalvalue_get_string(value); } /* EXDATE */ diff --git a/libical/src/libical/icalrestriction.c b/libical/src/libical/icalrestriction.c index 9393b3ea34..d5ffb784ef 100644 --- a/libical/src/libical/icalrestriction.c +++ b/libical/src/libical/icalrestriction.c @@ -18,9 +18,15 @@ ======================================================================*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "icalenums.h" #include "icalrestriction.h" +#define TMP_BUF_SIZE 1024 + /* Define the structs for the restrictions. these data are filled out in machine generated code below */ @@ -48,7 +54,9 @@ icalrestriction_property_record icalrestriction_property_records[]; /* The each row gives the result of comparing a restriction against a count. The columns in each row represent 0,1,2+. '-1' indicates - 'invalid, 'don't care' or 'needs more analysis' */ + 'invalid, 'don't care' or 'needs more analysis' So, for + ICAL_RESTRICTION_ONE, if there is 1 of a property with that + restriction, it passes, but if there are 0 or 2+, it fails. */ char compare_map[ICAL_RESTRICTION_UNKNOWN+1][3] = { { 1, 1, 1},/*ICAL_RESTRICTION_NONE*/ @@ -129,9 +137,9 @@ int icalrestriction_check_component(icalproperty_method method, if (compare == 0){ - char temp[1024]; + char temp[TMP_BUF_SIZE]; - sprintf(temp, "Failed iTIP restrictions for property %s. Expected %s instances of the property and got %d", + snprintf(temp, TMP_BUF_SIZE,"Failed iTIP restrictions for property %s. Expected %s instances of the property and got %d", icalenum_property_kind_to_string(kind), restr_string_map[restr], count); diff --git a/libical/src/libical/icaltypes.c b/libical/src/libical/icaltypes.c index 14daa2915d..2800b4857f 100644 --- a/libical/src/libical/icaltypes.c +++ b/libical/src/libical/icaltypes.c @@ -24,15 +24,21 @@ The original code is icaltypes.c ======================================================================*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include "icaltypes.h" #include "icalerror.h" +#include "icalmemory.h" #include /* for malloc */ #include /* for errno */ #include /* for strdup */ #include #include /* for SHRT_MAX */ +#define TEMP_MAX 1024 + void* icalattachtype_get_data (struct icalattachtype* type); @@ -198,3 +204,83 @@ void icalrecurrencetype_clear(struct icalrecurrencetype *recur) recur->until.year = 0; recur->count = 0; } + + +struct icalreqstattype icalreqstattype_from_string(char* str) +{ + char *p1,*p2; + size_t len; + struct icalreqstattype stat; + int major, minor; + + icalerror_check_arg((str != 0),"str"); + + stat.code = ICAL_UNKNOWN_STATUS; + stat.debug = 0; + + stat.desc = 0; + + /* Get the status numbers */ + + sscanf(str, "%d.%d",&major, &minor); + + if (major <= 0 || minor < 0){ + icalerror_set_errno(ICAL_BADARG_ERROR); + return stat; + } + + stat.code = icalenum_num_to_reqstat(major, minor); + + if (stat.code == ICAL_UNKNOWN_STATUS){ + icalerror_set_errno(ICAL_BADARG_ERROR); + return stat; + } + + + p1 = strchr(str,';'); + + if (p1 == 0){ + icalerror_set_errno(ICAL_BADARG_ERROR); + return stat; + } + + /* Just ignore the second clause; it will be taken from inside the library + */ + + + + p2 = strchr(p1+1,';'); + if (p2 != 0 && *p2 != 0){ + stat.debug = p2+1; + } + + return stat; + +} + +char* icalreqstattype_as_string(struct icalreqstattype stat) +{ + char format[20]; + char *temp; + + temp = (char*)icalmemory_tmp_buffer(TEMP_MAX); + + icalerror_check_arg_rz((stat.code != ICAL_UNKNOWN_STATUS),"Status"); + + if (stat.desc == 0){ + stat.desc = icalenum_reqstat_desc(stat.code); + } + + if(stat.debug != 0){ + snprintf(temp,TEMP_MAX,"%d.%d;%s;%s", icalenum_reqstat_major(stat.code), + icalenum_reqstat_minor(stat.code), + stat.desc, stat.debug); + + } else { + snprintf(temp,TEMP_MAX,"%d.%d;%s", icalenum_reqstat_major(stat.code), + icalenum_reqstat_minor(stat.code), + stat.desc); + } + + return temp; +} diff --git a/libical/src/libical/icaltypes.h b/libical/src/libical/icaltypes.h index c33e8acd7d..77a67fae80 100644 --- a/libical/src/libical/icaltypes.h +++ b/libical/src/libical/icaltypes.h @@ -157,12 +157,26 @@ union icaltriggertype struct icaldurationtype duration; }; -struct icalrequestsstatustype { - short minor; - short major; +/* struct icalreqstattype. This struct contains two string pointers, +but don't try to free either of them. The "desc" string is a pointer +to a static table inside the library. Don't try to free it. The +"debug" string is a pointer into the string that the called passed +into to icalreqstattype_from_string. Don't try to free it either, and +don't use it after the original string has been freed. +BTW, you would get that original string from +*icalproperty_get_requeststatus() or icalvalue_get_text(), when +operating on a the value of a request_status property. */ + +struct icalreqstattype { + + icalrequeststatus code; + char* desc; + char* debug; }; +struct icalreqstattype icalreqstattype_from_string(char* str); +char* icalreqstattype_as_string(struct icalreqstattype); #endif /* !ICALTYPES_H */ diff --git a/libical/src/libical/icalvalue.c b/libical/src/libical/icalvalue.c index 1ed83a0c6e..ec332a0f04 100644 --- a/libical/src/libical/icalvalue.c +++ b/libical/src/libical/icalvalue.c @@ -28,6 +28,10 @@ ======================================================================*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "ical.h" #include "icalerror.h" @@ -38,6 +42,7 @@ #include /* for malloc */ #include /* for sprintf */ #include /* For memset, others */ +#include /* For offsetof() macro */ #include #include /* for mktime */ #include /* for atoi and atof */ @@ -47,6 +52,8 @@ #include "strdup.h" #endif +#define TMP_BUF_SIZE 1024 + void print_datetime_to_string(char* str, struct icaltimetype *data); void print_date_to_string(char* str, struct icaltimetype *data); void print_time_to_string(char* str, struct icaltimetype *data); @@ -97,7 +104,6 @@ struct icalvalue_impl* icalvalue_new_impl(icalvalue_kind kind){ if ( ( v = (struct icalvalue_impl*) malloc(sizeof(struct icalvalue_impl))) == 0) { - errno = ENOMEM; icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } @@ -147,6 +153,7 @@ icalvalue* icalvalue_new_clone(icalvalue* value){ /* HACK ugh. I don't feel like impleenting this */ } + case ICAL_STRING_VALUE: case ICAL_TEXT_VALUE: case ICAL_CALADDRESS_VALUE: case ICAL_URI_VALUE: @@ -207,7 +214,7 @@ icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind,char* str,ic value = 0; if (error != 0){ - char temp[1024]; + char temp[TMP_BUF_SIZE]; sprintf(temp,"ATTACH Values are not implemented"); *error = icalproperty_vanew_xlicerror( temp, @@ -226,7 +233,7 @@ icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind,char* str,ic value = 0; if (error != 0){ - char temp[1024]; + char temp[TMP_BUF_SIZE]; sprintf(temp,"BINARY Values are not implemented"); *error = icalproperty_vanew_xlicerror( temp, @@ -245,7 +252,7 @@ icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind,char* str,ic value = 0; if (error != 0){ - char temp[1024]; + char temp[TMP_BUF_SIZE]; sprintf(temp,"BOOLEAN Values are not implemented"); *error = icalproperty_vanew_xlicerror( temp, @@ -282,6 +289,13 @@ icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind,char* str,ic break; } + + case ICAL_STRING_VALUE: + { + value = icalvalue_new_string(str); + break; + } + case ICAL_CALADDRESS_VALUE: { value = icalvalue_new_caladdress(str); @@ -298,6 +312,8 @@ icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind,char* str,ic { icalproperty_method method = icalenum_string_to_method(str); value = icalvalue_new_method(method); + break; + } case ICAL_GEO_VALUE: { @@ -305,7 +321,7 @@ icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind,char* str,ic /* HACK */ if (error != 0){ - char temp[1024]; + char temp[TMP_BUF_SIZE]; sprintf(temp,"GEO Values are not implemented"); *error = icalproperty_vanew_xlicerror( temp, @@ -337,15 +353,10 @@ icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind,char* str,ic { if (error != 0 ){ - char temp[1024]; + char temp[TMP_BUF_SIZE]; - if (strlen(str) > 265) { - sprintf(temp,"Unknown type for \'%256s...\'",str); - } else { - sprintf(temp,"Unknown type for \'%s\'",str); + snprintf(temp,TMP_BUF_SIZE,"Unknown type for \'%s\'",str); - } - *error = icalproperty_vanew_xlicerror( temp, icalparameter_new_xlicerrortype( @@ -360,14 +371,9 @@ icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind,char* str,ic if (error != 0 && *error == 0 && value == 0){ - char temp[1024]; + char temp[TMP_BUF_SIZE]; - if (strlen(str) > 265) { - sprintf(temp,"Failed to parse value: \'%256s...\'",str); - } else { - sprintf(temp,"Failed to parse value: \'%s\'",str); - - } + snprintf(temp,TMP_BUF_SIZE,"Failed to parse value: \'%s\'",str); *error = icalproperty_vanew_xlicerror( temp, @@ -529,20 +535,22 @@ char* icalvalue_recur_as_ical_string(icalvalue* value) struct icalvalue_impl *impl = (struct icalvalue_impl*)value; struct icalrecurrencetype *recur = impl->data.v_recur; - struct { char* str; short* array; short limit; } map[] = - { - {";BYSECOND=",recur->by_second,60}, - {";BYMINUTE=",recur->by_minute,60}, - {";BYHOUR=",recur->by_hour,24}, - {";BYDAY=",recur->by_day,7}, - {";BYMONTHDAY=",recur->by_month_day,31}, - {";BYYEARDAY=",recur->by_year_day,366}, - {";BYWEEKNO=",recur->by_week_no,52}, - {";BYMONTH=",recur->by_month,12}, - {";BYSETPOS=",recur->by_set_pos,366}, - {0,0,0}, - }; - + struct { char* str;size_t offset; short limit; } recurmap[] = + { + {";BYSECOND=",offsetof(struct icalrecurrencetype,by_second),60}, + {";BYMINUTE=",offsetof(struct icalrecurrencetype,by_minute),60}, + {";BYHOUR=",offsetof(struct icalrecurrencetype,by_hour),24}, + {";BYDAY=",offsetof(struct icalrecurrencetype,by_day),7}, + {";BYMONTHDAY=",offsetof(struct icalrecurrencetype,by_month_day),31}, + {";BYYEARDAY=",offsetof(struct icalrecurrencetype,by_year_day),366}, + {";BYWEEKNO=",offsetof(struct icalrecurrencetype,by_week_no),52}, + {";BYMONTH=",offsetof(struct icalrecurrencetype,by_month),12}, + {";BYSETPOS=",offsetof(struct icalrecurrencetype,by_set_pos),366}, + {0,0,0}, + }; + + + icalerror_check_arg_rz((value != 0),"value"); if(recur->freq == ICAL_NO_RECURRENCE){ @@ -577,14 +585,14 @@ char* icalvalue_recur_as_ical_string(icalvalue* value) icalmemory_append_string(&str,&str_p,&buf_sz, temp); } - for(j =0; map[j].str != 0; j++){ - short* array = map[j].array; - short limit = map[j].limit; + for(j =0; recurmap[j].str != 0; j++){ + short* array = (short*)(recurmap[j].offset+ (size_t)recur); + short limit = recurmap[j].limit; /* Skip unused arrays */ if( array[0] != ICAL_RECURRENCE_ARRAY_MAX ) { - icalmemory_append_string(&str,&str_p,&buf_sz,map[j].str); + icalmemory_append_string(&str,&str_p,&buf_sz,recurmap[j].str); for(i=0; i< limit && array[i] != ICAL_RECURRENCE_ARRAY_MAX; i++){ @@ -731,11 +739,11 @@ char* icalvalue_attach_as_ical_string(icalvalue* value) { void append_duration_segment(char** buf, char** buf_ptr, size_t* buf_size, char* sep, unsigned int value) { - char digits[256]; /* HACK: large hardcoded limit */ + char temp[TMP_BUF_SIZE]; - sprintf(digits,"%d",value); + sprintf(temp,"%d",value); - icalmemory_append_string(buf, buf_ptr, buf_size, digits); + icalmemory_append_string(buf, buf_ptr, buf_size, temp); icalmemory_append_string(buf, buf_ptr, buf_size, sep); } @@ -1025,6 +1033,7 @@ icalvalue_as_ical_string (icalvalue* value) case ICAL_TEXT_VALUE: return icalvalue_text_as_ical_string(value); + case ICAL_STRING_VALUE: case ICAL_URI_VALUE: case ICAL_CALADDRESS_VALUE: return icalvalue_string_as_ical_string(value); @@ -1155,7 +1164,7 @@ icalvalue_compare(icalvalue* a, icalvalue *b) case ICAL_DATE_VALUE: case ICAL_DATETIME_VALUE: case ICAL_DATETIMEDATE_VALUE: - case ICAL_DURATION_VALUE: + case ICAL_DURATION_VALUE: /* HACK. Not correct for DURATION */ case ICAL_TIME_VALUE: case ICAL_DATETIMEPERIOD_VALUE: { @@ -1216,7 +1225,9 @@ icalproperty* icalvalue_get_parent(icalvalue* value) -/* Recur is a special case, so it is not auto generated */ +/* Recur is a special case, so it is not auto generated. Well, + actually, it is auto-generated, but you will have to manually + remove the auto-generated version after each generation. */ icalvalue* icalvalue_new_recur (struct icalrecurrencetype v) { @@ -1762,89 +1773,74 @@ icalvalue_get_period(icalvalue* value) icalvalue* -icalvalue_new_text (char* v) +icalvalue_new_string (char* v) { - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_TEXT_VALUE); + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_STRING_VALUE); icalerror_check_arg_rz( (v!=0),"v"); - icalvalue_set_text((icalvalue*)impl,v); + icalvalue_set_string((icalvalue*)impl,v); return (icalvalue*)impl; } void -icalvalue_set_text(icalvalue* value, char* v) +icalvalue_set_string(icalvalue* value, char* v) { struct icalvalue_impl* impl; - char *p,*d; - + icalerror_check_arg_rv( (value!=0),"value"); icalerror_check_arg_rv( (v!=0),"v"); - icalerror_check_value_type(value, ICAL_TEXT_VALUE); + icalerror_check_value_type(value, ICAL_STRING_VALUE); impl = (struct icalvalue_impl*)value; - impl->data.v_string = malloc(strlen(v)+1); + impl->data.v_string = strdup(v); if (impl->data.v_string == 0){ errno = ENOMEM; - return; } - for(d=impl->data.v_string,p=v; *p!=0; p++){ +} - if (*p == '\\') { - p++; +char* +icalvalue_get_string(icalvalue* value) +{ + icalerror_check_arg( (value!=0),"value"); + icalerror_check_value_type(value, ICAL_STRING_VALUE); + + return ((struct icalvalue_impl*)value)->data.v_string; +} - if (p == 0){ - break; - } - switch(*p){ - case 'n': { - *d='\n';d++; - break; - } +icalvalue* +icalvalue_new_text (char* v) +{ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_TEXT_VALUE); + + icalerror_check_arg_rz( (v!=0),"v"); - case '\\': { - *d='\\';d++; - break; - } - - case 't': { - *d='\n';d++; - break; - } - case 'r': { - *d='\r';d++; - break; - } - case 'b': { - *d='\b';d++; - break; - } - case 'f': { - *d='\f';d++; - break; - } - - case ';': - case ',':{ - *d=*p;d++; - break; - } + icalvalue_set_text((icalvalue*)impl,v); - case '"':{ - *d='\"';d++; - break; - } - } - } else { - *d=*p;d++; - } + return (icalvalue*)impl; +} + +void +icalvalue_set_text(icalvalue* value, char* v) +{ + struct icalvalue_impl* impl; + + icalerror_check_arg_rv( (value!=0),"value"); + icalerror_check_arg_rv( (v!=0),"v"); + + icalerror_check_value_type(value, ICAL_TEXT_VALUE); + + impl = (struct icalvalue_impl*)value; + impl->data.v_string = strdup(v); + + if (impl->data.v_string == 0){ + errno = ENOMEM; } - *d='\0'; } diff --git a/libical/src/libical/icalvalue.h b/libical/src/libical/icalvalue.h index b5a2e6da9e..ec7457d6aa 100644 --- a/libical/src/libical/icalvalue.h +++ b/libical/src/libical/icalvalue.h @@ -131,6 +131,11 @@ icalvalue* icalvalue_new_recur(struct icalrecurrencetype v); struct icalrecurrencetype icalvalue_get_recur(icalvalue* value); void icalvalue_set_recur(icalvalue* value, struct icalrecurrencetype v); +/* STRING # Non-std */ +icalvalue* icalvalue_new_string(char* v); +char* icalvalue_get_string(icalvalue* value); +void icalvalue_set_string(icalvalue* value, char* v); + /* TEXT */ icalvalue* icalvalue_new_text(char* v); char* icalvalue_get_text(icalvalue* value); diff --git a/libical/src/libical/icalversion.h b/libical/src/libical/icalversion.h new file mode 100644 index 0000000000..3d5f132a3f --- /dev/null +++ b/libical/src/libical/icalversion.h @@ -0,0 +1,3 @@ + +#define ICAL_PACKAGE "libical" +#define ICAL_VERSION "0.16" diff --git a/libical/src/libical/icalversion.h.in b/libical/src/libical/icalversion.h.in new file mode 100644 index 0000000000..aaeeed6666 --- /dev/null +++ b/libical/src/libical/icalversion.h.in @@ -0,0 +1,3 @@ + +#define ICAL_PACKAGE "@PACKAGE@" +#define ICAL_VERSION "@VERSION@" diff --git a/libical/src/libical/icalyacc.y b/libical/src/libical/icalyacc.y new file mode 100644 index 0000000000..63fff212a2 --- /dev/null +++ b/libical/src/libical/icalyacc.y @@ -0,0 +1,480 @@ +%{ +/* -*- Mode: C -*- + ====================================================================== + FILE: icalitip.y + CREATOR: eric 10 June 1999 + + DESCRIPTION: + + $Id: icalyacc.y,v 1.1 2000/04/18 18:17:05 alves 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 icalitip.y + + + + ================================b======================================*/ + +#include +#include /* for strdup() */ +#include /* for SHRT_MAX*/ +#include "icalparser.h" +#include "ical.h" +#include "pvl.h" +#define YYERROR_VERBOSE +#define YYDEBUG 1 + + +icalvalue *icalparser_yy_value; /* Current Value */ + +/* Globals for UTCOFFSET values */ +int utc; +int utc_b; +int utcsign; + +/* Globals for DURATION values */ +struct icaldurationtype duration; + +/* Globals for RECUR values */ +struct icalrecurrencetype recur; +short skiplist[367]; +short skippos; + +void copy_list(short* array, size_t size); +void clear_recur(); +void add_prop(icalproperty_kind); +void icalparser_fill_date(struct tm* t, char* dstr); +void icalparser_fill_time(struct tm* t, char* tstr); +void set_value_type(icalvalue_kind kind); +void set_parser_value_state(); +struct icaltimetype fill_datetime(char* d, char* t); +void ical_yy_error(char *s); /* Don't know why I need this.... */ +/*int yylex(void); /* Or this. */ + + + +/* Set the state of the lexer so it will interpret values ( iCAL + VALUEs, that is, ) correctly. */ + +%} + +%union { + float v_float; + int v_int; + char* v_string; + + /* Renaming hack */ +#define yymaxdepth ical_yy_maxdepth +#define yyparse ical_yy_parse +#define yylex ical_yy_lex +#define yyerror ical_yy_error +#define yylval ical_yy_lval +#define yychar ical_yy_char +#define yydebug ical_yy_debug +#define yypact ical_yy_pact +#define yyr1 ical_yy_r1 +#define yyr2 ical_yy_r2 +#define yydef ical_yy_def +#define yychk ical_yy_chk +#define yypgo ical_yy_pgo +#define yyact ical_yy_act +#define yyexca ical_yy_exca +#define yyerrflag ical_yy_errflag +#define yynerrs ical_yy_nerrs +#define yyps ical_yy_ps +#define yypv ical_yy_pv +#define yys ical_yy_s +#define yy_yys ical_yy_yys +#define yystate ical_yy_state +#define yytmp ical_yy_tmp +#define yyv ical_yy_v +#define yy_yyv ical_yy_yyv +#define yyval ical_yy_val +#define yylloc ical_yy_lloc +#define yyreds ical_yy_reds +#define yytoks ical_yy_toks +#define yylhs ical_yy_yylhs +#define yylen ical_yy_yylen +#define yydefred ical_yy_yydefred +#define yydgoto ical_yy_yydgoto +#define yydefred ical_yy_yydefred +#define yydgoto ical_yy_yydgoto +#define yysindex ical_yy_yysindex +#define yyrindex ical_yy_yyrindex +#define yygindex ical_yy_yygindex +#define yytable ical_yy_yytable +#define yycheck ical_yy_yycheck +#define yyname ical_yy_yyname +#define yyrule ical_yy_yyrule + + + +} + +%token DIGITS +%token INTNUMBER +%token FLOATNUMBER +%token STRING +%token EOL EQUALS CHARACTER COLON COMMA SEMICOLON TIMESEPERATOR + +%token TRUE FALSE + +%token FREQ BYDAY BYHOUR BYMINUTE BYMONTH BYMONTHDAY BYSECOND BYSETPOS BYWEEKNO +%token BYYEARDAY DAILY MINUTELY MONTHLY SECONDLY WEEKLY HOURLY YEARLY +%token INTERVAL COUNT UNTIL WKST MO SA SU TU WE TH FR + +%token BIT8 ACCEPTED ADD AUDIO BASE64 BINARY BOOLEAN BUSY BUSYTENTATIVE +%token BUSYUNAVAILABLE CALADDRESS CANCEL CANCELLED CHAIR CHILD COMPLETED +%token CONFIDENTIAL CONFIRMED COUNTER DATE DATETIME DECLINECOUNTER DECLINED +%token DELEGATED DISPLAY DRAFT DURATION EMAIL END FINAL FLOAT FREE GREGORIAN +%token GROUP INDIVIDUAL INPROCESS INTEGER NEEDSACTION NONPARTICIPANT +%token OPAQUE OPTPARTICIPANT PARENT PERIOD PRIVATE PROCEDURE PUBLIC PUBLISH +%token RECUR REFRESH REPLY REQPARTICIPANT REQUEST RESOURCE ROOM SIBLING +%token START TENTATIVE TEXT THISANDFUTURE THISANDPRIOR TIME TRANSPAENT +%token UNKNOWN UTCOFFSET XNAME + +%token ALTREP CN CUTYPE DAYLIGHT DIR ENCODING EVENT FBTYPE FMTTYPE LANGUAGE +%token MEMBER PARTSTAT RANGE RELATED RELTYPE ROLE RSVP SENTBY STANDARD URI + +%token TIME_CHAR UTC_CHAR + + +%% + +value: + binary_value + | boolean_value + | date_value + | datetime_value + | duration_value + | period_value + | recur_value + | utcoffset_value + | error { + icalparser_yy_value = 0; + icalparser_clear_flex_input(); + yyclearin; + } + +binary_value: "unimplemented2" + +boolean_value: + TRUE + { icalparser_yy_value = icalvalue_new_boolean(1); } + | FALSE + { icalparser_yy_value = icalvalue_new_boolean(0); } + +date_value: DIGITS + { + struct icaltimetype stm; + + stm = fill_datetime($1,0); + + stm.hour = -1; + stm.minute = -1; + stm.second = -1; + stm.is_utc = 0; + stm.is_date = 1; + + icalparser_yy_value = icalvalue_new_date(stm); + } + +utc_char: + /*empty*/ {utc = 0;} + | UTC_CHAR {utc = 1;} + +/* This is used in the period_value, where there may be two utc characters per rule. */ +utc_char_b: + /*empty*/ {utc_b = 0;} + | UTC_CHAR {utc_b = 1;} + +datetime_value: + DIGITS TIME_CHAR DIGITS utc_char + { + struct icaltimetype stm; + stm = fill_datetime($1, $3); + stm.is_utc = utc; + stm.is_date = 0; + + icalparser_yy_value = + icalvalue_new_datetime(stm); + } + + +/* Duration */ + + +dur_date: dur_day + | dur_day dur_time + +dur_week: DIGITS 'W' + { + duration.weeks = atoi($1); + } + +dur_time: TIME_CHAR dur_hour + { + } + | TIME_CHAR dur_minute + { + } + | TIME_CHAR dur_second + { + } + +dur_hour: DIGITS 'H' + { + duration.hours = atoi($1); + } + | DIGITS 'H' dur_minute + { + duration.hours = atoi($1); + } + +dur_minute: DIGITS 'M' + { + duration.minutes = atoi($1); + } + | DIGITS 'M' dur_second + { + duration.minutes = atoi($1); + } + +dur_second: DIGITS 'S' + { + duration.seconds = atoi($1); + } + +dur_day: DIGITS 'D' + { + duration.days = atoi($1); + } + +dur_prefix: /* empty */ + { + } + | '+' + { + } + | '-' + { + } + +duration_value: dur_prefix 'P' dur_date + { + icalparser_yy_value = icalvalue_new_duration(duration); + memset(&duration,0, sizeof(duration)); + } + | dur_prefix 'P' dur_time + { + icalparser_yy_value = icalvalue_new_duration(duration); + memset(&duration,0, sizeof(duration)); + } + | dur_prefix 'P' dur_week + { + icalparser_yy_value = icalvalue_new_duration(duration); + memset(&duration,0, sizeof(duration)); + } + + +/* Period */ + +period_value: DIGITS TIME_CHAR DIGITS utc_char '/' DIGITS TIME_CHAR DIGITS utc_char_b + { + struct icalperiodtype p; + + p.start = fill_datetime($1,$3); + p.start.is_utc = utc; + p.start.is_date = 0; + + + p.end = fill_datetime($6,$8); + p.end.is_utc = utc_b; + p.end.is_date = 0; + + p.duration.days = -1; + p.duration.weeks = -1; + p.duration.hours = -1; + p.duration.minutes = -1; + p.duration.seconds = -1; + + icalparser_yy_value = icalvalue_new_period(p); + } + | DIGITS TIME_CHAR DIGITS utc_char '/' duration_value + { + struct icalperiodtype p; + + p.start = fill_datetime($1,$3); + p.start.is_utc = utc; + p.start.is_date = 0; + + p.end.year = -1; + p.end.month = -1; + p.end.day = -1; + p.end.hour = -1; + p.end.minute = -1; + p.end.second = -1; + + /* The duration_value rule setes the global 'duration' + variable, but it also creates a new value in + icalparser_yy_value. So, free that, then copy + 'duration' into the icalperiodtype struct. */ + + p.duration = icalvalue_get_duration(icalparser_yy_value); + icalvalue_free(icalparser_yy_value); + icalparser_yy_value = 0; + + icalparser_yy_value = icalvalue_new_period(p); + + } + + + +/* Recur */ + +recur_start: + FREQ EQUALS SECONDLY {clear_recur();recur.freq = ICAL_SECONDLY_RECURRENCE;} + | FREQ EQUALS MINUTELY {clear_recur();recur.freq = ICAL_MINUTELY_RECURRENCE;} + | FREQ EQUALS HOURLY {clear_recur();recur.freq = ICAL_HOURLY_RECURRENCE;} + | FREQ EQUALS DAILY {clear_recur();recur.freq = ICAL_DAILY_RECURRENCE;} + | FREQ EQUALS WEEKLY {clear_recur();recur.freq = ICAL_WEEKLY_RECURRENCE;} + | FREQ EQUALS MONTHLY {clear_recur();recur.freq = ICAL_MONTHLY_RECURRENCE;} + | FREQ EQUALS YEARLY {clear_recur();recur.freq = ICAL_YEARLY_RECURRENCE;} + ; + + +weekday: + SU { skiplist[skippos]=ICAL_SUNDAY_WEEKDAY; if( skippos<8) skippos++;} + | MO { skiplist[skippos]=ICAL_MONDAY_WEEKDAY;if( skippos<8) skippos++;} + | TU { skiplist[skippos]=ICAL_TUESDAY_WEEKDAY;if( skippos<8) skippos++;} + | WE { skiplist[skippos]=ICAL_WEDNESDAY_WEEKDAY;if( skippos<8) skippos++;} + | TH { skiplist[skippos]=ICAL_THURSDAY_WEEKDAY;if( skippos<8) skippos++;} + | FR { skiplist[skippos]=ICAL_FRIDAY_WEEKDAY;if( skippos<8) skippos++;} + | SA { skiplist[skippos]=ICAL_SATURDAY_WEEKDAY;if( skippos<8) skippos++;} + ; + + +weekday_list: + weekday + | DIGITS weekday { } /* HACK Incorectly handles int in BYDAY */ + | weekday_list COMMA weekday + + +recur_list: + DIGITS { skiplist[skippos] = atoi($1); skippos++;} + | recur_list COMMA DIGITS { skiplist[skippos] = atoi($3); if (skippos<367) skippos++;} + ; + +recur_skip: + INTERVAL EQUALS DIGITS {recur.interval = atoi($3);} + | WKST EQUALS SU {recur.week_start = ICAL_SUNDAY_WEEKDAY;} + | WKST EQUALS MO {recur.week_start = ICAL_MONDAY_WEEKDAY;} + | WKST EQUALS TU {recur.week_start = ICAL_TUESDAY_WEEKDAY;} + | WKST EQUALS WE {recur.week_start = ICAL_WEDNESDAY_WEEKDAY;} + | WKST EQUALS TH {recur.week_start = ICAL_THURSDAY_WEEKDAY;} + | WKST EQUALS FR {recur.week_start = ICAL_FRIDAY_WEEKDAY;} + | WKST EQUALS SA {recur.week_start = ICAL_SATURDAY_WEEKDAY;} + | BYSECOND EQUALS recur_list{copy_list(recur.by_second,60);} + | BYMINUTE EQUALS recur_list{copy_list(recur.by_minute,60);} + | BYHOUR EQUALS recur_list{copy_list(recur.by_hour,24);} + | BYDAY EQUALS weekday_list{copy_list(recur.by_day,7);} + | BYMONTH EQUALS recur_list{copy_list(recur.by_month,12);} + | BYMONTHDAY EQUALS recur_list{copy_list(recur.by_month_day,31);} + | BYYEARDAY EQUALS recur_list{copy_list(recur.by_year_day,366);} + | BYWEEKNO EQUALS recur_list{copy_list(recur.by_week_no,53);} + | BYSETPOS EQUALS recur_list{copy_list(recur.by_set_pos,366);} + | UNTIL EQUALS datetime_value + { recur.until = icalvalue_get_datetime(icalparser_yy_value); + icalvalue_free(icalparser_yy_value); icalparser_yy_value=0;} + | UNTIL EQUALS date_value + { recur.until = icalvalue_get_date(icalparser_yy_value); + icalvalue_free(icalparser_yy_value); icalparser_yy_value=0;} + | COUNT EQUALS DIGITS + { recur.count = atoi($3); } + ; + +recur_skip_list: + /* empty */ + | recur_skip_list SEMICOLON recur_skip + +recur_value: + recur_start recur_skip_list + { icalparser_yy_value = icalvalue_new_recur(recur); } + + + +/* UTC Offset */ + +plusminus: '+' { utcsign = 1; } + | '-' { utcsign = -1; } + +utcoffset_value: + plusminus INTNUMBER INTNUMBER + { + icalparser_yy_value = icalvalue_new_utcoffset( utcsign * ($2*3600) + ($3*60) ); + } + + | plusminus INTNUMBER INTNUMBER INTNUMBER + { + icalparser_yy_value = icalvalue_new_utcoffset(utcsign * ($2*3600) + ($3*60) +($4)); + } + + + +%% + + +void clear_recur() +{ + memset(&skiplist, ICAL_RECURRENCE_ARRAY_MAX_BYTE, sizeof(skiplist)); + skippos = 0; + + icalrecurrencetype_clear(&recur); +} + +void copy_list(short* array, size_t size) +{ + memcpy(array, skiplist, size*sizeof(short)); + memset(&skiplist,ICAL_RECURRENCE_ARRAY_MAX_BYTE, sizeof(skiplist)); + skippos = 0; +} + +struct icaltimetype fill_datetime(char* datestr, char* timestr) +{ + struct icaltimetype stm; + + memset(&stm,0,sizeof(stm)); + + if (datestr != 0){ + sscanf(datestr,"%4d%2d%2d",&(stm.year), &(stm.month), + &(stm.day)); + } + + if (timestr != 0){ + sscanf(timestr,"%2d%2d%2d", &(stm.hour), &(stm.minute), + &(stm.second)); + } + + return stm; + +} + +void yyerror(char* s) +{ + /*fprintf(stderr,"Parse error \'%s\'\n", s);*/ +} + diff --git a/libical/src/libical/pvl.c b/libical/src/libical/pvl.c index b88272a6a0..d5225a541e 100644 --- a/libical/src/libical/pvl.c +++ b/libical/src/libical/pvl.c @@ -17,6 +17,10 @@ limitations under the License. ======================================================================*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "pvl.h" #include #include diff --git a/libical/src/libicalss/Makefile.am b/libical/src/libicalss/Makefile.am index d2f65de885..4d05257e8b 100644 --- a/libical/src/libicalss/Makefile.am +++ b/libical/src/libicalss/Makefile.am @@ -1,13 +1,21 @@ -INCLUDES = \ - -I$(top_srcdir)/src/libical - -lib_LTLIBRARIES = libicalss.la - -libicalss_la_SOURCES = \ - icalcalendar.c \ - icalcalendar.h \ - icalcluster.c \ - icalcluster.h \ - icalcomponent.h \ - icalstore.c \ + + +#noinst_LTLIBRARIES = libicalss.la +lib_LIBRARIES = libicalss.a + +libicalss_a_SOURCES =\ + icalcalendar.c \ + icalcalendar.h \ + icalcluster.c \ + icalcluster.h \ + icalstore.c \ + icalstore.h + +include_HEADERS =\ + icalcalendar.h \ + icalcluster.h \ icalstore.h + + +INCLUDES = -I../libical/ + diff --git a/libical/src/libicalss/icalcalendar.c b/libical/src/libicalss/icalcalendar.c index 0933df1e31..0f2231b1d7 100644 --- a/libical/src/libicalss/icalcalendar.c +++ b/libical/src/libicalss/icalcalendar.c @@ -26,6 +26,11 @@ ======================================================================*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + #include "icalcalendar.h" #include "icalcluster.h" #include diff --git a/libical/src/libicalss/icalcluster.c b/libical/src/libicalss/icalcluster.c index c0160cc6c3..36bdccc743 100644 --- a/libical/src/libicalss/icalcluster.c +++ b/libical/src/libicalss/icalcluster.c @@ -26,6 +26,11 @@ ======================================================================*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + #include "icalcluster.h" #include #include /* For PATH_MAX */ @@ -33,11 +38,16 @@ #include /* for stat, getpid */ #include #include +#include /* for fcntl */ +#include /* for fcntl */ + +icalerrorenum icalcluster_create_cluster(char *path); struct icalcluster_impl { char *path; icalcomponent* cluster; int changed; + FILE* stream; }; icalcluster* icalcluster_new_impl() @@ -54,136 +64,24 @@ icalcluster* icalcluster_new_impl() return comp; } -icalerrorenum icalcluster_create_cluster(char *path) -{ - - FILE* f; - int r; - icalcomponent *c; - struct icaltimetype tt; - - icalerror_clear_errno(); - - f = fopen(path,"w"); - - if (f == 0){ - icalerror_set_errno(ICAL_FILE_ERROR); - return ICAL_FILE_ERROR; - } - - /* Create the root component in the cluster. This component holds - all of the other components and stores a count of - components. */ - - memset(&tt,0,sizeof(struct icaltimetype)); - - c = icalcomponent_vanew( - ICAL_VCALENDAR_COMPONENT, - icalproperty_new_xlicclustercount(0), - icalproperty_new_dtstart(tt), /* dtstart of earliest comp */ - icalproperty_new_dtend(tt), /* dtend of latest comp, excl. recuring */ - 0 - ); - - if (c == 0){ - fclose(f); - icalerror_set_errno(ICAL_INTERNAL_ERROR); - return ICAL_INTERNAL_ERROR; - } - - - /* Write the base component to the file */ - r = fputs(icalcomponent_as_ical_string(c),f); - - fclose(f); - - icalcomponent_free(c); - - if (r == EOF){ - icalerror_set_errno(ICAL_FILE_ERROR); - return ICAL_FILE_ERROR; - } - - return ICAL_NO_ERROR; -} - -FILE* parser_file; /*HACK. Not Thread Safe */ -char* read_from_file(char *s, size_t size) +char* read_from_file(char *s, size_t size, void *d) { - char *c = fgets(s,size, parser_file); + char *c = fgets(s,size, (FILE*)d); return c; } -icalerrorenum icalcluster_load(icalcluster* cluster, char* path) -{ - struct icalcluster_impl *impl = (struct icalcluster_impl*)cluster; - icalerrorenum error; - errno = 0; - - icalerror_check_arg_rz((cluster!=0),"cluster"); - icalerror_check_arg_rz((path!=0),"path"); - - if(impl->path != 0 && strcmp(impl->path,path) == 0){ - /* Already have the right cluster, so return */ - return ICAL_NO_ERROR; - } - - error = icalcluster_commit(cluster); - - if (error != ICAL_NO_ERROR){ - icalerror_set_errno(error); - return error; - } - - free(impl->path); - - impl->path= (char*)strdup(path); - - parser_file = fopen(impl->path,"r"); - - /* HACK. Yeah, the following code is horrible....*/ - if (parser_file ==0 || errno != 0){ - - /* Try to create the cluster */ - error = icalcluster_create_cluster(path); - - if (error == ICAL_NO_ERROR){ - /* Try to open the parser again. */ - errno = 0; - parser_file = fopen(impl->path,"r"); - - if (parser_file ==0 || errno != 0){ - impl->cluster = 0; - icalerror_set_errno(ICAL_FILE_ERROR); - return ICAL_FILE_ERROR; - } - } else { - impl->cluster = 0; - icalerror_set_errno(error); /* Redundant, actually */ - return error; - } - } - - impl->cluster = icalparser_parse(read_from_file); - - fclose(parser_file); - - if (impl->cluster == 0){ - icalerror_set_errno(ICAL_PARSE_ERROR); - return ICAL_PARSE_ERROR; - } - - return ICAL_NO_ERROR; -} - - icalcluster* icalcluster_new(char* path) { struct icalcluster_impl *impl = icalcluster_new_impl(); struct stat sbuf; int createclusterfile = 0; - icalerrorenum error; - + icalerrorenum error = ICAL_NO_ERROR; + icalparser *parser; + struct icaltimetype tt; + off_t cluster_file_size; + + memset(&tt,0,sizeof(struct icaltimetype)); + icalerror_clear_errno(); icalerror_check_arg_rz( (path!=0), "path"); @@ -193,15 +91,18 @@ icalcluster* icalcluster_new(char* path) /*impl->path = strdup(path); icalcluster_load does this */ impl->changed = 0; + impl->cluster = 0; + impl->path = 0; + impl->stream = 0; /* Check if the path already exists and if it is a regular file*/ if (stat(path,&sbuf) != 0){ /* A file by the given name does not exist, or there was another error */ - + cluster_file_size = 0; if (errno == ENOENT) { /* It was because the file does not exist */ createclusterfile = 1; @@ -219,7 +120,8 @@ icalcluster* icalcluster_new(char* path) return 0; } else { /* Lets assume that it is a file of the right type */ - createclusterfile = 0; + cluster_file_size = sbuf.st_size; + createclusterfile = 0; } } @@ -233,8 +135,43 @@ icalcluster* icalcluster_new(char* path) return 0; } } + + impl->path = (char*)strdup(path); + + errno = 0; + impl->stream = fopen(impl->path,"r"); - error = icalcluster_load(impl,path); + if (impl->stream ==0 || errno != 0){ + impl->cluster = 0; + icalerror_set_errno(ICAL_FILE_ERROR); /* Redundant, actually */ + return 0; + } + + icalcluster_lock(impl); + + if(cluster_file_size > 0){ + parser = icalparser_new(); + icalparser_set_gen_data(parser,impl->stream); + impl->cluster = icalparser_parse(parser,read_from_file); + icalparser_free(parser); + + if (icalcomponent_isa(impl->cluster) != ICAL_XROOT_COMPONENT){ + /* The parser got a single component, so it did not put it in + an XROOT. */ + icalcomponent *cl = impl->cluster; + impl->cluster = icalcomponent_new(ICAL_XROOT_COMPONENT); + icalcomponent_add_component(impl->cluster,cl); + } + + } else { + + impl->cluster = icalcomponent_new(ICAL_XROOT_COMPONENT); + } + + if (impl->cluster == 0){ + icalerror_set_errno(ICAL_PARSE_ERROR); + return 0; + } if (error != ICAL_NO_ERROR){ return 0; @@ -260,46 +197,134 @@ void icalcluster_free(icalcluster* cluster) impl->path = 0; } + if(impl->stream != 0){ + icalcluster_unlock(impl); + fclose(impl->stream); + impl->stream = 0; + } + free(impl); } -icalerrorenum icalcluster_commit(icalcluster* cluster) +char* icalcluster_path(icalcluster* cluster) { - int ws; /* Size in char of file written to disk */ - FILE *f; + struct icalcluster_impl *impl = (struct icalcluster_impl*)cluster; + icalerror_check_arg_rz((cluster!=0),"cluster"); + + return impl->path; +} + +int icalcluster_lock(icalcluster *cluster) +{ struct icalcluster_impl *impl = (struct icalcluster_impl*)cluster; + struct flock lock; + int fd; - icalerror_check_arg_re((impl!=0),"cluster",ICAL_BADARG_ERROR); + icalerror_check_arg_rz((impl->stream!=0),"impl->stream"); - if (impl->changed != 0 ){ - /* write the cluster to disk */ + fd = fileno(impl->stream); - /* Construct a filename and write out the file */ - - if ( (f = fopen(impl->path,"w")) != 0){ + lock.l_type = F_WRLCK; /* F_RDLCK, F_WRLCK, F_UNLCK */ + lock.l_start = 0; /* byte offset relative to l_whence */ + lock.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */ + lock.l_len = 0; /* #bytes (0 means to EOF) */ + + return (fcntl(fd, F_SETLKW, &lock)); +} + +int icalcluster_unlock(icalcluster *cluster) +{ + struct icalcluster_impl *impl = (struct icalcluster_impl*)cluster; + int fd; + struct flock lock; + icalerror_check_arg_rz((impl->stream!=0),"impl->stream"); + + fd = fileno(impl->stream); + + lock.l_type = F_WRLCK; /* F_RDLCK, F_WRLCK, F_UNLCK */ + lock.l_start = 0; /* byte offset relative to l_whence */ + lock.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */ + lock.l_len = 0; /* #bytes (0 means to EOF) */ + + return (fcntl(fd, F_UNLCK, &lock)); + +} + +icalerrorenum icalcluster_create_cluster(char *path) +{ + + FILE* f; + int r; + icalcomponent *c; + + icalerror_clear_errno(); + + f = fopen(path,"w"); + + if (f == 0){ + icalerror_set_errno(ICAL_FILE_ERROR); + return ICAL_FILE_ERROR; + } + + + /* This used to write data to the file... */ - char* str = icalcomponent_as_ical_string(impl->cluster); - - ws = fwrite(str,sizeof(char),strlen(str),f); - - if ( ws < strlen(str)){ - fclose(f); - return ICAL_FILE_ERROR; - } + fclose(f); + + return ICAL_NO_ERROR; +} + +icalerrorenum icalcluster_commit(icalcluster* cluster) +{ + FILE *f; + char tmp[PATH_MAX]; /* HACK Buffer overflow potential */ + char *str; + icalparser *parser; + icalcomponent *c; + + struct icalcluster_impl *impl = (struct icalcluster_impl*)cluster; + + icalerror_check_arg_re((impl!=0),"cluster",ICAL_BADARG_ERROR); + + if (impl->changed == 0 ){ + return ICAL_NO_ERROR; + } + +#ifdef ICAL_SAFESAVES + snprintf(tmp,PATH_MAX,"%s-tmp",impl->path); +#else + strcpy(tmp,impl->path); +#endif + + if ( (f = fopen(tmp,"w")) < 0 ){ + icalerror_set_errno(ICAL_FILE_ERROR); + return ICAL_FILE_ERROR; + } + + for(c = icalcomponent_get_first_component(impl->cluster,ICAL_ANY_COMPONENT); + c != 0; + c = icalcomponent_get_next_component(impl->cluster,ICAL_ANY_COMPONENT)){ + + str = icalcomponent_as_ical_string(c); + + if ( fwrite(str,sizeof(char),strlen(str),f) < strlen(str)){ fclose(f); - impl->changed = 0; - return ICAL_NO_ERROR; - } else { - icalerror_set_errno(ICAL_FILE_ERROR); return ICAL_FILE_ERROR; } - - } - + } + + fclose(f); + impl->changed = 0; + +#ifdef ICAL_SAFESAVES + rename(tmp,impl->path); /* HACK, should check for error here */ +#endif + return ICAL_NO_ERROR; -} + +} void icalcluster_mark(icalcluster* cluster){ diff --git a/libical/src/libicalss/icalcluster.h b/libical/src/libicalss/icalcluster.h index 05c3a4b144..39fe542027 100644 --- a/libical/src/libicalss/icalcluster.h +++ b/libical/src/libicalss/icalcluster.h @@ -37,9 +37,7 @@ typedef void icalcluster; icalcluster* icalcluster_new(char* path); void icalcluster_free(icalcluster* cluster); - -/* Load a new file into the cluster */ -icalerrorenum icalcluster_load(icalcluster* cluster, char* path); +char* icalcluster_path(icalcluster* cluster); /* Return a reference to the internal component. */ icalcomponent* icalcluster_get_component(icalcluster* cluster); diff --git a/libical/src/libicalss/icalstore.c b/libical/src/libicalss/icalstore.c index 5d1546f3b2..382464e476 100644 --- a/libical/src/libicalss/icalstore.c +++ b/libical/src/libicalss/icalstore.c @@ -1,29 +1,29 @@ /* -*- Mode: C -*- - ====================================================================== - FILE: icalstore.c - CREATOR: eric 28 November 1999 + ====================================================================== + FILE: icalstore.c + CREATOR: eric 28 November 1999 - $Id$ - $Locker$ + $Id$ + $Locker$ - (C) COPYRIGHT 1999 Eric Busboom - http://www.softwarestudio.org + (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/ + 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. + 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 + The Original Code is eric. The Initial Developer of the Original + Code is Eric Busboom - ======================================================================*/ + ======================================================================*/ /* @@ -51,6 +51,11 @@ */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + #include "ical.h" #include "icalstore.h" #include "pvl.h" @@ -58,8 +63,6 @@ #include "icalparser.h" #include "icalcluster.h" -#include "filelock.h" - #include #include /* for opendir() */ #include @@ -95,25 +98,23 @@ struct icalstore_impl* icalstore_new_impl() return comp; } - - -void icalstore_lock_dir(char* dir) +void icalstore_lock(char* dir) { } -void icalstore_unlock_dir(char* dir) +void icalstore_unlock(char* dir) { } /* Load the contents of the store directory into the store's internal directory list*/ icalerrorenum icalstore_read_directory(struct icalstore_impl* impl) { - struct dirent *de; - DIR* dp; - char *str; + struct dirent *de; + DIR* dp; + char *str; - dp = opendir(impl->dir); + dp = opendir(impl->dir); if ( dp == 0) { icalerror_set_errno(ICAL_FILE_ERROR); @@ -166,7 +167,7 @@ icalstore* icalstore_new(char* dir) return 0; } - icalstore_lock_dir(dir); + icalstore_lock(dir); impl = icalstore_new_impl(); @@ -192,7 +193,7 @@ void icalstore_free(icalstore* s) struct icalstore_impl *impl = (struct icalstore_impl*)s; char* str; - icalstore_unlock_dir(impl->dir); + icalstore_unlock(impl->dir); if(impl->dir !=0){ free(impl->dir); @@ -298,10 +299,13 @@ icalerrorenum icalstore_next_cluster(icalstore* store) return ICAL_NO_ERROR; } - sprintf(path,"%s/%s",impl->dir,(char*)pvl_data(impl->directory_iterator)); - return icalcluster_load(impl->cluster,path); + icalcluster_free(impl->cluster); + + impl->cluster = icalcluster_new(path); + + return icalerrno; } void icalstore_add_uid(icalstore* store, icalstore* comp) @@ -310,8 +314,8 @@ void icalstore_add_uid(icalstore* store, icalstore* comp) icalproperty *uid; struct utsname unamebuf; - icalerror_check_arg_rz( (store!=0), "store"); - icalerror_check_arg_rz( (comp!=0), "comp"); + icalerror_check_arg_rv( (store!=0), "store"); + icalerror_check_arg_rv( (comp!=0), "comp"); uid = icalcomponent_get_first_property(comp,ICAL_UID_PROPERTY); @@ -319,7 +323,7 @@ void icalstore_add_uid(icalstore* store, icalstore* comp) uname(&unamebuf); - sprintf(uidstring,"%d-%s",getpid(),unamebuf.nodename); + sprintf(uidstring,"%d-%s",(int)getpid(),unamebuf.nodename); uid = icalproperty_new_uid(uidstring); icalcomponent_add_property(comp,uid); @@ -329,14 +333,20 @@ void icalstore_add_uid(icalstore* store, icalstore* comp) } } + +/* This assumes that the top level component is a VCALENDAR, and there + is an inner component of type VEVENT, VTODO or VJOURNAL. The inner + component must have a DTSTART property */ + icalerrorenum icalstore_add_component(icalstore* store, icalstore* comp) { struct icalstore_impl *impl; char clustername[PATH_MAX]; - icalproperty *dt, *count, *lm; + icalproperty *dt, *count; icalvalue *v; struct icaltimetype tm; icalerrorenum error = ICAL_NO_ERROR; + icalcomponent *inner; impl = (struct icalstore_impl*)store; icalerror_check_arg_rz( (store!=0), "store"); @@ -346,20 +356,21 @@ icalerrorenum icalstore_add_component(icalstore* store, icalstore* comp) icalstore_add_uid(store,comp); - /* Determine which cluster this object belongs in */ - - dt = icalcomponent_get_first_property(comp,ICAL_DTSTART_PROPERTY); + /* Determine which cluster this object belongs in. This is a HACK */ - if (dt == 0){ - dt = icalcomponent_get_first_property(comp,ICAL_DTSTAMP_PROPERTY); + for(inner = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT); + inner != 0; + inner = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT)){ + + dt = icalcomponent_get_first_property(inner,ICAL_DTSTART_PROPERTY); + + if (dt != 0){ + break; + } } if (dt == 0){ - dt = icalcomponent_get_first_property(comp,ICAL_CREATED_PROPERTY); - } - - if (dt == 0){ - icalerror_warn("The component does not have a DTSTART, DTSTAMP or a CREATED property, so it cannot be added to the store"); + icalerror_warn("The component does not have a DTSTART property, so it cannot be added to the store"); icalerror_set_errno(ICAL_BADARG_ERROR); return ICAL_BADARG_ERROR; } @@ -368,41 +379,29 @@ icalerrorenum icalstore_add_component(icalstore* store, icalstore* comp) tm = icalvalue_get_datetime(v); - sprintf(clustername,"%s/%04d%02d",impl->dir,tm.year,tm.month); + snprintf(clustername,PATH_MAX,"%s/%04d%02d",impl->dir,tm.year,tm.month); /* Load the cluster and insert the object */ + if(impl->cluster != 0 && + strcmp(clustername,icalcluster_path(impl->cluster)) != 0 ){ + icalcluster_free(impl->cluster); + impl->cluster = 0; + } + if (impl->cluster == 0){ impl->cluster = icalcluster_new(clustername); if (impl->cluster == 0){ error = icalerrno; } - } else { - error = icalcluster_load(impl->cluster, - clustername); - } - if (error != ICAL_NO_ERROR){ icalerror_set_errno(error); return error; } - /* Update or add the LAST-MODIFIED property */ - - lm = icalcomponent_get_first_property(comp, - ICAL_LASTMODIFIED_PROPERTY); - - if (lm == 0){ - lm = icalproperty_new_lastmodified(icaltimetype_from_timet( time(0),1)); - icalcomponent_add_property(comp,lm); - } else { - icalproperty_set_lastmodified(comp,icaltimetype_from_timet( time(0),1)); - } - - /* Add the component to the cluster */ icalcluster_add_component(impl->cluster,comp); @@ -419,7 +418,7 @@ icalerrorenum icalstore_add_component(icalstore* store, icalstore* comp) } icalproperty_set_xlicclustercount(count, - icalproperty_get_xlicclustercount(count)+1); + icalproperty_get_xlicclustercount(count)+1); icalcluster_mark(impl->cluster); @@ -438,38 +437,38 @@ icalerrorenum icalstore_remove_component(icalstore* store, icalstore* comp) icalerror_check_arg_re((impl->cluster!=0),"Cluster pointer",ICAL_USAGE_ERROR); /* HACK The following code should be used to ensure that the component -the caller is trying to remove is actually in the cluster, but it -resets the internal iterators, which immediately ends any loops over -the cluster the caller may have in progress - - for(c = icalcluster_get_first_component( - impl->cluster, - ICAL_ANY_COMPONENT); - c != 0; - c = icalcluster_get_next_component( - impl->cluster, - ICAL_ANY_COMPONENT)){ - - if (c == comp){ - found = 1; - } - - } - - if (found != 1){ - icalerror_warn("icalstore_remove_component: component is not part of current cluster"); - icalerror_set_errno(ICAL_USAGE_ERROR); - return ICAL_USAGE_ERROR; - } + the caller is trying to remove is actually in the cluster, but it + resets the internal iterators, which immediately ends any loops over + the cluster the caller may have in progress + + for(c = icalcluster_get_first_component( + impl->cluster, + ICAL_ANY_COMPONENT); + c != 0; + c = icalcluster_get_next_component( + impl->cluster, + ICAL_ANY_COMPONENT)){ + + if (c == comp){ + found = 1; + } + + } + + if (found != 1){ + icalerror_warn("icalstore_remove_component: component is not part of current cluster"); + icalerror_set_errno(ICAL_USAGE_ERROR); + return ICAL_USAGE_ERROR; + } */ icalcluster_remove_component(impl->cluster, - comp); + comp); icalcluster_mark(impl->cluster); - /* Decrement the clusters count value */ + /* Decrement the clusters count value */ count = icalcomponent_get_first_property( icalcluster_get_component(impl->cluster), ICAL_XLICCLUSTERCOUNT_PROPERTY); @@ -480,7 +479,7 @@ the cluster the caller may have in progress } icalproperty_set_xlicclustercount(count, - icalproperty_get_xlicclustercount(count)-1); + icalproperty_get_xlicclustercount(count)-1); return ICAL_NO_ERROR; } @@ -507,6 +506,7 @@ icalcomponent* icalstore_make_gauge(icalcomponent* query); Here is an example: + BEGIN:XROOT BEGIN:VCOMPONENT BEGIN:VEVENT DTSTART;X-LIC-COMPARETYPE=LESS:19981025T020000 @@ -516,76 +516,79 @@ icalcomponent* icalstore_make_gauge(icalcomponent* query); LOCATION;X-LIC-COMPARETYPE=EQUAL:McNary's Pub END:VEVENT END:VCALENDAR + END:XROOT This gauge has two sub-components; one which will match a VEVENT based on start time, and organizer, and another that matches based on LOCATION. A target component will pass the test if it matched - either of the gauge. + either of the sub-components. */ -int icalstore_test(icalcomponent* comp, icalcomponent* gauge) + +int icalstore_test_recurse(icalcomponent* comp, icalcomponent* gauge) { - int pass = 0,localpass = 0; - icalcomponent *c; + int pass = 1,localpass = 0; icalproperty *p; - icalcomponent *child; + icalcomponent *child,*subgauge; + icalcomponent_kind gaugekind, compkind; icalerror_check_arg_rz( (comp!=0), "comp"); icalerror_check_arg_rz( (gauge!=0), "gauge"); - for(c = icalcomponent_get_first_component(gauge,ICAL_ANY_COMPONENT); - c != 0; - c = icalcomponent_get_next_component(gauge,ICAL_ANY_COMPONENT)){ + gaugekind = icalcomponent_isa(gauge); + compkind = icalcomponent_isa(comp); + if( ! (gaugekind == compkind || gaugekind == ICAL_ANY_COMPONENT) ){ + return 0; + } - /* Test properties. For each property in the gauge, search through - the component for a similar property. If one is found, compare - the two properties value with the comparison specified in the - gauge with the X-LIC-COMPARETYPE parameter */ - - for(p = icalcomponent_get_first_property(c,ICAL_ANY_PROPERTY); - p != 0; - p = icalcomponent_get_next_property(c,ICAL_ANY_PROPERTY)){ + /* Test properties. For each property in the gauge, search through + the component for a similar property. If one is found, compare + the two properties value with the comparison specified in the + gauge with the X-LIC-COMPARETYPE parameter */ + + for(p = icalcomponent_get_first_property(gauge,ICAL_ANY_PROPERTY); + p != 0; + p = icalcomponent_get_next_property(gauge,ICAL_ANY_PROPERTY)){ + + icalproperty* targetprop; + icalparameter* compareparam; + icalparameter_xliccomparetype compare; + int rel; /* The relationship between the gauge and target values.*/ + + /* Extract the comparison type from the gauge. If there is no + comparison type, assume that it is "EQUAL" */ + + compareparam = icalproperty_get_first_parameter( + p, + ICAL_XLICCOMPARETYPE_PARAMETER); + + if (compareparam!=0){ + compare = icalparameter_get_xliccomparetype(compareparam); + } else { + compare = ICAL_XLICCOMPARETYPE_EQUAL; + } + + /* Find a property in the component that has the same type + as the gauge property. HACK -- multiples of a single + property type in the gauge will match only the first + instance in the component */ + + targetprop = icalcomponent_get_first_property(comp, + icalproperty_isa(p)); + + if(targetprop != 0){ - icalproperty* targetprop; - icalparameter* compareparam; - icalparameter_xliccomparetype compare; - int rel; /* The realtionship between the gauge and target values.*/ - - /* Extract the comparison type from the gauge. If there is no - comparison type, assume that it is "EQUAL" */ - - compareparam = icalproperty_get_first_parameter( - p, - ICAL_XLICCOMPARETYPE_PARAMETER); - - if (compareparam!=0){ - compare = icalparameter_get_xliccomparetype(compareparam); - } else { - compare = ICAL_XLICCOMPARETYPE_EQUAL; - } - - /* Find a property in the component that has the same type as - the gauge property */ - - targetprop = icalcomponent_get_first_property(comp, - icalproperty_isa(p)); - - - if(targetprop == 0){ - continue; - } - /* Compare the values of the gauge property and the target property */ - + rel = icalvalue_compare(icalproperty_get_value(p), icalproperty_get_value(targetprop)); - + /* Now see if the comparison is equavalent to the comparison specified in the gauge */ - + if (rel == compare){ localpass++; } else if (compare == ICAL_XLICCOMPARETYPE_LESSEQUAL && @@ -599,27 +602,59 @@ int icalstore_test(icalcomponent* comp, icalcomponent* gauge) } else if (compare == ICAL_XLICCOMPARETYPE_NOTEQUAL && ( rel == ICAL_XLICCOMPARETYPE_GREATER || rel == ICAL_XLICCOMPARETYPE_LESS)) { - pass++; + localpass++; } else { localpass = 0; } - - pass += localpass; + + pass = pass && (localpass>0); } - - - /* test subcomponents. Look for a child component that has a - counterpart in the gauge. If one is found, recursively call - icalstore_test */ + } + + /* Test subcomponents. Look for a child component that has a + counterpart in the gauge. If one is found, recursively call + icalstore_test */ + + for(subgauge = icalcomponent_get_first_component(gauge,ICAL_ANY_COMPONENT); + subgauge != 0; + subgauge = icalcomponent_get_next_component(gauge,ICAL_ANY_COMPONENT)){ - for(child = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT); - child != 0; - child = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT)){ + gaugekind = icalcomponent_isa(subgauge); + + if (gaugekind == ICAL_ANY_COMPONENT){ + child = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT); + } else { + child = icalcomponent_get_first_component(comp,gaugekind); + } - pass += icalstore_test(child,gauge); - + if(child !=0){ + localpass = icalstore_test_recurse(child,subgauge); + pass = pass && localpass; + } else { + pass = 0; } } + + return pass; +} + +/* guagecontainer is an XROOT component that holds several gauges. The + results of comparing against these gauges are ORed together in this + routine */ +int icalstore_test(icalcomponent* comp, icalcomponent* gaugecontainer) +{ + int pass = 0; + icalcomponent *gauge; + + icalerror_check_arg_rz( (comp!=0), "comp"); + icalerror_check_arg_rz( (gauge!=0), "gauge"); + + for(gauge = icalcomponent_get_first_component(gaugecontainer,ICAL_ANY_COMPONENT); + gauge != 0; + gauge = icalcomponent_get_next_component(gaugecontainer,ICAL_ANY_COMPONENT)){ + + pass += icalstore_test_recurse(comp, gauge); + } return pass>0; @@ -721,16 +756,21 @@ icalcomponent* icalstore_get_first_component(icalstore* store) sprintf(path,"%s/%s",impl->dir,(char*)pvl_data(impl->directory_iterator)); - if (impl->cluster == 0){ + /* If the next cluster we need is different than the current cluster, + delete the current one and get a new one */ + + if(impl->cluster != 0 && strcmp(path,icalcluster_path(impl->cluster)) != 0 ){ + icalcluster_free(impl->cluster); + impl->cluster = 0; + } + + if (impl->cluster == 0){ impl->cluster = icalcluster_new(path); if (impl->cluster == 0){ error = icalerrno; } - } else { - error = icalcluster_load(impl->cluster,path); - - } + } if (error != ICAL_NO_ERROR){ icalerror_set_errno(error); @@ -783,13 +823,13 @@ icalcomponent* icalstore_get_next_component(icalstore* store) ICAL_ANY_COMPONENT)){ /* If there is a gauge defined and the component does not - pass the gauge, skip the rest of the loop */ + pass the gauge, skip the rest of the loop */ if (impl->gauge != 0 && icalstore_test(c,impl->gauge) == 0){ continue; } /* Either there is no gauge, or the component passed the - gauge, so return it*/ + gauge, so return it*/ return c; } @@ -815,3 +855,4 @@ icalcomponent* icalstore_get_next_component(icalstore* store) + diff --git a/libical/src/test/Makefile.am b/libical/src/test/Makefile.am new file mode 100644 index 0000000000..0ebb00ac9a --- /dev/null +++ b/libical/src/test/Makefile.am @@ -0,0 +1,12 @@ + +noinst_PROGRAMS = usecases copycluster regression parser findobj storage + +LDADD = ../libical/libical.a ../libicalss/libicalss.a +INCLUDES = -I . -I../libical -I../libicalss + +findobj_SOURCES = findobj.c +usecases_SOURCES = usecases.c +copycluster_SOURCES = copycluster.c +regression_SOURCES = regression.c +parser_SOURCES = icaltestparser.c +storage_SOURCES = storage.c \ No newline at end of file diff --git a/libical/src/test/Makefile.in b/libical/src/test/Makefile.in index 5d3d5f709f..a8af11a146 100644 --- a/libical/src/test/Makefile.in +++ b/libical/src/test/Makefile.in @@ -1,36 +1,310 @@ +# Makefile.in generated automatically by automake 1.4a from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 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. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = ../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_FLAG = +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +AR = @AR@ +CC = @CC@ +LEX = @LEX@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +VERSION = @VERSION@ +YACC = @YACC@ + +noinst_PROGRAMS = usecases copycluster regression parser findobj storage + +LDADD = ../libical/libical.a ../libicalss/libicalss.a INCLUDES = -I . -I../libical -I../libicalss -CFLAGS = -Wall -g $(INCLUDES) -LIBS = -L../libical -L../libicalss -licalss -lical -CC = gcc -LD = ld -all: usecases copycluster regression parser findobj +findobj_SOURCES = findobj.c +usecases_SOURCES = usecases.c +copycluster_SOURCES = copycluster.c +regression_SOURCES = regression.c +parser_SOURCES = icaltestparser.c +storage_SOURCES = storage.c +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../../config.h +CONFIG_CLEAN_FILES = +PROGRAMS = $(noinst_PROGRAMS) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I../.. +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +usecases_OBJECTS = usecases.o +usecases_LDADD = $(LDADD) +usecases_DEPENDENCIES = ../libical/libical.a ../libicalss/libicalss.a +usecases_LDFLAGS = +copycluster_OBJECTS = copycluster.o +copycluster_LDADD = $(LDADD) +copycluster_DEPENDENCIES = ../libical/libical.a \ +../libicalss/libicalss.a +copycluster_LDFLAGS = +regression_OBJECTS = regression.o +regression_LDADD = $(LDADD) +regression_DEPENDENCIES = ../libical/libical.a ../libicalss/libicalss.a +regression_LDFLAGS = +parser_OBJECTS = icaltestparser.o +parser_LDADD = $(LDADD) +parser_DEPENDENCIES = ../libical/libical.a ../libicalss/libicalss.a +parser_LDFLAGS = +findobj_OBJECTS = findobj.o +findobj_LDADD = $(LDADD) +findobj_DEPENDENCIES = ../libical/libical.a ../libicalss/libicalss.a +findobj_LDFLAGS = +storage_OBJECTS = storage.o +storage_LDADD = $(LDADD) +storage_DEPENDENCIES = ../libical/libical.a ../libicalss/libicalss.a +storage_LDFLAGS = +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(usecases_SOURCES) $(copycluster_SOURCES) $(regression_SOURCES) $(parser_SOURCES) $(findobj_SOURCES) $(storage_SOURCES) +OBJECTS = $(usecases_OBJECTS) $(copycluster_OBJECTS) $(regression_OBJECTS) $(parser_OBJECTS) $(findobj_OBJECTS) $(storage_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps src/test/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-noinstPROGRAMS: + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) + +distclean-noinstPROGRAMS: + +maintainer-clean-noinstPROGRAMS: + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +usecases: $(usecases_OBJECTS) $(usecases_DEPENDENCIES) + @rm -f usecases + $(LINK) $(usecases_LDFLAGS) $(usecases_OBJECTS) $(usecases_LDADD) $(LIBS) + +copycluster: $(copycluster_OBJECTS) $(copycluster_DEPENDENCIES) + @rm -f copycluster + $(LINK) $(copycluster_LDFLAGS) $(copycluster_OBJECTS) $(copycluster_LDADD) $(LIBS) + +regression: $(regression_OBJECTS) $(regression_DEPENDENCIES) + @rm -f regression + $(LINK) $(regression_LDFLAGS) $(regression_OBJECTS) $(regression_LDADD) $(LIBS) + +parser: $(parser_OBJECTS) $(parser_DEPENDENCIES) + @rm -f parser + $(LINK) $(parser_LDFLAGS) $(parser_OBJECTS) $(parser_LDADD) $(LIBS) + +findobj: $(findobj_OBJECTS) $(findobj_DEPENDENCIES) + @rm -f findobj + $(LINK) $(findobj_LDFLAGS) $(findobj_OBJECTS) $(findobj_LDADD) $(LIBS) + +storage: $(storage_OBJECTS) $(storage_DEPENDENCIES) + @rm -f storage + $(LINK) $(storage_LDFLAGS) $(storage_OBJECTS) $(storage_LDADD) $(LIBS) + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = src/test + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile $(PROGRAMS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_STRIP_FLAG=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-noinstPROGRAMS mostlyclean-compile \ + mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-am -parser: icaltestparser.o ../libical/libical.a ../libicalss/libicalss.a - $(CC) -o icalparser icaltestparser.o $(LIBS) +clean-am: clean-noinstPROGRAMS clean-compile clean-tags clean-generic \ + mostlyclean-am -copycluster: copycluster.o ../libical/libical.a ../libicalss/libicalss.a - $(CC) -o copycluster copycluster.o $(INCLUDES) $(LIBS) +clean: clean-am -findobj: findobj.o ../libical/libical.a ../libicalss/libicalss.a - $(CC) -o findobj findobj.o $(INCLUDES) $(LIBS) +distclean-am: distclean-noinstPROGRAMS distclean-compile distclean-tags \ + distclean-generic clean-am -regression: regression.o ../libical/libical.a ../libicalss/libicalss.a - $(CC) -o regression regression.o $(INCLUDES) $(LIBS) +distclean: distclean-am -usecases: usecases.o ../libical/libical.a ../libicalss/libicalss.a - $(CC) -o usecases usecases.o $(INCLUDES) $(LIBS) +maintainer-clean-am: maintainer-clean-noinstPROGRAMS \ + maintainer-clean-compile maintainer-clean-tags \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." -clean: - -/bin/rm -f *.o - -/bin/rm -f \#* - -/bin/rm -f *~ Makefile.bak icalitip.tab.h icalitip.tab.c lex.yy.c - -/bin/rm -rf icalparser core regression usecases copycluster findobj +maintainer-clean: maintainer-clean-am -ci: clean - ci -u *.c *.h +.PHONY: mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \ +clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ +check-am installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean -depend: - @makedepend -Y $(INCLUDES) $(SOURCES) -install: \ No newline at end of file +# 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/libical/src/test/icaltestparser.c b/libical/src/test/icaltestparser.c index d56af49258..3f07fcd044 100644 --- a/libical/src/test/icaltestparser.c +++ b/libical/src/test/icaltestparser.c @@ -33,78 +33,91 @@ #include -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 +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_stdin(char *s, size_t size, void *d) +char* read_stream(char *s, size_t size, void *d) { - char *c = fgets(s,size, stdin); + char *c = fgets(s,size, (FILE*)d); return c; } -int main() + + +int main(int argc, char* argv[]) { - /* This is how we would have the parser parse a string */ - /* icalcomponent *c = icalparser_parse_string(str);*/ + int lineno = 0; + char* line; + FILE* stream; + icalcomponent *c; + icalparser *parser = icalparser_new(); - icalcomponent *c = icalparser_parse(read_stdin); + stream = fopen(argv[1],"r"); - printf("%s\n",icalcomponent_as_ical_string(c)); + assert(stream != 0); - /* Strip errors and spit it out again - printf("\n%d Errors in Component\n",icalcomponent_count_errors(c)); - icalcomponent_strip_errors(c); - printf("%s\n",icalcomponent_as_ical_string(c)); - */ + icalparser_set_gen_data(parser,stream); - icalmemory_free_ring(); - icalcomponent_free(c); + do{ + + line = icalparser_get_line(parser,read_stream); - return 1; -} + c = icalparser_add_line(parser,line); + if (c != 0){ + icalcomponent_convert_errors(c); + printf("%s",icalcomponent_as_ical_string(c)); + icalparser_claim(parser); + printf("\n---------------\n"); + icalcomponent_free(c); + } + + } while ( line != 0); + + +} diff --git a/libical/src/test/regression.c b/libical/src/test/regression.c index a969022d98..7b1606d432 100644 --- a/libical/src/test/regression.c +++ b/libical/src/test/regression.c @@ -43,94 +43,48 @@ /* This example creates and minipulates the ical object that appears * in rfc 2445, page 137 */ -/* - 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 - -*/ -char str[] = "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 -BEGIN:BOOGA -DTSTAMP:19980309T231000Z -X-LIC-FOO:Booga -DTSTOMP:19980309T231000Z -UID:guid-1.host1.com -END:BOOGA +char str[] = "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\ +BEGIN:BOOGA\ +DTSTAMP:19980309T231000Z\ +X-LIC-FOO:Booga\ +DTSTOMP:19980309T231000Z\ +UID:guid-1.host1.com\ +END:BOOGA\ END:VCALENDAR"; -void _test_string_line_generator(char* str); - -void test_string_line_generator() { - - _test_string_line_generator(str); - -} icalcomponent* create_simple_component() { @@ -611,9 +565,9 @@ void test_properties() icalparameter_new_cn("A Common Name 4"), 0); - for(param = icalproperty_get_first_parameter(prop,ICAL_ANY_PROPERTY); + for(param = icalproperty_get_first_parameter(prop,ICAL_ANY_PARAMETER); param != 0; - param = icalproperty_get_next_parameter(prop,ICAL_ANY_PROPERTY)) { + param = icalproperty_get_next_parameter(prop,ICAL_ANY_PARAMETER)) { printf("Prop parameter: %s\n",icalparameter_get_cn(param)); } @@ -811,17 +765,6 @@ void test_memory() } -int test_parser() -{ - - - icalcomponent *c = icalparser_parse_string(str); - printf("%s\n",icalcomponent_as_ical_string(c)); - icalcomponent_free(c); - icalmemory_free_ring(); - return 1; -} - int test_store() { @@ -1084,7 +1027,7 @@ void test_restriction() ICAL_VCALENDAR_COMPONENT, icalproperty_new_version("2.0"), icalproperty_new_prodid("-//RDU Software//NONSGML HandCal//EN"), - icalproperty_new_method(ICAL_METHOD_CANCEL), + icalproperty_new_method(ICAL_METHOD_REQUEST), icalcomponent_vanew( ICAL_VTIMEZONE_COMPONENT, icalproperty_new_tzid("US_Eastern"), @@ -1129,11 +1072,11 @@ void test_restriction() icalproperty_new_class("PUBLIC"), icalproperty_new_created(atime), icalproperty_new_summary("XYZ Project Review"), - icalproperty_vanew_dtstart( +/* icalproperty_vanew_dtstart( atime, icalparameter_new_tzid("US-Eastern"), 0 - ), + ),*/ icalproperty_vanew_dtend( atime, icalparameter_new_tzid("US-Eastern"), @@ -1273,35 +1216,89 @@ void test_strings(){ } -int main(int argc, char *argv[]) +void test_requeststat() { + icalrequeststatus s; + struct icalreqstattype st, st2; + char temp[1024]; + s = icalenum_num_to_reqstat(2,1); - printf("\n------------Test strings---------------\n"); - test_strings(); + assert(s == ICAL_2_1_FALLBACK_STATUS); -exit(0); + assert(icalenum_reqstat_major(s) == 2); + assert(icalenum_reqstat_minor(s) == 1); - printf("\n------------Test recur---------------\n"); - test_recur(); + printf("2.1: %s\n",icalenum_reqstat_desc(s)); -#if 0 - printf("\n------------Test Calendar---------------\n"); - test_calendar(); + st.code = s; + st.debug = "booga"; + st.desc = 0; - printf("\n------------Test Store---------------\n"); - test_store(); -#endif + printf("%s\n",icalreqstattype_as_string(st)); - printf("\n------------Test duration---------------\n"); - test_duration(); + st.desc = " A non-standard description"; + + printf("%s\n",icalreqstattype_as_string(st)); + 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",icalenum_reqstat_major(st2.code), + icalenum_reqstat_minor(st2.code), + icalenum_reqstat_desc(st2.code), + st2.debug); + + st2 = icalreqstattype_from_string("2.1;Success but fallback taken on one or more property values.;booga"); + printf("%s\n",icalreqstattype_as_string(st2)); + + st2 = icalreqstattype_from_string("2.1;Success but fallback taken on one or more property values.;"); + printf("%s\n",icalreqstattype_as_string(st2)); + + st2 = icalreqstattype_from_string("2.1;Success but fallback taken on one or more property values."); + printf("%s\n",icalreqstattype_as_string(st2)); + + st2 = icalreqstattype_from_string("2.1;"); + printf("%s\n",icalreqstattype_as_string(st2)); + + st2 = icalreqstattype_from_string("2.1"); + printf("%s\n",icalreqstattype_as_string(st2)); + + st2 = icalreqstattype_from_string("16.4"); + assert(st2.code == ICAL_UNKNOWN_STATUS); + + st2 = icalreqstattype_from_string("1."); + assert(st2.code == ICAL_UNKNOWN_STATUS); + +} + + +int main(int argc, char *argv[]) +{ + printf("\n------------Test Restriction---------------\n"); test_restriction(); + exit(0); + printf("\n------------Test request status-------\n"); + test_requeststat(); + + + printf("\n------------Test strings---------------\n"); + test_strings(); + + printf("\n------------Test recur---------------\n"); + test_recur(); + + printf("\n------------Test duration---------------\n"); + test_duration(); printf("\n------------Test Compare---------------\n"); test_compare(); @@ -1324,9 +1321,6 @@ exit(0); printf("\n------------Create Components --------\n"); create_new_component(); - printf("\n------------Test Parser---------------\n"); - test_parser(); - printf("\n----- Create Components with vaargs ---\n"); create_new_component_with_va_args(); diff --git a/libical/src/test/storage.c b/libical/src/test/storage.c new file mode 100644 index 0000000000..f6d0dd69e5 --- /dev/null +++ b/libical/src/test/storage.c @@ -0,0 +1,460 @@ +/* -*- Mode: C -*- + ====================================================================== + FILE: usecases.c + CREATOR: eric 03 April 1999 + + DESCRIPTION: + + $Id$ + $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 "ical.h" +#include +#include /* for strdup */ +#include /* for malloc */ +#include /* for printf */ +#include /* for time() */ +#include "icalmemory.h" +#include "icalstore.h" +#include "icalcluster.h" +#include "icalerror.h" +#include "icalrestriction.h" +#include "icalcalendar.h" + +/* This example creates and minipulates the ical object that appears + * in rfc 2445, page 137 */ + +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_cluster() +{ + icalcluster *cin, *cout; + int month = 0; + int count=0; + struct icaltimetype start, end; + icalcomponent *c,*clone, *itr; + + start = icaltimetype_from_timet( time(0),0); + end = start; + end.hour++; + + cout = icalcluster_new("clusterout.ics"); + assert(cout != 0); + + c = icalparser_parse_string(str2); + assert(c != 0); + + for(month = 1; month < 2; month++){ + icalcomponent *event; + icalproperty *dtstart, *dtend; + + cout = icalcluster_new("clusterout.ics"); + 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); + + icalcluster_add_component(cout,clone); + icalcluster_commit(cout); + + icalcluster_free(cout); + + } + + + /* Print them out */ + + + cout = icalcluster_new("clusterout.ics"); + assert(cout != 0); + + for (itr = icalcluster_get_first_component(cout, + ICAL_ANY_COMPONENT); + itr != 0; + itr = icalcluster_get_next_component(cout, + ICAL_ANY_COMPONENT)){ + + 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 */ + + icalcluster_free(cout); + + cout = icalcluster_new("clusterout.ics"); + assert(cout != 0); + + for (itr = icalcluster_get_first_component(cout, + ICAL_ANY_COMPONENT); + itr != 0; + itr = icalcluster_get_next_component(cout, + ICAL_ANY_COMPONENT)){ + + + icalcluster_remove_component(cout, itr); + } + + icalcluster_free(cout); + + + /* Print them out again */ + + cout = icalcluster_new("clusterout.ics"); + assert(cout != 0); + count =0; + + for (itr = icalcluster_get_first_component(cout, + ICAL_ANY_COMPONENT); + itr != 0; + itr = icalcluster_get_next_component(cout, + ICAL_ANY_COMPONENT)){ + + 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)); + + } + + icalcluster_free(cout); + + +} + + + +int test_store() +{ + + icalcomponent *c, *gauge; + icalerrorenum error; + icalcomponent *next, *itr; + icalcluster* cluster; + struct icalperiodtype rtime; + icalstore *s = icalstore_new("store"); + int i; + + assert(s != 0); + + rtime.start = icaltimetype_from_timet( time(0),0); + + cluster = icalcluster_new("clusterout.ics"); + + assert(cluster != 0); + +#define NUMCOMP 4 + + /* Duplicate every component in the cluster NUMCOMP times */ + + icalerror_clear_errno(); + + for (i = 1; i