aboutsummaryrefslogtreecommitdiffstats
path: root/libical/src
diff options
context:
space:
mode:
Diffstat (limited to 'libical/src')
-rw-r--r--libical/src/Makefile.am2
-rw-r--r--libical/src/libical/.cvsignore3
-rw-r--r--libical/src/libical/Makefile.am116
-rw-r--r--libical/src/libical/ical.h2
-rw-r--r--libical/src/libical/icalcomponent.c88
-rw-r--r--libical/src/libical/icalcomponent.h4
-rw-r--r--libical/src/libical/icalenums.c76
-rw-r--r--libical/src/libical/icalenums.h15
-rw-r--r--libical/src/libical/icalerror.c14
-rw-r--r--libical/src/libical/icalerror.h2
-rw-r--r--libical/src/libical/icallexer.l282
-rw-r--r--libical/src/libical/icalmemory.c7
-rw-r--r--libical/src/libical/icalparameter.c90
-rw-r--r--libical/src/libical/icalparser.c963
-rw-r--r--libical/src/libical/icalparser.h47
-rw-r--r--libical/src/libical/icalproperty.c29
-rw-r--r--libical/src/libical/icalrestriction.c14
-rw-r--r--libical/src/libical/icaltypes.c86
-rw-r--r--libical/src/libical/icaltypes.h20
-rw-r--r--libical/src/libical/icalvalue.c192
-rw-r--r--libical/src/libical/icalvalue.h5
-rw-r--r--libical/src/libical/icalversion.h3
-rw-r--r--libical/src/libical/icalversion.h.in3
-rw-r--r--libical/src/libical/icalyacc.y480
-rw-r--r--libical/src/libical/pvl.c4
-rw-r--r--libical/src/libicalss/Makefile.am32
-rw-r--r--libical/src/libicalss/icalcalendar.c5
-rw-r--r--libical/src/libicalss/icalcluster.c323
-rw-r--r--libical/src/libicalss/icalcluster.h4
-rw-r--r--libical/src/libicalss/icalstore.c361
-rw-r--r--libical/src/test/Makefile.am12
-rw-r--r--libical/src/test/Makefile.in324
-rw-r--r--libical/src/test/icaltestparser.c123
-rw-r--r--libical/src/test/regression.c232
-rw-r--r--libical/src/test/storage.c460
-rw-r--r--libical/src/test/usecases.c46
36 files changed, 3272 insertions, 1197 deletions
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 <stdlib.h> /* 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 <string.h> /* 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
+
+
+
+%%
+
+%{
+%}
+
+
+<binary_value>{
+.* { yylval.v_string= icalmemory_tmp_copy(yytext);
+ return STRING;}
+{crlf} { return EOL;}
+
+}
+
+<boolean_value>{
+. { return CHARACTER; }
+{crlf} { return EOL;}
+
+}
+
+<uri_value>{
+.* { yylval.v_string= icalmemory_tmp_copy(yytext);
+ return STRING;}
+{crlf} { return EOL;}
+
+}
+
+
+<time_value>{
+{digit}* { yylval.v_string= icalmemory_tmp_copy(yytext);
+ return DIGITS; }
+T { return TIME_CHAR; }
+Z { return UTC_CHAR; }
+{crlf} { return EOL;}
+}
+
+<duration_value>{
+{digit}+ { yylval.v_string =icalmemory_tmp_copy(yytext);
+ return DIGITS; }
+T { return TIME_CHAR; }
+[\+\-PTWHMSD] { return yytext[0]; }
+{crlf} { return EOL;}
+
+}
+
+<number_value>{
+[\+\-\.0-9]+ { yylval.v_int=atoi(yytext); return INTNUMBER; }
+{crlf} { return EOL;}
+}
+
+<period_value>{
+{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;}
+
+}
+
+<recur_value>{
+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;}
+}
+
+<utcoffset_value>{
+{crlf} { return EOL;}
+\-|\+ { return yytext[0]; }
+{digit}{digit} { yylval.v_int=atoi(yytext); return INTNUMBER; }
+
+}
+
+<enum_param_value>{
+. { return CHARACTER; }
+{crlf} { return EOL;}
+
+}
+
+<seperator>{
+, { 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 <stdio.h> /* for printf (debugging) */
#include <stdlib.h> /* for malloc, realloc */
+#include <string.h> /* 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 <stdlib.h> /* 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 <string.h> /* For strncpy */
+#include <string.h> /* For strncpy & size_t */
#include <stdio.h> /* For FILE and fgets and sprintf */
#include <stdlib.h> /* 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 <stdio.h> /* 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 <string.h> /* For strdup, rindex */
#include <assert.h>
#include <stdlib.h>
@@ -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 <stdlib.h> /* for malloc */
#include <errno.h> /* for errno */
#include <string.h> /* for strdup */
#include <assert.h>
#include <limits.h> /* 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 <stdlib.h> /* for malloc */
#include <stdio.h> /* for sprintf */
#include <string.h> /* For memset, others */
+#include <stddef.h> /* For offsetof() macro */
#include <errno.h>
#include <time.h> /* for mktime */
#include <stdlib.h> /* 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 <stdlib.h>
+#include <string.h> /* for strdup() */
+#include <limits.h> /* 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 <v_string> DIGITS
+%token <v_int> INTNUMBER
+%token <v_float> FLOATNUMBER
+%token <v_string> 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 <errno.h>
#include <assert.h>
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 <limits.h>
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 <errno.h>
#include <limits.h> /* For PATH_MAX */
@@ -33,11 +38,16 @@
#include <unistd.h> /* for stat, getpid */
#include <stdlib.h>
#include <string.h>
+#include <fcntl.h> /* for fcntl */
+#include <unistd.h> /* 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 <limits.h>
#include <dirent.h> /* for opendir() */
#include <errno.h>
@@ -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 <stdlib.h>
-char str[] = "BEGIN:VCALENDAR
-PRODID:\"-//RDU Software//NONSGML HandCal//EN\"
-VERSION:2.0
-BEGIN:VTIMEZONE
-TZID:US-Eastern
-BEGIN:STANDARD
-DTSTART:19990404T020000
-RDATE:19990u404xT020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:19990404T020000
-RDATE:19990404T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-TZNAME:EDT
-Dkjhgri:derhvnv;
-BEGIN:dfkjh
-END:dfdfkjh
-END:DAYLIGHT
-END:VTIMEZONE
-BEGIN:VEVENT
-GEO:Bongo
-DTSTAMP:19980309T231000Z
-UID:guid-1.host1.com
-ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com
-ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP
- :MAILTO:employee-A@host.com
-DESCRIPTION:Project XYZ Review Meeting
-CATEGORIES:MEETING
-CLASS:PUBLIC
-CREATED:19980309T130000Z
-SUMMARY:XYZ Project Review
-DTSTART;TZID=US-Eastern:19980312T083000
-DTEND;TZID=US-Eastern:19980312T093000
-LOCATION:1CP Conference Room 4350
-END:VEVENT
-END:VCALENDAR
+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 <assert.h>
+#include <string.h> /* for strdup */
+#include <stdlib.h> /* for malloc */
+#include <stdio.h> /* for printf */
+#include <time.h> /* for time() */
+#include "icalmemory.h"
+#include "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<NUMCOMP+1; i++){
+
+ /*rtime.start.month = i%12;*/
+ rtime.start.month = i;
+ rtime.end = rtime.start;
+ rtime.end.hour++;
+
+ for (itr = icalcluster_get_first_component(cluster,
+ ICAL_ANY_COMPONENT);
+ itr != 0;
+ itr = icalcluster_get_next_component(cluster,
+ ICAL_ANY_COMPONENT)){
+ icalcomponent *clone, *inner;
+ icalproperty *p;
+
+ inner = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT);
+ if (inner == 0){
+ continue;
+ }
+
+ /* Change the dtstart and dtend times in the component
+ pointed to by Itr*/
+
+ clone = icalcomponent_new_clone(itr);
+ inner = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT);
+
+ assert(icalerrno == ICAL_NO_ERROR);
+ assert(inner !=0);
+
+ /* DTSTART*/
+ p = icalcomponent_get_first_property(inner,ICAL_DTSTART_PROPERTY);
+ assert(icalerrno == ICAL_NO_ERROR);
+
+ if (p == 0){
+ p = icalproperty_new_dtstart(rtime.start);
+ icalcomponent_add_property(inner,p);
+ } else {
+ icalproperty_set_dtstart(p,rtime.start);
+ }
+ assert(icalerrno == ICAL_NO_ERROR);
+
+ /* DTEND*/
+ p = icalcomponent_get_first_property(inner,ICAL_DTEND_PROPERTY);
+ assert(icalerrno == ICAL_NO_ERROR);
+
+ if (p == 0){
+ p = icalproperty_new_dtstart(rtime.end);
+ icalcomponent_add_property(inner,p);
+ } else {
+ icalproperty_set_dtstart(p,rtime.end);
+ }
+ assert(icalerrno == ICAL_NO_ERROR);
+
+ printf("\n----------\n%s\n---------\n",icalcomponent_as_ical_string(inner));
+
+ error = icalstore_add_component(s,inner);
+
+ assert(icalerrno == ICAL_NO_ERROR);
+
+ }
+
+ }
+
+ gauge =
+ icalcomponent_vanew(
+ ICAL_VCALENDAR_COMPONENT,
+ icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_vanew_summary(
+ "Submit Income Taxes",
+ icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_EQUAL),
+ 0),
+ 0),
+ icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_vanew_summary(
+ "Bastille Day Party",
+ icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_EQUAL),
+ 0),
+ 0),
+ 0);
+
+#if 0
+
+
+ icalstore_select(s,gauge);
+
+ for(c = icalstore_first(s); c != 0; c = icalstore_next(s)){
+
+ printf("Got one! (%d)\n", count++);
+
+ if (c != 0){
+ printf("%s", icalcomponent_as_ical_string(c));;
+ if (icalstore_store(s2,c) == 0){
+ printf("Failed to write!\n");
+ }
+ icalcomponent_free(c);
+ } else {
+ printf("Failed to get component\n");
+ }
+ }
+
+
+ icalstore_free(s2);
+#endif
+
+
+ for(c = icalstore_get_first_component(s);
+ c != 0;
+ c = next){
+
+ next = icalstore_get_next_component(s);
+
+ if (c != 0){
+ /*icalstore_remove_component(s,c);*/
+ printf("%s", icalcomponent_as_ical_string(c));;
+ } else {
+ printf("Failed to get component\n");
+ }
+
+
+ }
+
+ icalstore_free(s);
+ return 0;
+}
+
+void test_calendar()
+{
+ icalcomponent *comp;
+ icalcluster *c;
+ icalstore *s;
+ icalcalendar* calendar = icalcalendar_new("calendar");
+ icalerrorenum error;
+ struct icaltimetype atime = icaltimetype_from_timet( time(0),0);
+
+ comp = icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_new_version("2.0"),
+ icalproperty_new_description("This is an event"),
+ icalproperty_new_dtstart(atime),
+ icalproperty_vanew_comment(
+ "Another Comment",
+ icalparameter_new_cn("A Common Name 1"),
+ icalparameter_new_cn("A Common Name 2"),
+ icalparameter_new_cn("A Common Name 3"),
+ icalparameter_new_cn("A Common Name 4"),
+ 0),
+ icalproperty_vanew_xlicerror(
+ "This is only a test",
+ icalparameter_new_xlicerrortype(ICAL_XLICERRORTYPE_COMPONENTPARSEERROR),
+ 0),
+
+ 0);
+
+
+ s = icalcalendar_get_booked(calendar);
+
+ error = icalstore_add_component(s,comp);
+
+ assert(error == ICAL_NO_ERROR);
+
+ c = icalcalendar_get_properties(calendar);
+
+ error = icalcluster_add_component(c,icalcomponent_new_clone(comp));
+
+ assert(error == ICAL_NO_ERROR);
+
+ icalcalendar_free(calendar);
+
+}
+
+
+int main(int argc, char *argv[])
+{
+
+
+ printf("\n------------Test Cluster---------------\n");
+ test_cluster();
+
+#if 0
+
+ printf("\n------------Test Store---------------\n");
+ test_store();
+
+
+
+ printf("\n------------Test Calendar---------------\n");
+ test_calendar();
+
+#endif
+
+ return 0;
+}
+
+
+
diff --git a/libical/src/test/usecases.c b/libical/src/test/usecases.c
index d07b5edac5..05c295197f 100644
--- a/libical/src/test/usecases.c
+++ b/libical/src/test/usecases.c
@@ -59,21 +59,22 @@
END:VCALENDAR
*/
-char str[] = "BEGIN:VCALENDAR
-PRODID:\"-//RDU Software//NONSGML HandCal//EN\"
-VERSION:2.0
-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
-CREATED:19980309T130000Z
-SUMMARY:XYZ Project Review
-DTSTART;TZID=US-Eastern:19980312T083000
-DTEND;TZID=US-Eastern:19980312T093000
-END:VEVENT
+
+char str[] = "BEGIN:VCALENDAR\
+PRODID:\"-//RDU Software//NONSGML HandCal//EN\"\
+VERSION:2.0\
+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\
+CREATED:19980309T130000Z\
+SUMMARY:XYZ Project Review\
+DTSTART;TZID=US-Eastern:19980312T083000\
+DTEND;TZID=US-Eastern:19980312T093000\
+END:VEVENT\
END:VCALENDAR";
/* Creating iCal Components
@@ -148,6 +149,9 @@ icalcomponent* create_new_component()
If the routine returns a string ( "get" and "as_ical_string" )
The library owns the returned memory.
+ There are more rules, so refer to the documentation for more
+ details.
+
*/
icalcomponent_add_property(
@@ -515,18 +519,6 @@ void test_parameters()
}
-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 main(int argc, char *argv[])
{
icalcomponent *c1;