aboutsummaryrefslogtreecommitdiffstats
path: root/libical/src
diff options
context:
space:
mode:
Diffstat (limited to 'libical/src')
-rw-r--r--libical/src/libical/Makefile.am4
-rw-r--r--libical/src/libical/icalcomponent.c62
-rw-r--r--libical/src/libical/icalcomponent.h6
-rw-r--r--libical/src/libical/icalenums.c17
-rw-r--r--libical/src/libical/icalenums.h6
-rw-r--r--libical/src/libical/icalerror.c26
-rw-r--r--libical/src/libical/icalerror.h3
-rw-r--r--libical/src/libical/icallexer.l129
-rw-r--r--libical/src/libical/icalmemory.h1
-rw-r--r--libical/src/libical/icalparameter.c.in9
-rw-r--r--libical/src/libical/icalparser.c106
-rw-r--r--libical/src/libical/icalparser.h1
-rw-r--r--libical/src/libical/icalproperty.c.in4
-rw-r--r--libical/src/libical/icalrecur.c775
-rw-r--r--libical/src/libical/icalrestriction.h1
-rw-r--r--libical/src/libical/icaltime.c640
-rw-r--r--libical/src/libical/icaltime.h58
-rw-r--r--libical/src/libical/icaltypes.c37
-rw-r--r--libical/src/libical/icaltypes.h6
-rw-r--r--libical/src/libical/icalvalue.c.in265
-rw-r--r--libical/src/libical/icalyacc.y120
-rw-r--r--libical/src/libicalss/Makefile.am6
-rw-r--r--libical/src/libicalss/icalcstp.h13
-rw-r--r--libical/src/test/Makefile.am10
-rw-r--r--libical/src/test/icaltestparser.c1
-rw-r--r--libical/src/test/regression.c1493
-rw-r--r--libical/src/test/storage.c4
-rw-r--r--libical/src/test/stow.c1
28 files changed, 2795 insertions, 1009 deletions
diff --git a/libical/src/libical/Makefile.am b/libical/src/libical/Makefile.am
index 20859f4744..a3b61d5677 100644
--- a/libical/src/libical/Makefile.am
+++ b/libical/src/libical/Makefile.am
@@ -54,7 +54,8 @@ libical_la_SOURCES = \
pvl.c \
pvl.h \
sspm.c \
- sspm.h
+ sspm.h \
+ vsnprintf.c
libicalincludedir = $(includedir)
@@ -187,3 +188,4 @@ EXTRA_DIST = \
$(BUILT_SOURCES) \
icallexer.c \
icalyacc.c
+
diff --git a/libical/src/libical/icalcomponent.c b/libical/src/libical/icalcomponent.c
index e36faae8e7..3ac0ee0663 100644
--- a/libical/src/libical/icalcomponent.c
+++ b/libical/src/libical/icalcomponent.c
@@ -696,8 +696,8 @@ time_t icalcomponent_convert_time(icalproperty *p)
tzp = icalproperty_get_first_parameter(p,ICAL_TZID_PARAMETER);
if (sict.is_utc == 1 && tzp != 0){
- icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
icalerror_warn("icalcomponent_get_span: component has a UTC DTSTART with a timezone specified ");
+ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
return 0;
}
@@ -715,7 +715,7 @@ time_t icalcomponent_convert_time(icalproperty *p)
/* _as_timet will use localtime() to do the conversion */
convt = icaltime_as_timet(sict);
- offset = icaltime_local_utc_offset();
+ offset = icaltime_utc_offset(sict,0);
convt += offset;
#ifdef TEST_CONVERT_TIME
@@ -837,7 +837,7 @@ struct icaltime_span icalcomponent_get_span(icalcomponent* comp)
dur = icalproperty_get_duration(duration);
- durt = icaldurationtype_as_timet(dur);
+ durt = icaldurationtype_as_int(dur);
span.end = span.start+durt;
}
@@ -1163,14 +1163,16 @@ struct icaltimetype icalcomponent_get_dtend(icalcomponent* comp)
} else if ( end_prop != 0) {
return icalproperty_get_dtend(end_prop);
} else if ( dur_prop != 0) {
+
struct icaltimetype start =
icalcomponent_get_dtstart(inner);
- time_t startt = icaltime_as_timet(start);
struct icaldurationtype duration =
icalproperty_get_duration(dur_prop);
- time_t durt = icaldurationtype_as_timet(duration);
- return icaltime_from_timet(startt+durt,start.is_date,start.is_utc);
+ struct icaltimetype end = icaltime_add(start,duration);
+
+ return end;
+
} else {
/* Error, both duration and dtend have been specified */
icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
@@ -1200,14 +1202,12 @@ void icalcomponent_set_dtend(icalcomponent* comp, struct icaltimetype v)
} else if ( dur_prop != 0) {
struct icaltimetype start =
icalcomponent_get_dtstart(inner);
- time_t startt = icaltime_as_timet(start);
struct icaltimetype end =
icalcomponent_get_dtend(inner);
- time_t endt = icaltime_as_timet(end);
-
+
struct icaldurationtype dur
- = icaldurationtype_from_timet(endt-startt);
+ = icaltime_subtract(end,start);
icalproperty_set_duration(dur_prop,dur);
@@ -1235,17 +1235,13 @@ void icalcomponent_set_duration(icalcomponent* comp,
} else if ( end_prop != 0) {
struct icaltimetype start =
icalcomponent_get_dtstart(inner);
- time_t startt = icaltime_as_timet(start);
- time_t durt = icaldurationtype_as_timet(v);
-
- struct icaltimetype new_end
- = icaltime_from_timet(startt+durt,start.is_date,start.is_utc);
+ struct icaltimetype new_end = icaltime_add(start,v);
icalproperty_set_dtend(end_prop,new_end);
} else if ( dur_prop != 0) {
- icalproperty_set_duration(end_prop,v);
+ icalproperty_set_duration(dur_prop,v);
} else {
/* Error, both duration and dtend have been specified */
icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
@@ -1277,7 +1273,7 @@ struct icaldurationtype icalcomponent_get_duration(icalcomponent* comp)
icalcomponent_get_dtend(inner);
time_t endt = icaltime_as_timet(end);
- return icaldurationtype_from_timet(endt-startt);
+ return icaldurationtype_from_int(endt-startt);
} else if ( dur_prop != 0) {
return icalproperty_get_duration(dur_prop);
} else {
@@ -1287,8 +1283,6 @@ struct icaldurationtype icalcomponent_get_duration(icalcomponent* comp)
}
}
-
-
void icalcomponent_set_method(icalcomponent* comp, icalproperty_method method)
{
icalproperty *prop
@@ -1348,8 +1342,34 @@ struct icaltimetype icalcomponent_get_dtstamp(icalcomponent* comp)
}
-void icalcomponent_set_summary(icalcomponent* comp, const char* v);
-const char* icalcomponent_get_summary(icalcomponent* comp);
+void icalcomponent_set_summary(icalcomponent* comp, const char* v)
+{
+ icalcomponent *inner = icalcomponent_get_inner(comp);
+ icalproperty *prop
+ = icalcomponent_get_first_property(inner, ICAL_SUMMARY_PROPERTY);
+
+ if (prop == 0){
+ prop = icalproperty_new_summary(v);
+ icalcomponent_add_property(inner, prop);
+ }
+
+ icalproperty_set_summary(prop,v);
+}
+
+
+const char* icalcomponent_get_summary(icalcomponent* comp)
+{
+ icalcomponent *inner = icalcomponent_get_inner(comp);
+ icalproperty *prop
+ = icalcomponent_get_first_property(inner,ICAL_SUMMARY_PROPERTY);
+
+ if (prop == 0){
+ return 0;
+ }
+
+ return icalproperty_get_summary(prop);
+
+}
void icalcomponent_set_comment(icalcomponent* comp, const char* v);
const char* icalcomponent_get_comment(icalcomponent* comp);
diff --git a/libical/src/libical/icalcomponent.h b/libical/src/libical/icalcomponent.h
index b08d488db3..61f4bf0dbf 100644
--- a/libical/src/libical/icalcomponent.h
+++ b/libical/src/libical/icalcomponent.h
@@ -86,6 +86,12 @@ icalproperty** icalcomponent_get_properties(icalcomponent* component,
*/
+/* Return the first VEVENT, VTODO or VJOURNAL sub-component of cop, or
+ comp if it is one of those types */
+
+icalcomponent* icalcomponent_get_inner(icalcomponent* comp);
+
+
void icalcomponent_add_component(icalcomponent* parent,
icalcomponent* child);
diff --git a/libical/src/libical/icalenums.c b/libical/src/libical/icalenums.c
index cd5ec43203..92811eef93 100644
--- a/libical/src/libical/icalenums.c
+++ b/libical/src/libical/icalenums.c
@@ -32,6 +32,7 @@
#include <stdio.h> /* For fprintf */
#include <stdio.h> /* For stderr */
+#include <string.h> /* For strncmp */
#include <assert.h>
struct icalproperty_kind_map {
@@ -41,6 +42,7 @@ struct icalproperty_kind_map {
static struct icalproperty_kind_map property_map[] =
{
+ { ICAL_ANY_PROPERTY, "ANY"},
{ ICAL_ACTION_PROPERTY, "ACTION"},
{ ICAL_ATTACH_PROPERTY, "ATTACH"},
{ ICAL_ATTENDEE_PROPERTY, "ATTENDEE"},
@@ -126,7 +128,7 @@ const char* icalenum_property_kind_to_string(icalproperty_kind kind)
}
-icalproperty_kind icalenum_string_to_property_kind(char* string)
+icalproperty_kind icalenum_string_to_property_kind(const char* string)
{
int i;
@@ -205,7 +207,7 @@ const char* icalenum_parameter_kind_to_string(icalparameter_kind kind)
}
-icalparameter_kind icalenum_string_to_parameter_kind(char* string)
+icalparameter_kind icalenum_string_to_parameter_kind(const char* string)
{
int i;
@@ -250,9 +252,10 @@ static struct icalvalue_kind_map value_map[] =
{ ICAL_METHOD_VALUE, "METHOD"}, /* Not an RFC2445 type */
{ ICAL_STATUS_VALUE, "STATUS"}, /* Not an RFC2445 type */
{ ICAL_GEO_VALUE, "FLOAT"}, /* Not an RFC2445 type */
- { ICAL_ATTACH_VALUE, "XATTACH"}, /* Not an RFC2445 type */
- { ICAL_DATETIMEDATE_VALUE, "XDATETIMEDATE"}, /* Not an RFC2445 type */
- { ICAL_DATETIMEPERIOD_VALUE, "XDATETIMEPERIOD"}, /* Not an RFC2445 type */
+ { ICAL_ATTACH_VALUE, "ATTACH"}, /* Not an RFC2445 type */
+ { ICAL_DATETIMEDATE_VALUE, "DATETIMEDATE"}, /* Not an RFC2445 type */
+ { ICAL_DATETIMEPERIOD_VALUE, "DATETIMEPERIOD"}, /* Not an RFC2445 type */
+ { ICAL_TRIGGER_VALUE, "TRIGGER"}, /* Not an RFC2445 type */
{ ICAL_QUERY_VALUE, "QUERY"},
{ ICAL_NO_VALUE, ""},
};
@@ -330,7 +333,7 @@ const char* icalenum_component_kind_to_string(icalcomponent_kind kind)
}
-icalcomponent_kind icalenum_string_to_component_kind(char* string)
+icalcomponent_kind icalenum_string_to_component_kind(const char* string)
{
int i;
@@ -400,7 +403,7 @@ static struct icalproperty_kind_value_map propval_map[] =
{ ICAL_RECURRENCEID_PROPERTY, ICAL_DATETIME_VALUE },
{ ICAL_EXDATE_PROPERTY, ICAL_DATETIME_VALUE },
{ ICAL_RDATE_PROPERTY, ICAL_DATETIME_VALUE },
- { ICAL_TRIGGER_PROPERTY, ICAL_DURATION_VALUE },
+ { ICAL_TRIGGER_PROPERTY, ICAL_TRIGGER_VALUE },
{ ICAL_DURATION_PROPERTY, ICAL_DURATION_VALUE },
/* CAP properties */
diff --git a/libical/src/libical/icalenums.h b/libical/src/libical/icalenums.h
index ab25532cf6..d11547efad 100644
--- a/libical/src/libical/icalenums.h
+++ b/libical/src/libical/icalenums.h
@@ -421,16 +421,16 @@ icalrequeststatus icalenum_num_to_reqstat(short major, short minor);
**********************************************************************/
const char* icalenum_property_kind_to_string(icalproperty_kind kind);
-icalproperty_kind icalenum_string_to_property_kind(char* string);
+icalproperty_kind icalenum_string_to_property_kind(const char* string);
const char* icalenum_value_kind_to_string(icalvalue_kind kind);
icalvalue_kind icalenum_value_kind_by_prop(icalproperty_kind kind);
const char* icalenum_parameter_kind_to_string(icalparameter_kind kind);
-icalparameter_kind icalenum_string_to_parameter_kind(char* string);
+icalparameter_kind icalenum_string_to_parameter_kind(const char* string);
const char* icalenum_component_kind_to_string(icalcomponent_kind kind);
-icalcomponent_kind icalenum_string_to_component_kind(char* string);
+icalcomponent_kind icalenum_string_to_component_kind(const char* string);
icalvalue_kind icalenum_property_kind_to_value_kind(icalproperty_kind kind);
diff --git a/libical/src/libical/icalerror.c b/libical/src/libical/icalerror.c
index 76212afdae..e9641efc6a 100644
--- a/libical/src/libical/icalerror.c
+++ b/libical/src/libical/icalerror.c
@@ -53,15 +53,29 @@ void icalerror_clear_errno() {
icalerrno = ICAL_NO_ERROR;
}
-void icalerror_set_errno(icalerrorenum e) {
-
#ifdef ICAL_ERRORS_ARE_FATAL
- fprintf(stderr,"libical: icalerrno_set_error: %s",icalerror_strerror(e));
- icalerror_crash_here();
+int icalerror_errors_are_fatal = 1;
+#else
+int icalerror_errors_are_fatal = 0;
#endif
- icalerror_stop_here();
+void icalerror_set_errno(icalerrorenum e) {
+
+
icalerrno = e;
+ icalerror_stop_here();
+
+ if(icalerror_errors_are_fatal == 1){
+
+ fprintf(stderr,"libical: icalerrno_set_error: %s\n",icalerror_strerror(e));
+#ifdef NDEBUG
+ icalerror_crash_here();
+#else
+ assert(0);
+#endif
+ }
+
+
}
@@ -75,7 +89,7 @@ static struct icalerror_string_map string_map[] =
{ICAL_BADARG_ERROR,"Bad argument to function"},
{ICAL_NEWFAILED_ERROR,"Failed to create a new object via a *_new() routine"},
{ICAL_MALFORMEDDATA_ERROR,"An input string was not correctly formed or a component has missing or extra properties"},
- {ICAL_PARSE_ERROR,"Failed to parse a part of an iCal componet"},
+ {ICAL_PARSE_ERROR,"Failed to parse a part of an iCal component"},
{ICAL_INTERNAL_ERROR,"Random internal error. This indicates an error in the library code, not an error in use"},
{ICAL_FILE_ERROR,"An operation on a file failed. Check errno for more detail."},
{ICAL_ALLOCATION_ERROR,"Failed to allocate memory"},
diff --git a/libical/src/libical/icalerror.h b/libical/src/libical/icalerror.h
index c5035149f9..85e054fd86 100644
--- a/libical/src/libical/icalerror.h
+++ b/libical/src/libical/icalerror.h
@@ -131,8 +131,11 @@ typedef enum icalerrorenum {
} icalerrorenum;
+/* The libical error enumeration, like errno*/
extern icalerrorenum icalerrno;
+/* If true, libicl aborts after a call to icalerror_set_error*/
+extern int icalerror_errors_are_fatal;
void icalerror_clear_errno(void);
void icalerror_set_errno(icalerrorenum e);
diff --git a/libical/src/libical/icallexer.l b/libical/src/libical/icallexer.l
index 5a3616b8da..d76a7938e3 100644
--- a/libical/src/libical/icallexer.l
+++ b/libical/src/libical/icallexer.l
@@ -6,7 +6,7 @@
DESCRIPTION:
- $Id: icallexer.l,v 1.7 2000/12/12 22:54:40 danw Exp $
+ $Id: icallexer.l,v 1.8 2001/01/23 20:22:33 jpr Exp $
$Locker: $
(C) COPYRIGHT 1999 Eric Busboom
@@ -94,54 +94,7 @@ digit [0-9]
%}
-<binary_value>{
-.* { ical_yylval.v_string= icalmemory_tmp_copy(yytext);
- return STRING;}
-{crlf} { return EOL;}
-
-}
-
-<boolean_value>{
-. { return CHARACTER; }
-{crlf} { return EOL;}
-
-}
-
-<uri_value>{
-.* { ical_yylval.v_string= icalmemory_tmp_copy(yytext);
- return STRING;}
-{crlf} { return EOL;}
-
-}
-
-
<time_value>{
-{digit}* { ical_yylval.v_string= icalmemory_tmp_copy(yytext);
- return DIGITS; }
-T { return TIME_CHAR; }
-Z { return UTC_CHAR; }
-{crlf} { return EOL;}
-. { return CHARACTER; }
-
-}
-
-<duration_value>{
-{digit}+ { ical_yylval.v_string =icalmemory_tmp_copy(yytext);
- return DIGITS; }
-T { return TIME_CHAR; }
-[\+\-PTWHMSD] { return yytext[0]; }
-{crlf} { return EOL;}
-
-}
-
-<number_value>{
-[\+\-\.0-9]+ { ical_yylval.v_int=atoi(yytext); return INTNUMBER; }
-{crlf} { return EOL;}
-. { return CHARACTER; }
-
-}
-
-<period_value>{
{digit}+ { ical_yylval.v_string =icalmemory_tmp_copy(yytext) ;
return DIGITS; }
T { return TIME_CHAR; }
@@ -151,46 +104,6 @@ Z { return UTC_CHAR; }
}
-<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; }
-- { return MINUS; }
-[\+0-9]+ { ical_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]; }
@@ -222,52 +135,14 @@ 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;}
+ {BEGIN(time_value);break;}
- case ICAL_NO_VALUE:
- {
- /* The value is probably actually a component name */
- {BEGIN(component); break;}
- }
default:
{
assert(1==0);
diff --git a/libical/src/libical/icalmemory.h b/libical/src/libical/icalmemory.h
index 63ede3f3ac..3ae77024c4 100644
--- a/libical/src/libical/icalmemory.h
+++ b/libical/src/libical/icalmemory.h
@@ -5,6 +5,7 @@
$Id$
+
$Locker$
This program is free software; you can redistribute it and/or modify
diff --git a/libical/src/libical/icalparameter.c.in b/libical/src/libical/icalparameter.c.in
index ad83927e87..00e9280c7d 100644
--- a/libical/src/libical/icalparameter.c.in
+++ b/libical/src/libical/icalparameter.c.in
@@ -3,7 +3,7 @@
FILE: icalderivedparameters.{c,h}
CREATOR: eric 09 May 1999
- $Id: icalparameter.c.in,v 1.2 2000/12/14 02:13:54 federico Exp $
+ $Id: icalparameter.c.in,v 1.3 2001/01/23 20:22:33 jpr Exp $
$Locker: $
@@ -233,7 +233,8 @@ void icalparameter_set_impl_data(icalparameter_kind kind,
data->v_xlicerrortype=value; break;
case ICAL_XLICCOMPARETYPE_PARAMETER:
data->v_xliccomparetype=value; break;
- default:
+ default:
+ break;
}
}
@@ -750,7 +751,7 @@ icalparameter_as_ical_string (icalparameter* parameter)
}
- icalmemory_append_string(&buf, &buf_ptr, &buf_size, "=");
+ icalmemory_append_string(&buf, &buf_ptr, &buf_size, "=");
switch (impl->kind) {
case ICAL_CUTYPE_PARAMETER:
@@ -1236,7 +1237,7 @@ icalproperty* icalparameter_get_parent(icalparameter* param)
{
struct icalparameter_impl *impl = (struct icalparameter_impl*)param;
- icalerror_check_arg_rv( (param!=0),"param");
+ icalerror_check_arg_rz( (param!=0),"param");
return impl->parent;
}
diff --git a/libical/src/libical/icalparser.c b/libical/src/libical/icalparser.c
index 6359d42d27..462fd164af 100644
--- a/libical/src/libical/icalparser.c
+++ b/libical/src/libical/icalparser.c
@@ -70,7 +70,6 @@ struct icalparser_impl
size_t tmp_buf_size;
char temp[TMP_BUF_SIZE];
icalcomponent *root_component;
- icalcomponent *tail;
int version;
int level;
int lineno;
@@ -203,7 +202,7 @@ void icalparser_clear_flex_input(void)
input_buffer_p = input_buffer+strlen(input_buffer);
}
-/* Cal the flex parser to parse a complex value */
+/* Call the flex/bison parser to parse a complex value */
icalvalue* icalparser_parse_value(icalvalue_kind kind,
const char* str, icalproperty** error)
@@ -526,40 +525,52 @@ icalcomponent* icalparser_parse(icalparser *parser,
char* line;
icalcomponent *c=0;
- icalcomponent *root_component=0;
+ icalcomponent *root=0;
+ struct icalparser_impl *impl = (struct icalparser_impl*)parser;
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);
- }
+
+ if(icalcomponent_get_parent(c) !=0){
+ /* This is bad news... assert? */
+ }
+
+ assert(impl->root_component == 0);
+ assert(pvl_count(impl->components) ==0);
+
+ if (root == 0){
+ /* Just one component */
+ root = c;
+ } else if(icalcomponent_isa(root) != ICAL_XROOT_COMPONENT) {
+ /*Got a second component, so move the two components under
+ an XROOT container */
+ icalcomponent *tempc = icalcomponent_new(ICAL_XROOT_COMPONENT);
+ icalcomponent_add_component(tempc, root);
+ icalcomponent_add_component(tempc, c);
+ root = tempc;
+ } else if(icalcomponent_isa(root) == ICAL_XROOT_COMPONENT) {
+ /* Already have an XROOT container, so add the component
+ to it*/
+ icalcomponent_add_component(root, c);
+
+ } else {
+ /* Badness */
+ assert(0);
+ }
+
+ c = 0;
+
}
if(line != 0){
free(line);
}
} while ( line != 0);
- return root_component;
+ return root;
}
@@ -593,7 +604,7 @@ icalcomponent* icalparser_add_line(icalparser* parser,
end = 0;
str = icalparser_get_prop_name(line, &end);
- if (str == 0){
+ if (str == 0 || strlen(str) == 0 ){
/* Could not get a property name */
icalcomponent *tail = pvl_data(pvl_tail(impl->components));
@@ -638,20 +649,35 @@ icalcomponent* icalparser_add_line(icalparser* parser,
impl->level--;
str = icalparser_get_next_value(end,&end, value_kind);
+ /* Pop last component off of list and add it to the second-to-last*/
impl->root_component = pvl_pop(impl->components);
tail = pvl_data(pvl_tail(impl->components));
if(tail != 0){
icalcomponent_add_component(tail,impl->root_component);
- }
+ }
tail = 0;
/* Return the component if we are back to the 0th level */
if (impl->level == 0){
+ icalcomponent *rtrn;
+
+ if(pvl_count(impl->components) != 0){
+ /* There are still components on the stack -- this means
+ that one of them did not have a proper "END" */
+ pvl_push(impl->components,impl->root_component);
+ icalparser_clean(parser); /* may reset impl->root_component*/
+ }
+
+ assert(pvl_count(impl->components) == 0);
+
impl->state = ICALPARSER_SUCCESS;
- return impl->root_component;
+ rtrn = impl->root_component;
+ impl->root_component = 0;
+ return rtrn;
+
} else {
impl->state = ICALPARSER_END_COMP;
return 0;
@@ -893,10 +919,12 @@ icalcomponent* icalparser_add_line(icalparser* parser,
/****************************************************************
* End of component parsing.
*****************************************************************/
-
+
if (pvl_data(pvl_tail(impl->components)) == 0 &&
impl->level == 0){
+ /* HACK. Does this clause ever get executed? */
impl->state = ICALPARSER_SUCCESS;
+ assert(0);
return impl->root_component;
} else {
impl->state = ICALPARSER_IN_PROGRESS;
@@ -912,29 +940,16 @@ icalparser_state icalparser_get_state(icalparser* parser)
}
-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));
+ icalcomponent *tail;
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," ",
@@ -946,8 +961,13 @@ icalcomponent* icalparser_clean(icalparser* parser)
tail=pvl_data(pvl_tail(impl->components));
if(tail != 0){
- icalcomponent_add_component(tail,impl->root_component);
+ if(icalcomponent_get_parent(impl->root_component)!=0){
+ icalerror_warn("icalparser_clean is trying to attach a component for the second time");
+ } else {
+ icalcomponent_add_component(tail,impl->root_component);
+ }
}
+
}
return impl->root_component;
diff --git a/libical/src/libical/icalparser.h b/libical/src/libical/icalparser.h
index 673d514f65..efbe86eb21 100644
--- a/libical/src/libical/icalparser.h
+++ b/libical/src/libical/icalparser.h
@@ -54,7 +54,6 @@ typedef enum icalparser_state {
icalparser* icalparser_new(void);
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);
diff --git a/libical/src/libical/icalproperty.c.in b/libical/src/libical/icalproperty.c.in
index 3b5cff835b..80fefd58ab 100644
--- a/libical/src/libical/icalproperty.c.in
+++ b/libical/src/libical/icalproperty.c.in
@@ -4,7 +4,7 @@
FILE: icalproperty.c
CREATOR: eric 28 April 1999
- $Id: icalproperty.c.in,v 1.2 2000/12/14 02:13:54 federico Exp $
+ $Id: icalproperty.c.in,v 1.3 2001/01/23 20:22:33 jpr Exp $
(C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org
@@ -376,7 +376,7 @@ icalproperty_add_parameter (icalproperty* prop,icalparameter* parameter)
void
icalproperty_set_parameter (icalproperty* prop,icalparameter* parameter)
{
- icalproperty_kind kind;
+ icalparameter_kind kind;
kind = icalparameter_isa(parameter);
diff --git a/libical/src/libical/icalrecur.c b/libical/src/libical/icalrecur.c
index 6a9bfcd011..cfd8e2b33b 100644
--- a/libical/src/libical/icalrecur.c
+++ b/libical/src/libical/icalrecur.c
@@ -4,6 +4,7 @@
CREATOR: eric 16 May 2000
$Id$
+
$Locker$
@@ -111,6 +112,16 @@
Finally, icalrecur_iterator_next() does a few other checks on the
time value, and if it passes, it returns the time.
+ A note about the end_of_data flag. This flag is usually set early in
+ a next_* routine and returned in the end. The way it is used allows
+ the next_* routine to set the last time back to the first element in
+ a BYxx rule, and then signal to the higer level routine to increment
+ the next higher level. For instance. WITH FREQ=MONTHLY;BYDAY=TU,FR,
+ After next_weekday_by_month runs though both TU and FR, it sets the
+ week day back to TU and sets end_of_data. This signals next_month to
+ increment the month.
+
+
======================================================================*/
#ifdef HAVE_CONFIG_H
@@ -120,22 +131,383 @@
#include "icalrecur.h"
#ifdef ICAL_NO_LIBICAL
-#include "icalerror.h"
-#else
#define icalerror_set_errno(x)
#define icalerror_check_arg_rv(x,y)
+#else
+#include "icalerror.h"
+#include "icalmemory.h"
#endif
#include <stdlib.h> /* for malloc */
#include <errno.h> /* for errno */
-#include <string.h> /* for strdup */
+#include <string.h> /* for strdup and strchr*/
#include <assert.h>
+#include <stddef.h> /* For offsetof() macro */
#define TEMP_MAX 1024
+/*********************** Rule parsing routines ************************/
+
+struct icalrecur_parser {
+ const char* rule;
+ char* copy;
+ char* this_clause;
+ char* next_clause;
+
+ struct icalrecurrencetype rt;
+};
+
+const char* icalrecur_first_clause(struct icalrecur_parser *parser)
+{
+ char *idx;
+ parser->this_clause = parser->copy;
+
+ idx = strchr(parser->this_clause,';');
+
+ if (idx == 0){
+ parser->next_clause = 0;
+ return 0;
+ }
+
+ *idx = 0;
+ idx++;
+ parser->next_clause = idx;
+
+ return parser->this_clause;
+
+}
+
+const char* icalrecur_next_clause(struct icalrecur_parser *parser)
+{
+ char* idx;
+
+ parser->this_clause = parser->next_clause;
+
+ if(parser->this_clause == 0){
+ return 0;
+ }
+
+ idx = strchr(parser->this_clause,';');
+
+ if (idx == 0){
+ parser->next_clause = 0;
+ } else {
+
+ *idx = 0;
+ idx++;
+ parser->next_clause = idx;
+ }
+
+ return parser->this_clause;
+
+}
+
+void icalrecur_clause_name_and_value(struct icalrecur_parser *parser,
+ char** name, char** value)
+{
+ char *idx;
+
+ *name = parser->this_clause;
+
+ idx = strchr(parser->this_clause,'=');
+
+ if (idx == 0){
+ *name = 0;
+ *value = 0;
+ return;
+ }
+
+ *idx = 0;
+ idx++;
+ *value = idx;
+}
+
+void icalrecur_add_byrules(struct icalrecur_parser *parser, short *array,
+ int size, char* vals)
+{
+ char *t, *n;
+ int i=0;
+ int sign = 1;
+ short v;
+
+ n = vals;
+
+ while(n != 0){
+
+ if(i == size){
+ return;
+ }
+
+ t = n;
+
+ n = strchr(t,',');
+
+ if(n != 0){
+ *n = 0;
+ n++;
+ }
+
+ /* Get optional sign. HACK. sign is not allowed for all BYxxx
+ rule parts */
+ if( *t == '-'){
+ sign = 1;
+ t++;
+ } else if (*t == '+'){
+ sign = -1;
+ t++;
+ }
+
+ v = atoi(t) * sign ;
+
+
+ array[i++] = v;
+ array[i] = ICAL_RECURRENCE_ARRAY_MAX;
+
+ }
+
+}
+
+void icalrecur_add_bydayrules(struct icalrecur_parser *parser, const char* vals)
+{
+
+ char *t, *n;
+ int i=0;
+ int sign = 1;
+ int weekno = 0;
+ icalrecurrencetype_weekday wd;
+ short *array = parser->rt.by_day;
+ char* end;
+
+ end = (char*)vals+strlen(vals);
+ n = vals;
+
+ while(n != 0){
+
+
+ t = n;
+
+ n = strchr(t,',');
+
+ if(n != 0){
+ *n = 0;
+ n++;
+ }
+
+ /* Get optional sign. */
+ if( *t == '-'){
+ sign = -1;
+ t++;
+ } else if (*t == '+'){
+ sign = 1;
+ t++;
+ } else {
+ sign = 1;
+ }
+
+ weekno = 0;
+ /* Get Optional weekno */
+ if( sscanf(t,"%d",&weekno) != 0){
+ if (n != 0){
+ int weeknolen = (n-t)-3; /* 3 -> one for \0, 2 for day name */
+ /* could use abs(log10(weekno))+1, but that needs libm */
+ t += weeknolen;
+ } else {
+ t = end -2;
+ }
+ }
+
+ wd = icalrecur_string_to_weekday(t);
+
+ array[i++] = sign* ((int)wd + 8*weekno);
+ array[i] = ICAL_RECURRENCE_ARRAY_MAX;
+
+ }
+
+}
+
+
+struct icalrecurrencetype icalrecurrencetype_from_string(const char* str)
+{
+ struct icalrecur_parser parser;
+
+ memset(&parser,0,sizeof(parser));
+ icalrecurrencetype_clear(&parser.rt);
+
+ icalerror_check_arg_re(str!=0,"str",parser.rt);
+
+
+ /* Set up the parser struct */
+ parser.rule = str;
+ parser.copy = strdup(parser.rule);
+ parser.this_clause = parser.copy;
+
+ if(parser.copy == 0){
+ icalerror_set_errno(ICAL_NEWFAILED_ERROR);
+ return parser.rt;
+ }
+ /* Loop through all of the clauses */
+ for(icalrecur_first_clause(&parser);
+ parser.this_clause != 0;
+ icalrecur_next_clause(&parser))
+ {
+ char *name, *value;
+ icalrecur_clause_name_and_value(&parser,&name,&value);
+
+ if (strcmp(name,"FREQ") == 0){
+ parser.rt.freq = icalrecur_string_to_recurrence(value);
+ } else if (strcmp(name,"COUNT") == 0){
+ parser.rt.count = atoi(value);
+ } else if (strcmp(name,"UNTIL") == 0){
+ parser.rt.until = icaltime_from_string(value);
+ } else if (strcmp(name,"INTERVAL") == 0){
+ parser.rt.interval = atoi(value);
+ } else if (strcmp(name,"WKST") == 0){
+ parser.rt.week_start = icalrecur_string_to_weekday(value);
+ } else if (strcmp(name,"BYSECOND") == 0){
+ icalrecur_add_byrules(&parser,parser.rt.by_second,
+ ICAL_BY_SECOND_SIZE,value);
+ } else if (strcmp(name,"BYMINUTE") == 0){
+ icalrecur_add_byrules(&parser,parser.rt.by_minute,
+ ICAL_BY_MINUTE_SIZE,value);
+ } else if (strcmp(name,"BYHOUR") == 0){
+ icalrecur_add_byrules(&parser,parser.rt.by_hour,
+ ICAL_BY_HOUR_SIZE,value);
+ } else if (strcmp(name,"BYDAY") == 0){
+ icalrecur_add_bydayrules(&parser,value);
+ } else if (strcmp(name,"BYMONTHDAY") == 0){
+ icalrecur_add_byrules(&parser,parser.rt.by_month_day,
+ ICAL_BY_MONTHDAY_SIZE,value);
+ } else if (strcmp(name,"BYYEARDAY") == 0){
+ icalrecur_add_byrules(&parser,parser.rt.by_year_day,
+ ICAL_BY_YEARDAY_SIZE,value);
+ } else if (strcmp(name,"BYWEEKNO") == 0){
+ icalrecur_add_byrules(&parser,parser.rt.by_week_no,
+ ICAL_BY_WEEKNO_SIZE,value);
+ } else if (strcmp(name,"BYMONTH") == 0){
+ icalrecur_add_byrules(&parser,parser.rt.by_month,
+ ICAL_BY_MONTH_SIZE,value);
+ } else if (strcmp(name,"BYSETPOS") == 0){
+ icalrecur_add_byrules(&parser,parser.rt.by_set_pos,
+ ICAL_BY_SETPOS_SIZE,value);
+ } else {
+ /* error */
+ }
+
+ }
+
+ free(parser.copy);
+
+ return parser.rt;
+
+}
+
+#ifndef ICAL_NO_LIBICAL
+
+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},
+};
+
+/* A private routine in icalvalue.c */
+void print_datetime_to_string(char* str, struct icaltimetype *data);
+
+char* icalrecurrencetype_as_string(struct icalrecurrencetype *recur)
+{
+ char* str;
+ char *str_p;
+ size_t buf_sz = 200;
+ char temp[20];
+ int i,j;
+
+ if(recur->freq == ICAL_NO_RECURRENCE){
+ return 0;
+ }
+ str = (char*)icalmemory_tmp_buffer(buf_sz);
+ str_p = str;
+
+ icalmemory_append_string(&str,&str_p,&buf_sz,"FREQ=");
+ icalmemory_append_string(&str,&str_p,&buf_sz,
+ icalrecur_recurrence_to_string(recur->freq));
+
+ if(recur->until.year != 0){
+
+ temp[0] = 0;
+ print_datetime_to_string(temp,&(recur->until));
+
+ icalmemory_append_string(&str,&str_p,&buf_sz,";UNTIL=");
+ icalmemory_append_string(&str,&str_p,&buf_sz, temp);
+ }
+
+ if(recur->count != 0){
+ sprintf(temp,"%d",recur->count);
+ icalmemory_append_string(&str,&str_p,&buf_sz,";COUNT=");
+ icalmemory_append_string(&str,&str_p,&buf_sz, temp);
+ }
+
+ if(recur->interval != 0){
+ sprintf(temp,"%d",recur->interval);
+ icalmemory_append_string(&str,&str_p,&buf_sz,";INTERVAL=");
+ icalmemory_append_string(&str,&str_p,&buf_sz, temp);
+ }
+
+ 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,recurmap[j].str);
+
+ for(i=0;
+ i< limit && array[i] != ICAL_RECURRENCE_ARRAY_MAX;
+ i++){
+ if (j == 3) { /* BYDAY */
+ short dow = icalrecurrencetype_day_day_of_week(array[i]);
+ const char *daystr = icalrecur_weekday_to_string(dow);
+ short pos;
+
+ pos = icalrecurrencetype_day_position(array[i]);
+
+ if (pos == 1)
+ icalmemory_append_string(&str,&str_p,&buf_sz,daystr);
+ else {
+ sprintf(temp,"%d%s",pos,daystr);
+ icalmemory_append_string(&str,&str_p,&buf_sz,temp);
+ }
+
+ } else {
+ sprintf(temp,"%d",array[i]);
+ icalmemory_append_string(&str,&str_p,&buf_sz, temp);
+ }
+
+ if( (i+1)<limit &&array[i+1]
+ != ICAL_RECURRENCE_ARRAY_MAX){
+ icalmemory_append_char(&str,&str_p,&buf_sz,',');
+ }
+ }
+ }
+ }
+
+ return str;
+}
+#endif
+
+
+
+/************************* occurrence iteration routiens ******************/
enum byrule {
NO_CONTRACTION = -1,
@@ -156,7 +528,7 @@ struct icalrecur_iterator_impl {
struct icaltimetype dtstart; /* Hack. Make into time_t */
struct icaltimetype last; /* last time return from _iterator_next*/
- int occurrence_no; /* number of step made on this iterator */
+ int occurrence_no; /* number of step made on t iterator */
struct icalrecurrencetype rule;
short days[366];
@@ -164,6 +536,7 @@ struct icalrecur_iterator_impl {
enum byrule byrule;
short by_indices[9];
+ short orig_data[9]; /* 1 if there was data in the byrule */
short *by_ptrs[9]; /* Pointers into the by_* array elements of the rule */
@@ -306,6 +679,11 @@ void setup_defaults(struct icalrecur_iterator_impl* impl,
int expand_year_days(struct icalrecur_iterator_impl* impl,short year);
+int has_by_data(struct icalrecur_iterator_impl* impl, enum byrule byrule){
+
+ return (impl->orig_data[byrule] == 1);
+}
+
icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule,
struct icaltimetype dtstart)
@@ -341,6 +719,27 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule,
impl->by_ptrs[BY_SECOND]=impl->rule.by_second;
impl->by_ptrs[BY_SET_POS]=impl->rule.by_set_pos;
+ memset(impl->orig_data,0,9);
+
+ impl->orig_data[BY_MONTH]
+ = (impl->rule.by_month[0]!=ICAL_RECURRENCE_ARRAY_MAX);
+ impl->orig_data[BY_WEEK_NO]
+ =(impl->rule.by_week_no[0]!=ICAL_RECURRENCE_ARRAY_MAX);
+ impl->orig_data[BY_YEAR_DAY]
+ =(impl->rule.by_year_day[0]!=ICAL_RECURRENCE_ARRAY_MAX);
+ impl->orig_data[BY_MONTH_DAY]
+ =(impl->rule.by_month_day[0]!=ICAL_RECURRENCE_ARRAY_MAX);
+ impl->orig_data[BY_DAY]
+ = (impl->rule.by_day[0]!=ICAL_RECURRENCE_ARRAY_MAX);
+ impl->orig_data[BY_HOUR]
+ = (impl->rule.by_hour[0]!=ICAL_RECURRENCE_ARRAY_MAX);
+ impl->orig_data[BY_MINUTE]
+ = (impl->rule.by_minute[0]!=ICAL_RECURRENCE_ARRAY_MAX);
+ impl->orig_data[BY_SECOND]
+ = (impl->rule.by_second[0]!=ICAL_RECURRENCE_ARRAY_MAX);
+ impl->orig_data[BY_SET_POS]
+ = (impl->rule.by_set_pos[0]!=ICAL_RECURRENCE_ARRAY_MAX);
+
/* Check if the recurrence rule is legal */
@@ -400,7 +799,7 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule,
/* Rewrite some of the rules and set up defaults to make later
- processing easier. Primarily, this involves copying an element
+ processing easier. Primarily, t involves copying an element
from the start time into the coresponding BY_* array when the
BY_* array is empty */
@@ -420,9 +819,37 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule,
setup_defaults(impl,BY_MONTH,ICAL_MONTHLY_RECURRENCE,impl->dtstart.month,
&(impl->last.month));
- if(impl->rule.freq == ICAL_WEEKLY_RECURRENCE &&
- impl->by_ptrs[BY_DAY][0] == ICAL_RECURRENCE_ARRAY_MAX){
- impl->by_ptrs[BY_DAY][0] = icaltime_day_of_week(impl->dtstart);
+ if(impl->rule.freq == ICAL_WEEKLY_RECURRENCE ){
+
+ if(impl->by_ptrs[BY_DAY][0] == ICAL_RECURRENCE_ARRAY_MAX){
+
+ /* Weekly recurrences with no BY_DAY data should occur on the
+ same day of the week as the start time . */
+ impl->by_ptrs[BY_DAY][0] = icaltime_day_of_week(impl->dtstart);
+
+ } else {
+ /* If there is BY_DAY data, then we need to move the initial
+ time to the start of the BY_DAY data. That if if the
+ start time is on a Wednesday, and the rule has
+ BYDAY=MO,WE,FR, move the initial time back to
+ monday. Otherwise, jumping to the next week ( jumping 7
+ days ahead ) will skip over some occurrences in the
+ second week. */
+
+ /* This is probably a HACK. There should be some more
+ general way to solve this problem */
+
+ short dow = impl->by_ptrs[BY_DAY][0]-icaltime_day_of_week(impl->last);
+
+ if(dow < 0) {
+ /* initial time is after first day of BY_DAY data */
+
+ impl->last.day += dow;
+ impl->last = icaltime_normalize(impl->last);
+ }
+ }
+
+
}
@@ -430,6 +857,41 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule,
expand_year_days(impl,impl->dtstart.year);
}
+
+ /* If this is a monthly interval with by day data, then we need to
+ set the last value to the appropriate day of the month */
+
+ if(impl->rule.freq == ICAL_MONTHLY_RECURRENCE &&
+ has_by_data(impl,BY_DAY)) {
+
+ short dow = icalrecurrencetype_day_day_of_week(
+ impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]]);
+ short pos = icalrecurrencetype_day_position(
+ impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]]);
+
+ short poscount = 0;
+ short days_in_month =
+ icaltime_days_in_month(impl->last.month, impl->last.year) ;
+
+ for(impl->last.day = 1;
+ impl->last.day <= days_in_month;
+ impl->last.day++){
+
+ if(icaltime_day_of_week(impl->last) == dow){
+ if(++poscount == pos){
+ break;
+ }
+ }
+ }
+
+ if(impl->last.day > days_in_month){
+ icalerror_set_errno(ICAL_USAGE_ERROR);
+ return 0;
+ }
+
+ }
+
+
return impl;
}
@@ -540,8 +1002,7 @@ void increment_second(struct icalrecur_iterator_impl* impl, int inc)
}
}
-#if 0
-
+#if 0
#include "ical.h"
void test_increment()
{
@@ -812,11 +1273,10 @@ int next_yearday(struct icalrecur_iterator_impl* impl)
}
-/* This routine is only called by next_week or next_month, so it does
-not have a clause for this_frequency. In both cases, it is certain
-that BY_DAY has data */
+/* This routine is only called by next_week. It is certain that BY_DAY
+has data */
-int next_weekday(struct icalrecur_iterator_impl* impl)
+int next_weekday_by_week(struct icalrecur_iterator_impl* impl)
{
short end_of_data = 0;
@@ -829,42 +1289,121 @@ int next_weekday(struct icalrecur_iterator_impl* impl)
assert( impl->by_ptrs[BY_DAY][0]!=ICAL_RECURRENCE_ARRAY_MAX);
- impl->by_indices[BY_DAY]++;
-
- if (impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]]
- ==ICAL_RECURRENCE_ARRAY_MAX){
- impl->by_indices[BY_DAY] = 0;
+ while(1) {
+
+ impl->by_indices[BY_DAY]++; /* Look at next elem in BYDAY array */
- end_of_data = 1;
- }
+ /* Are we at the end of the BYDAY array? */
+ if (impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]]
+ ==ICAL_RECURRENCE_ARRAY_MAX){
+
+ impl->by_indices[BY_DAY] = 0; /* Reset to 0 */
+ end_of_data = 1; /* Signal that we're at the end */
+ }
+
+ /* Add the day of week offset to to the start of this week, and use
+ that to get the next day */
+ dow = impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]];
+ start_of_week = icaltime_start_doy_of_week(impl->last);
+
+ dow--; /*Sun is 1, not 0 */
- /* HACK. I don't think this handles the Nth day of week rules
- correctly ( "BYDAY=2TU" ) */
- dow = impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]];
-
- start_of_week = icaltime_start_doy_of_week(impl->last);
- next = icaltime_from_day_of_year(start_of_week + dow - 1,impl->last.year);
+ if(dow+start_of_week <1 && !end_of_data){
+ /* The selected date is in the previous year. */
+ continue;
+ }
- impl->last.day = next.day;
- impl->last.month = next.month;
+ next = icaltime_from_day_of_year(start_of_week + dow,impl->last.year);
+
+ impl->last.day = next.day;
+ impl->last.month = next.month;
+ impl->last.year = next.year;
- return end_of_data;
+ return end_of_data;
+ }
}
+int next_weekday_by_month(struct icalrecur_iterator_impl* impl)
+{
+
+ short end_of_data = 0;
+ struct icaltimetype start_of_month; /* Start of month */
+ short pos, poscount, dow, days_in_month;
+
+ if (next_hour(impl) == 0){
+ return 0;
+ }
+
+ assert( impl->by_ptrs[BY_DAY][0]!=ICAL_RECURRENCE_ARRAY_MAX);
+
+ while(1) {
+ impl->by_indices[BY_DAY]++; /* Look at next elem in BYDAY array */
+
+ /* Are we at the end of the BYDAY array? */
+ if (impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]]
+ ==ICAL_RECURRENCE_ARRAY_MAX){
+
+ impl->by_indices[BY_DAY] = 0; /* Reset to 0 */
+ end_of_data = 1; /* Signal that we're at the end */
+ }
+
+ dow = icalrecurrencetype_day_day_of_week(
+ impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]]);
+ pos = icalrecurrencetype_day_position(
+ impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]]);
+
+ start_of_month = impl->last;
+
+ /* Find right day in month. HACK. Find an arithmetic way to do
+ this */
+
+ poscount = 0;
+ days_in_month =
+ icaltime_days_in_month(impl->last.month, impl->last.year) ;
+
+ for(start_of_month.day = 1;
+ start_of_month.day <= days_in_month;
+ start_of_month.day++){
+
+ if(icaltime_day_of_week(start_of_month) == dow){
+ if(++poscount == pos){
+ break;
+ }
+ }
+ }
+
+ if (!end_of_data == 1 &&
+ (
+ start_of_month.day > days_in_month ||
+ icaltime_compare(start_of_month,impl->last) <= 0
+ )
+ ){
+ continue;
+ }
+
+ impl->last.day = start_of_month.day;
+ impl->last.month = start_of_month.month;
+ impl->last.year = start_of_month.year;
+
+ return end_of_data;
+ }
+}
+
int next_month(struct icalrecur_iterator_impl* impl)
{
- short has_by_data = (impl->by_ptrs[BY_MONTH][0]!=ICAL_RECURRENCE_ARRAY_MAX);
short this_frequency = (impl->rule.freq == ICAL_MONTHLY_RECURRENCE);
short end_of_data = 0;
- assert(has_by_data || this_frequency);
+ assert( has_by_data(impl,BY_MONTH) || this_frequency);
/* Week day data overrides monthday data */
- if(impl->by_ptrs[BY_DAY][0]!=ICAL_RECURRENCE_ARRAY_MAX){
- if (next_weekday(impl) == 0){
+ if(has_by_data(impl,BY_DAY)){
+ /* For this case, the weekdays are relative to the
+ month. BYDAY=FR -> First Friday in month, etc. */
+ if (next_weekday_by_month(impl) == 0){
return 0;
}
} else {
@@ -873,7 +1412,8 @@ int next_month(struct icalrecur_iterator_impl* impl)
}
}
- if( has_by_data ){
+
+ if(has_by_data(impl,BY_MONTH) ){
/* Ignore the frequency and use the byrule data */
impl->by_indices[BY_MONTH]++;
@@ -888,13 +1428,36 @@ int next_month(struct icalrecur_iterator_impl* impl)
impl->last.month =
impl->by_ptrs[BY_MONTH][impl->by_indices[BY_MONTH]];
- } else if( !has_by_data && this_frequency ){
- /* Compute the next value from the last time and the frequency interval*/
- increment_month(impl,impl->rule.interval);
+ } else if( !has_by_data(impl,BY_MONTH) && this_frequency ){
- }
+ if(has_by_data(impl,BY_DAY)){
- if(has_by_data && end_of_data && this_frequency ){
+ short dayinc = 28;
+
+ /* BY_DAY data specified a day of week, but incrementing the
+ month changes the day of the week -- Nov 2 is not the
+ same DOW as Oct 2. So, we need to fix the day of week by
+ incrementing in even weeks into the next month. . */
+
+
+ if ( impl->last.day + dayinc
+ <= icaltime_days_in_month(impl->last.month, impl->last.year)){
+ dayinc += 7;
+ }
+
+ increment_monthday(impl,dayinc);
+
+ } else {
+
+ /* Compute the next value from the last time and the
+ frequency interval*/
+ increment_month(impl,impl->rule.interval);
+ }
+
+ }
+
+
+ if(has_by_data(impl,BY_MONTH) && end_of_data && this_frequency ){
increment_year(impl,1);
}
return end_of_data;
@@ -908,16 +1471,14 @@ int next_week(struct icalrecur_iterator_impl* impl)
short this_frequency = (impl->rule.freq == ICAL_WEEKLY_RECURRENCE);
short end_of_data = 0;
- int sec_in_week = 60*60*24*7;
- if (next_weekday(impl) == 0){
+ if (next_weekday_by_week(impl) == 0){
return 0;
}
if( impl->by_ptrs[BY_WEEK_NO][0]!=ICAL_RECURRENCE_ARRAY_MAX){
/* Use the Week Number byrule data */
int week_no;
- time_t tt;
struct icaltimetype t;
impl->by_indices[BY_WEEK_NO]++;
@@ -935,13 +1496,13 @@ int next_week(struct icalrecur_iterator_impl* impl)
week_no = impl->by_ptrs[BY_WEEK_NO][impl->by_indices[BY_WEEK_NO]];
- tt = icaltime_as_timet(impl->last);
-
- tt+=sec_in_week*week_no;
-
- impl->last = icaltime_from_timet(tt,impl->last.is_date,impl->last.is_utc);
+ impl->last.day += week_no*7;
+
+ impl->last = icaltime_normalize(impl->last);
} else if( !has_by_data && this_frequency ){
+
+
increment_monthday(impl,7*impl->rule.interval);
}
@@ -953,10 +1514,6 @@ int next_week(struct icalrecur_iterator_impl* impl)
}
-int has_by_data(struct icalrecur_iterator_impl* impl, enum byrule byrule){
-
- return (impl->by_ptrs[byrule][0] != ICAL_RECURRENCE_ARRAY_MAX);
-}
/* For INTERVAL=YEARLY, set up the days[] array in the iterator to
@@ -970,10 +1527,13 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year)
struct icaltimetype t;
+ t.is_date = 1; /* Needed to make day_of_year routines work property */
+
memset(&t,0,sizeof(t));
memset(impl->days,ICAL_RECURRENCE_ARRAY_MAX_BYTE,sizeof(impl->days));
- if(has_by_data(impl,BY_MONTH) && !has_by_data(impl,BY_MONTH_DAY)){
+ if(has_by_data(impl,BY_MONTH) && !has_by_data(impl,BY_MONTH_DAY)
+ && !has_by_data(impl,BY_DAY)){
for(j=0;impl->by_ptrs[BY_MONTH][j]!=ICAL_RECURRENCE_ARRAY_MAX;j++){
struct icaltimetype t;
@@ -983,6 +1543,7 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year)
t = impl->dtstart;
t.year = year;
t.month = month;
+ t.is_date = 1;
doy = icaltime_day_of_year(t);
@@ -1003,7 +1564,8 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year)
t.day = 1;
t.year = year;
t.month = month;
-
+ t.is_date = 1;
+
for(t.day = 1; t.day <=days_in_month; t.day++){
short current_dow = icaltime_day_of_week(t);
@@ -1034,6 +1596,7 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year)
t.day = month_day;
t.month = month;
t.year = year;
+ t.is_date = 1;
doy = icaltime_day_of_year(t);
@@ -1049,18 +1612,30 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year)
t.day = impl->dtstart.day;
t.month = impl->dtstart.month;
t.year = year;
+ t.is_date = 1;
dow = icaltime_day_of_week(t);
+ /* HACK Not finished */
+
} else if (has_by_data(impl,BY_WEEK_NO) && has_by_data(impl,BY_DAY)){
-
+ /* HACK Not finished */
} else if (has_by_data(impl,BY_YEAR_DAY)){
-
+
+ for(j=0;impl->by_ptrs[BY_YEAR_DAY][j]!=ICAL_RECURRENCE_ARRAY_MAX;j++){
+ short doy = impl->by_ptrs[BY_YEAR_DAY][j];
+ impl->days[days_index++] = doy;
+ }
+
} else if (has_by_data(impl,BY_MONTH_DAY) ){
+ /* HACK Not finished */
} else if (has_by_data(impl,BY_DAY)){
+ /* HACK Not finished */
} else {
+ assert(0);
+ /* HACK Not finished */
}
@@ -1124,7 +1699,6 @@ int check_restriction(struct icalrecur_iterator_impl* impl,
int check_contracting_rules(struct icalrecur_iterator_impl* impl)
{
- enum byrule;
int day_of_week=0;
int week_no=0;
@@ -1158,14 +1732,15 @@ struct icaltimetype icalrecur_iterator_next(icalrecur_iterator *itr)
return icaltime_null_time();
}
- if(impl->occurrence_no == 0){
+ if(impl->occurrence_no == 0
+ && icaltime_compare(impl->last,impl->dtstart) >= 0){
+
impl->occurrence_no++;
return impl->last;
}
-
do {
- switch(impl->rule.freq){
+ switch(impl->rule.freq){
case ICAL_SECONDLY_RECURRENCE: {
next_second(impl);
@@ -1199,19 +1774,19 @@ struct icaltimetype icalrecur_iterator_next(icalrecur_iterator *itr)
assert(0); /* HACK, need a better error */
}
}
-
+
if(impl->last.year >= 2038){
/* HACK */
return icaltime_null_time();
}
-
} while(!check_contracting_rules(impl)
|| icaltime_compare(impl->last,impl->dtstart) < 0);
-
-
+
+
+/* Ignore null times and times that are after the until time */
if( !icaltime_is_null_time(impl->rule.until) &&
- icaltime_compare(impl->last,impl->rule.until) > 0) {
+ icaltime_compare(impl->last,impl->rule.until) > 0 ) {
return icaltime_null_time();
}
@@ -1252,7 +1827,17 @@ enum icalrecurrencetype_weekday icalrecurrencetype_day_day_of_week(short day)
short icalrecurrencetype_day_position(short day)
{
- return (day-icalrecurrencetype_day_day_of_week(day))/8;
+ short wd, pos;
+
+ wd = icalrecurrencetype_day_day_of_week(day);
+
+ pos = (abs(day)-wd)/8 * ((day<0)?-1:1);
+
+ if(pos == 0){
+ pos = 1;
+ }
+
+ return pos;
}
@@ -1283,6 +1868,20 @@ const char* icalrecur_weekday_to_string(icalrecurrencetype_weekday kind)
return 0;
}
+icalrecurrencetype_weekday icalrecur_string_to_weekday(const char* str)
+{
+ int i;
+
+ for (i=0; wd_map[i].wd != ICAL_NO_WEEKDAY; i++) {
+ if ( strcmp(str,wd_map[i].str) == 0){
+ return wd_map[i].wd;
+ }
+ }
+
+ return ICAL_NO_WEEKDAY;
+}
+
+
struct {
icalrecurrencetype_frequency kind;
@@ -1310,4 +1909,48 @@ const char* icalrecur_recurrence_to_string(icalrecurrencetype_frequency kind)
return 0;
}
+icalrecurrencetype_frequency icalrecur_string_to_recurrence(const char* str)
+{
+ int i;
+
+ for (i=0; freq_map[i].kind != ICAL_NO_RECURRENCE ; i++) {
+ if ( strcmp(str,freq_map[i].str) == 0){
+ return freq_map[i].kind;
+ }
+ }
+ return ICAL_NO_RECURRENCE;
+}
+
+
+int icalrecur_expand_recurrence(char* rule, time_t start,
+ int count, time_t* array)
+{
+ struct icalrecurrencetype recur;
+ icalrecur_iterator* ritr;
+ time_t tt;
+ struct icaltimetype icstart, next;
+ int i = 0;
+
+ memset(array, 0, count*sizeof(time_t));
+
+ icstart = icaltime_from_timet(start,0);
+
+ recur = icalrecurrencetype_from_string(rule);
+ for(ritr = icalrecur_iterator_new(recur,icstart),
+ next = icalrecur_iterator_next(ritr);
+ !icaltime_is_null_time(next) && i < count;
+ next = icalrecur_iterator_next(ritr)){
+
+ tt = icaltime_as_timet(next);
+
+ if (tt >= start ){
+ array[i++] = tt;
+ }
+
+ }
+
+ icalrecur_iterator_free(ritr);
+
+ return 1;
+}
diff --git a/libical/src/libical/icalrestriction.h b/libical/src/libical/icalrestriction.h
index 409334cf28..6d414db4af 100644
--- a/libical/src/libical/icalrestriction.h
+++ b/libical/src/libical/icalrestriction.h
@@ -6,6 +6,7 @@
$Id$
+
(C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org
This program is free software; you can redistribute it and/or modify
diff --git a/libical/src/libical/icaltime.c b/libical/src/libical/icaltime.c
index 112ac7972b..8169161dee 100644
--- a/libical/src/libical/icaltime.c
+++ b/libical/src/libical/icaltime.c
@@ -30,47 +30,223 @@
#endif
#include "icaltime.h"
-#include "icalvalue.h"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
+#ifdef ICAL_NO_LIBICAL
+#define icalerror_set_errno(x)
+#define icalerror_check_arg_rv(x,y)
+#define icalerror_check_arg_re(x,y,z)
+#else
+#include "icalerror.h"
+#include "icalmemory.h"
+#endif
+
+
+
+extern long int timezone; /* Global defined by libc */
struct icaltimetype
-icaltime_from_timet(time_t tm, int is_date, int is_utc)
+icaltime_from_timet(time_t tm, int is_date)
{
- struct icaltimetype tt;
+ struct icaltimetype tt = icaltime_null_time();
struct tm t;
-#if 0 /* This is incorrect; a time_t *is* in UTC by definition. So we just ignore the flag. */
- if(is_utc == 0){
- tm += icaltime_local_utc_offset();
- }
-#endif
-
t = *(gmtime(&tm));
+
+ if(is_date == 0){
+ tt.second = t.tm_sec;
+ tt.minute = t.tm_min;
+ tt.hour = t.tm_hour;
+ } else {
+ tt.second = tt.minute =tt.hour = 0 ;
+ }
- tt.second = t.tm_sec;
- tt.minute = t.tm_min;
- tt.hour = t.tm_hour;
tt.day = t.tm_mday;
tt.month = t.tm_mon + 1;
tt.year = t.tm_year+ 1900;
-#if 0
- tt.is_utc = is_utc;
-#endif
tt.is_utc = 1;
tt.is_date = is_date;
return tt;
}
-/* Always returns time in UTC */
+char* set_tz(const char* tzid)
+{
+ char *tzstr = 0;
+ char *tmp;
+
+ /* Put the new time zone into the environment */
+ if(getenv("TZ") != 0){
+ tzstr = (char*)strdup(getenv("TZ"));
+
+ if(tzstr == 0){
+ icalerror_set_errno(ICAL_NEWFAILED_ERROR);
+ return 0;
+ }
+ }
+
+ tmp = (char*)malloc(1024);
+
+ if(tmp == 0){
+ icalerror_set_errno(ICAL_NEWFAILED_ERROR);
+ return 0;
+ }
+
+ snprintf(tmp,1024,"TZ=%s",tzid);
+
+ /* HACK. In some libc versions, putenv gives the string to the
+ system and in some it gives a copy, so the following might be a
+ memory leak. THe linux man page says that glibc2.1.2 take
+ ownership ( no leak) while BSD4.4 uses a copy ( A leak ) */
+ putenv(tmp);
+
+ return tzstr; /* This will be zero if the TZ env var was not set */
+}
+
+void unset_tz(char* tzstr)
+{
+ /* restore the original environment */
+
+ if(tzstr!=0){
+ char temp[1024];
+ snprintf(temp,1024,"TZ=%s",tzstr);
+ putenv(temp);
+ free(tzstr);
+ } else {
+ putenv("TZ"); /* Delete from environment */
+ }
+}
+
time_t icaltime_as_timet(struct icaltimetype tt)
{
struct tm stm;
+ time_t t;
+
+ memset(&stm,0,sizeof( struct tm));
+
+ if(icaltime_is_null_time(tt)) {
+ return 0;
+ }
+
+ stm.tm_sec = tt.second;
+ stm.tm_min = tt.minute;
+ stm.tm_hour = tt.hour;
+ stm.tm_mday = tt.day;
+ stm.tm_mon = tt.month-1;
+ stm.tm_year = tt.year-1900;
+ stm.tm_isdst = -1;
+
+ if(tt.is_utc == 1 || tt.is_date == 1){
+ char* old_tz = set_tz("UTC");
+ t = mktime(&stm);
+ unset_tz(old_tz);
+ } else {
+ t = mktime(&stm);
+ }
+
+ return t;
+
+}
+
+char* icaltime_as_ical_string(struct icaltimetype tt)
+{
+ size_t size = 17;
+ char* buf = icalmemory_new_buffer(size);
+
+ if(tt.is_date){
+ snprintf(buf, size,"%04d%02d%02d",tt.year,tt.month,tt.day);
+ } else {
+ char* fmt;
+ if(tt.is_utc){
+ fmt = "%04d%02d%02dT%02d%02d%02dZ";
+ } else {
+ fmt = "%04d%02d%02dT%02d%02d%02d";
+ }
+ snprintf(buf, size,fmt,tt.year,tt.month,tt.day,
+ tt.hour,tt.minute,tt.second);
+ }
+
+ icalmemory_add_tmp_buffer(buf);
+
+ return buf;
+
+}
+
+
+/* convert tt, of timezone tzid, into a utc time */
+struct icaltimetype icaltime_as_utc(struct icaltimetype tt,const char* tzid)
+{
+ int tzid_offset;
+
+ if(tt.is_utc == 1 || tt.is_date == 1){
+ return tt;
+ }
+
+ tzid_offset = icaltime_utc_offset(tt,tzid);
+
+ tt.second -= tzid_offset;
+
+ tt.is_utc = 1;
+
+ return icaltime_normalize(tt);
+}
+
+/* convert tt, a time in UTC, into a time in timezone tzid */
+struct icaltimetype icaltime_as_zone(struct icaltimetype tt,const char* tzid)
+{
+ int tzid_offset;
+
+ tzid_offset = icaltime_utc_offset(tt,tzid);
+
+ tt.second += tzid_offset;
+
+ tt.is_utc = 0;
+
+ return icaltime_normalize(tt);
+
+}
+
+
+/* Return the offset of the named zone as seconds. tt is a time
+ indicating the date for which you want the offset */
+int icaltime_utc_offset(struct icaltimetype ictt, const char* tzid)
+{
+
+ time_t tt = icaltime_as_timet(ictt);
+ time_t offset_tt;
+ struct tm gtm;
+
+ char *tzstr = 0;
+
+ if(tzid != 0){
+ tzstr = set_tz(tzid);
+ }
+
+ /* Mis-interpret a UTC broken out time as local time */
+ gtm = *(gmtime(&tt));
+ gtm.tm_isdst = localtime(&tt)->tm_isdst;
+ offset_tt = mktime(&gtm);
+
+ if(tzid != 0){
+ unset_tz(tzstr);
+ }
+
+ return tt-offset_tt;
+}
+
+
+
+/* Normalize by converting from localtime to utc and back to local
+ time. This uses localtime because localtime and mktime are inverses
+ of each other */
+
+struct icaltimetype icaltime_normalize(struct icaltimetype tt)
+{
+ struct tm stm;
time_t tut;
memset(&stm,0,sizeof( struct tm));
@@ -87,29 +263,71 @@ time_t icaltime_as_timet(struct icaltimetype tt)
if(tt.is_utc)
stm.tm_sec -= icaltime_local_utc_offset();
+
tut = mktime(&stm);
- return tut;
+ stm = *(localtime(&tut));
+
+ tt.second = stm.tm_sec;
+ tt.minute = stm.tm_min;
+ tt.hour = stm.tm_hour;
+ tt.day = stm.tm_mday;
+ tt.month = stm.tm_mon +1;
+ tt.year = stm.tm_year+1900;
+
+ return tt;
}
+#ifndef ICAL_NO_LIBICAL
+#include "icalvalue.h"
struct icaltimetype icaltime_from_string(const char* str)
{
- struct icaltimetype tt;
- icalvalue *v = icalvalue_new_from_string(ICAL_DATETIME_VALUE,str);
-
- if (v == 0){
+ struct icaltimetype tt = icaltime_null_time();
+ int size;
+
+ icalerror_check_arg_re(str!=0,"str",icaltime_null_time());
+
+ size = strlen(str);
+
+ if(size == 15) { /* floating time */
+ tt.is_utc = 0;
+ tt.is_date = 0;
+ } else if (size == 16) { /* UTC time, ends in 'Z'*/
+ tt.is_utc = 1;
+ tt.is_date = 0;
+
+ if(str[15] != 'Z'){
+ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
+ return icaltime_null_time();
+ }
+
+ } else if (size == 8) { /* A DATE */
+ tt.is_utc = 0;
+ tt.is_date = 1;
+ } else { /* error */
+ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
return icaltime_null_time();
}
- tt = icalvalue_get_datetime(v);
+ if(tt.is_date == 1){
+ sscanf(str,"%04d%02d%02d",&tt.year,&tt.month,&tt.day);
+ } else {
+ char tsep;
+ sscanf(str,"%04d%02d%02d%c%02d%02d%02d",&tt.year,&tt.month,&tt.day,
+ &tsep,&tt.hour,&tt.minute,&tt.second);
- icalvalue_free(v);
+ if(tsep != 'T'){
+ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
+ return icaltime_null_time();
+ }
- return tt;
-
+ }
+
+ return tt;
}
+#endif
char ctime_str[20];
char* icaltime_as_ctime(struct icaltimetype t)
@@ -128,6 +346,7 @@ short days_in_month[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
short icaltime_days_in_month(short month,short year)
{
+
int is_leap =0;
int days = days_in_month[month];
@@ -152,7 +371,11 @@ short icaltime_day_of_week(struct icaltimetype t){
time_t tt = icaltime_as_timet(t);
struct tm *tm;
- tm = gmtime(&tt);
+ if(t.is_utc == 1){
+ tm = gmtime(&tt);
+ } else {
+ tm = localtime(&tt);
+ }
return tm->tm_wday+1;
}
@@ -161,26 +384,50 @@ short icaltime_start_doy_of_week(struct icaltimetype t){
time_t tt = icaltime_as_timet(t);
time_t start_tt;
struct tm *stm;
+ int syear;
stm = gmtime(&tt);
+ syear = stm->tm_year;
start_tt = tt - stm->tm_wday*(60*60*24);
stm = gmtime(&start_tt);
+
+ if(syear == stm->tm_year){
+ return stm->tm_yday+1;
+ } else {
+ /* return negative to indicate that start of week is in
+ previous year. */
+ int is_leap = 0;
+ int year = stm->tm_year;
- return stm->tm_yday;
+ if( (year % 4 == 0 && year % 100 != 0) ||
+ year % 400 == 0){
+ is_leap =1;
+ }
+
+ return (stm->tm_yday+1)-(365+is_leap);
+ }
+
}
+
+
short icaltime_day_of_year(struct icaltimetype t){
time_t tt = icaltime_as_timet(t);
struct tm *stm;
- stm = gmtime(&tt);
+ if(t.is_utc==1){
+ stm = gmtime(&tt);
+ } else {
+ stm = localtime(&tt);
+ }
- return stm->tm_yday;
+ return stm->tm_yday+1;
}
+/* Jan 1 is day #1, not 0 */
struct icaltimetype icaltime_from_day_of_year(short doy, short year)
{
struct tm stm;
@@ -195,9 +442,10 @@ struct icaltimetype icaltime_from_day_of_year(short doy, short year)
/* Now add in the days */
+ doy--;
tt += doy *60*60*24;
- return icaltime_from_timet(tt, 1, 1);
+ return icaltime_from_timet(tt, 1);
}
struct icaltimetype icaltime_null_time()
@@ -255,102 +503,83 @@ icaltime_compare_date_only (struct icaltimetype a, struct icaltimetype b)
}
}
-/* convert tt, of timezone tzid, into a utc time */
-struct icaltimetype icaltime_as_utc(struct icaltimetype tt,const char* tzid)
+struct icalperiodtype icalperiodtype_from_string (const char* str)
{
- time_t offset, tm;
- struct icaltimetype utc;
+
+ struct icalperiodtype p, null_p;
+ char *s = strdup(str);
+ char *start, *end = s;
+ int old_ieaf = icalerror_errors_are_fatal;
- offset = icaltime_utc_offset(tt,tzid);
- tm = icaltime_as_timet(tt);
+ p.start = p.end = icaltime_null_time();
+ p.duration = icaldurationtype_from_int(0);
- tm += offset;
+ null_p = p;
- utc = icaltime_from_timet(tm,0,0);
+ if(s == 0) goto error;
- return utc;
-}
+ start = s;
+ end = strchr(s, '/');
-/* convert tt, a time in UTC, into a time in timezone tzid */
-struct icaltimetype icaltime_as_zone(struct icaltimetype tt,const char* tzid)
-{
- time_t offset, tm;
- struct icaltimetype zone;
+ if(end == 0) goto error;
- offset = icaltime_utc_offset(tt,tzid);
- tm = icaltime_as_timet(tt);
+ *end = 0;
+ end++;
- tm -= offset;
-
- zone = icaltime_from_timet(tm,0,0);
+ p.start = icaltime_from_string(start);
- return zone;
+ if (icaltime_is_null_time(p.start)) goto error;
+
+ icalerror_errors_are_fatal = 0;
+ p.end = icaltime_from_string(end);
+ icalerror_errors_are_fatal = old_ieaf;
-}
+ if (icaltime_is_null_time(p.end)){
-/* Return the offset of the named zone as seconds. tt is a time
- indicating the date for which you want the offset */
-time_t icaltime_utc_offset(struct icaltimetype tt, const char* tzid)
-{
-#ifdef HAVE_TIMEZONE
- extern long int timezone;
-#endif
- time_t now;
- struct tm *stm;
+ p.duration = icaldurationtype_from_string(end);
- char *tzstr = 0;
- char *tmp;
+ if(icaldurationtype_as_int(p.duration) == 0) goto error;
+ }
- /* Put the new time zone into the environment */
- if(getenv("TZ") != 0){
- tzstr = (char*)strdup(getenv("TZ"));
- }
+ return p;
- tmp = (char*)malloc(1024);
- snprintf(tmp,1024,"TZ=%s",tzid);
+ error:
+ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
+ return null_p;
+}
- putenv(tmp);
- /* Get the offset */
+const char* icalperiodtype_as_ical_string(struct icalperiodtype p)
+{
- now = icaltime_as_timet(tt);
+ const char* start;
+ const char* end;
- stm = localtime(&now); /* This sets 'timezone'*/
+ char *buf;
+ size_t buf_size = 40;
+ char* buf_ptr = 0;
- /* restore the original environment */
+ buf = (char*)icalmemory_new_buffer(buf_size);
+ buf_ptr = buf;
+
- if(tzstr!=0){
- putenv(tzstr);
+ start = icaltime_as_ical_string(p.start);
+
+ icalmemory_append_string(&buf, &buf_ptr, &buf_size, start);
+
+ if(!icaltime_is_null_time(p.end)){
+ end = icaltime_as_ical_string(p.end);
} else {
- putenv("TZ"); /* Delete from environment */
+ end = icaldurationtype_as_ical_string(p.duration);
}
-
-#ifdef HAVE_TIMEZONE
- return timezone;
-#else
- return -stm->tm_gmtoff;
-#endif
-}
-time_t icaltime_local_utc_offset()
-{
- time_t now;
- struct tm *stm;
+ icalmemory_append_char(&buf, &buf_ptr, &buf_size, '/');
- stm = localtime(&now); /* This sets 'timezone'*/
+ icalmemory_append_string(&buf, &buf_ptr, &buf_size, end);
-#ifdef HAVE_TIMEZONE
- return timezone;
-#else
- return -stm->tm_gmtoff;
-#endif
+ return buf;
}
-
-
-
-
-
time_t
icalperiodtype_duration (struct icalperiodtype period);
@@ -360,20 +589,21 @@ icalperiodtype_end (struct icalperiodtype period);
/* From Russel Steinthal */
-time_t icaldurationtype_as_timet(struct icaldurationtype dur)
+int icaldurationtype_as_int(struct icaldurationtype dur)
{
- return (time_t) (dur.seconds +
- (60 * dur.minutes) +
- (60 * 60 * dur.hours) +
- (60 * 60 * 24 * dur.days) +
- (60 * 60 * 24 * 7 * dur.weeks));
+ return (int)( (dur.seconds +
+ (60 * dur.minutes) +
+ (60 * 60 * dur.hours) +
+ (60 * 60 * 24 * dur.days) +
+ (60 * 60 * 24 * 7 * dur.weeks))
+ * (dur.is_neg==1? -1 : 1) ) ;
}
/* From Seth Alves, <alves@hungry.com> */
-struct icaldurationtype icaldurationtype_from_timet(time_t t)
+struct icaldurationtype icaldurationtype_from_int(int t)
{
struct icaldurationtype dur;
- time_t used = 0;
+ int used = 0;
dur.weeks = (t - used) / (60 * 60 * 24 * 7);
used += dur.weeks * (60 * 60 * 24 * 7);
@@ -385,33 +615,209 @@ struct icaldurationtype icaldurationtype_from_timet(time_t t)
used += dur.minutes * (60);
dur.seconds = (t - used);
+ dur.is_neg = t<0? 1 : 0;
+
return dur;
}
+#ifndef ICAL_NO_LIBICAL
+#include "icalvalue.h"
struct icaldurationtype icaldurationtype_from_string(const char* str)
{
- icalvalue *v = icalvalue_new_from_string(ICAL_DURATION_VALUE,str);
+ int i;
+ int begin_flag = 0;
+ int time_flag = 0;
+ int date_flag = 0;
+ int week_flag = 0;
+ int digits=-1;
+ int scan_size = -1;
+ int size = strlen(str);
+ char p;
+ struct icaldurationtype d;
+
+ memset(&d, 0, sizeof(struct icaldurationtype));
+
+ for(i=0;i != size;i++){
+ p = str[i];
+
+ switch(p)
+ {
+ case '-': {
+ if(i != 0 || begin_flag == 1) goto error;
+
+ d.is_neg = 1;
+ break;
+ }
+
+ case 'P': {
+ if (i != 0 && i !=1 ) goto error;
+ begin_flag = 1;
+ break;
+ }
+
+ case 'T': {
+ time_flag = 1;
+ break;
+ }
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+
+ /* HACK. Skip any more digits if the l;ast one
+ read has not been assigned */
+ if(digits != -1){
+ break;
+ }
+
+ if (begin_flag == 0) goto error;
+ /* Get all of the digits, not one at a time */
+ scan_size = sscanf((char*)(str+i),"%d",&digits);
+ if(scan_size == 0) goto error;
+ break;
+ }
+
+ case 'H': {
+ if (time_flag == 0||week_flag == 1||d.hours !=0||digits ==-1)
+ goto error;
+ d.hours = digits; digits = -1;
+ break;
+ }
+ case 'M': {
+ if (time_flag == 0||week_flag==1||d.minutes != 0||digits ==-1)
+ goto error;
+ d.minutes = digits; digits = -1;
+ break;
+ }
+ case 'S': {
+ if (time_flag == 0||week_flag==1||d.seconds!=0||digits ==-1)
+ goto error;
+ d.seconds = digits; digits = -1;
+ break;
+ }
+ case 'W': {
+ if (time_flag==1||date_flag==1||d.weeks!=0||digits ==-1)
+ goto error;
+ week_flag = 1;
+ d.weeks = digits; digits = -1;
+ break;
+ }
+ case 'D': {
+ if (time_flag==1||week_flag==1||d.days!=0||digits ==-1)
+ goto error;
+ date_flag = 1;
+ d.days = digits; digits = -1;
+ break;
+ }
+ default: {
+ goto error;
+ }
+
+ }
+ }
+
+ return d;
+
+
+ error:
+ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
+ memset(&d, 0, sizeof(struct icaldurationtype));
+ return d;
+
+}
+
+#define TMP_BUF_SIZE 1024
+void append_duration_segment(char** buf, char** buf_ptr, size_t* buf_size,
+ char* sep, unsigned int value) {
+
+ char temp[TMP_BUF_SIZE];
+
+ sprintf(temp,"%d",value);
+
+ icalmemory_append_string(buf, buf_ptr, buf_size, temp);
+ icalmemory_append_string(buf, buf_ptr, buf_size, sep);
+
+}
+
+char* icaldurationtype_as_ical_string(struct icaldurationtype d)
+{
- if( v !=0){
- return icalvalue_get_duration(v);
+ char *buf, *output_line;
+ size_t buf_size = 256;
+ char* buf_ptr = 0;
+ int seconds;
+
+ buf = (char*)icalmemory_new_buffer(buf_size);
+ buf_ptr = buf;
+
+
+ seconds = icaldurationtype_as_int(d);
+
+ if(seconds !=0){
+
+ if(d.is_neg == 1){
+ icalmemory_append_char(&buf, &buf_ptr, &buf_size, '-');
+ }
+
+ icalmemory_append_char(&buf, &buf_ptr, &buf_size, 'P');
+
+ if (d.weeks != 0 ) {
+ append_duration_segment(&buf, &buf_ptr, &buf_size, "W", d.weeks);
+ }
+
+ if (d.days != 0 ) {
+ append_duration_segment(&buf, &buf_ptr, &buf_size, "D", d.days);
+ }
+
+ if (d.hours != 0 || d.minutes != 0 || d.seconds != 0) {
+
+ icalmemory_append_string(&buf, &buf_ptr, &buf_size, "T");
+
+ if (d.hours != 0 ) {
+ append_duration_segment(&buf, &buf_ptr, &buf_size, "H", d.hours);
+ }
+ if (d.minutes != 0 ) {
+ append_duration_segment(&buf, &buf_ptr, &buf_size, "M",
+ d.minutes);
+ }
+ if (d.seconds != 0 ) {
+ append_duration_segment(&buf, &buf_ptr, &buf_size, "S",
+ d.seconds);
+ }
+
+ }
} else {
- struct icaldurationtype dur;
- memset(&dur,0,sizeof(struct icaldurationtype));
- return dur;
+ icalmemory_append_string(&buf, &buf_ptr, &buf_size, "PTS0");
}
+ output_line = icalmemory_tmp_copy(buf);
+ icalmemory_free_buffer(buf);
+
+ return output_line;
+
}
+#endif
struct icaltimetype icaltime_add(struct icaltimetype t,
struct icaldurationtype d)
{
- time_t tt = icaltime_as_timet(t);
- time_t dt = icaldurationtype_as_timet(d);
+ int dt = icaldurationtype_as_int(d);
+
+ t.second += dt;
- return icaltime_from_timet(tt + dt, t.is_date, t.is_utc);
+ t = icaltime_normalize(t);
+ return t;
}
struct icaldurationtype icaltime_subtract(struct icaltimetype t1,
@@ -421,7 +827,7 @@ struct icaldurationtype icaltime_subtract(struct icaltimetype t1,
time_t t1t = icaltime_as_timet(t1);
time_t t2t = icaltime_as_timet(t2);
- return icaldurationtype_from_timet(t1t-t2t);
+ return icaldurationtype_from_int(t1t-t2t);
}
diff --git a/libical/src/libical/icaltime.h b/libical/src/libical/icaltime.h
index 64617e578d..d624041c29 100644
--- a/libical/src/libical/icaltime.h
+++ b/libical/src/libical/icaltime.h
@@ -5,6 +5,7 @@
$Id$
+
$Locker$
(C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org
@@ -50,8 +51,38 @@ struct icaltimetype
int is_utc; /* 1-> time is in UTC timezone */
int is_date; /* 1 -> interpret this as date. */
+
+ const char* zone; /*Ptr to Olsen placename. Libical does not own mem*/
};
+/* Convert seconds past UNIX epoch to a timetype*/
+struct icaltimetype icaltime_from_timet(time_t v, int is_date);
+time_t icaltime_as_timet(struct icaltimetype);
+char* icaltime_as_ical_string(struct icaltimetype tt);
+
+/* Like icaltime_from_timet(), except that the input may be in seconds
+ past the epoch in floating time */
+struct icaltimetype icaltime_from_int(int v, int is_date, int is_utc);
+int icaltime_as_int(struct icaltimetype);
+
+/* create a time from an ISO format string */
+struct icaltimetype icaltime_from_string(const char* str);
+
+/* Routines for handling timezones */
+/* Return the offset of the named zone as seconds. tt is a time
+ indicating the date for which you want the offset */
+int icaltime_utc_offset(struct icaltimetype tt, const char* tzid);
+
+/* convert tt, of timezone tzid, into a utc time. Does nothing if the
+ time is already UTC. */
+struct icaltimetype icaltime_as_utc(struct icaltimetype tt,
+ const char* tzid);
+
+/* convert tt, a time in UTC, into a time in timezone tzid */
+struct icaltimetype icaltime_as_zone(struct icaltimetype tt,
+ const char* tzid);
+
+
struct icaltimetype icaltime_null_time(void);
int icaltime_is_null_time(struct icaltimetype t);
@@ -64,9 +95,6 @@ struct icaltimetype icaltime_from_day_of_year(short doy, short year);
short icaltime_day_of_week(struct icaltimetype t);
short icaltime_start_doy_of_week(struct icaltimetype t);
-struct icaltimetype icaltime_from_timet(time_t v, int is_date, int is_utc);
-struct icaltimetype icaltime_from_string(const char* str);
-time_t icaltime_as_timet(struct icaltimetype);
char* icaltime_as_ctime(struct icaltimetype);
short icaltime_week_number(short day_of_month, short month, short year);
@@ -80,22 +108,6 @@ int icaltime_compare_date_only(struct icaltimetype a, struct icaltimetype b);
short icaltime_days_in_month(short month,short year);
-/* Routines for handling timezones */
-
-/* Return the offset of the named zone as seconds. tt is a time
- indicating the date for which you want the offset */
-time_t icaltime_utc_offset(struct icaltimetype tt, const char* tzid);
-
-time_t icaltime_local_utc_offset();
-
-
-/* convert tt, of timezone tzid, into a utc time */
-struct icaltimetype icaltime_as_utc(struct icaltimetype tt,const char* tzid);
-
-/* convert tt, a time in UTC, into a time in timezone tzid */
-struct icaltimetype icaltime_as_zone(struct icaltimetype tt,const char* tzid);
-
-
struct icaldurationtype
{
@@ -107,9 +119,10 @@ struct icaldurationtype
unsigned int seconds;
};
-struct icaldurationtype icaldurationtype_from_timet(time_t t);
+struct icaldurationtype icaldurationtype_from_int(int t);
struct icaldurationtype icaldurationtype_from_string(const char*);
-time_t icaldurationtype_as_timet(struct icaldurationtype duration);
+int icaldurationtype_as_int(struct icaldurationtype duration);
+char* icaldurationtype_as_ical_string(struct icaldurationtype d);
struct icalperiodtype
@@ -119,6 +132,9 @@ struct icalperiodtype
struct icaldurationtype duration;
};
+struct icalperiodtype icalperiodtype_from_string (const char* str);
+const char* icalperiodtype_as_ical_string(struct icalperiodtype p);
+
time_t icalperiodtype_duration(struct icalperiodtype period);
time_t icalperiodtype_end(struct icalperiodtype period);
diff --git a/libical/src/libical/icaltypes.c b/libical/src/libical/icaltypes.c
index e726904fcf..4afc8916bb 100644
--- a/libical/src/libical/icaltypes.c
+++ b/libical/src/libical/icaltypes.c
@@ -4,6 +4,7 @@
CREATOR: eric 16 May 1999
$Id$
+
$Locker$
@@ -149,6 +150,42 @@ void* icalattachtype_get_binary(struct icalattachtype* v)
}
+struct icaltriggertype icaltriggertype_from_string(const char* str)
+{
+
+
+ struct icaltriggertype tr, null_tr;
+ int old_ieaf = icalerror_errors_are_fatal;
+
+ tr.time= icaltime_null_time();
+ tr.duration = icaldurationtype_from_int(0);
+
+ null_tr = tr;
+
+ if(str == 0) goto error;
+
+
+ icalerror_errors_are_fatal = 0;
+
+ tr.time = icaltime_from_string(str);
+
+ icalerror_errors_are_fatal = old_ieaf;
+
+ if (icaltime_is_null_time(tr.time)){
+
+ tr.duration = icaldurationtype_from_string(str);
+
+ if(icaldurationtype_as_int(tr.duration) == 0) goto error;
+ }
+
+ return tr;
+
+ error:
+ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
+ return null_tr;
+
+}
+
struct icalreqstattype icalreqstattype_from_string(char* str)
{
diff --git a/libical/src/libical/icaltypes.h b/libical/src/libical/icaltypes.h
index d2a106883b..ef4f874064 100644
--- a/libical/src/libical/icaltypes.h
+++ b/libical/src/libical/icaltypes.h
@@ -67,15 +67,13 @@ struct icalgeotype
float lon;
};
-
-
-union icaltriggertype
+struct icaltriggertype
{
struct icaltimetype time;
struct icaldurationtype duration;
};
-
+struct icaltriggertype icaltriggertype_from_string(const char* str);
/* struct icalreqstattype. This struct contains two string pointers,
but don't try to free either of them. The "desc" string is a pointer
diff --git a/libical/src/libical/icalvalue.c.in b/libical/src/libical/icalvalue.c.in
index ae48207f42..cdcd12ba83 100644
--- a/libical/src/libical/icalvalue.c.in
+++ b/libical/src/libical/icalvalue.c.in
@@ -3,7 +3,7 @@
FILE: icalvalue.c
CREATOR: eric 02 May 1999
- $Id: icalvalue.c.in,v 1.2 2001/01/19 14:55:26 jpr Exp $
+ $Id: icalvalue.c.in,v 1.3 2001/01/23 20:22:33 jpr Exp $
(C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org
@@ -91,7 +91,7 @@ struct icalvalue_impl {
a reference*/
struct icalrecurrencetype *v_recur;
- union icaltriggertype v_trigger;
+ struct icaltriggertype v_trigger;
icalproperty_method v_method;
icalproperty_status v_status;
@@ -197,7 +197,7 @@ icalvalue* icalvalue_new_clone(icalvalue* value){
char* icalmemory_strdup_and_dequote(const char* str)
{
- char* p;
+ const char* p;
char* out = (char*)malloc(sizeof(char) * strlen(str) +1);
char* pout;
@@ -215,8 +215,9 @@ char* icalmemory_strdup_and_dequote(const char* str)
switch(*p){
case 0:
{
- break;
*pout = '\0';
+ break;
+
}
case 'n':
{
@@ -417,18 +418,56 @@ icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind,const char*
}
case ICAL_RECUR_VALUE:
+ {
+ struct icalrecurrencetype rt;
+ rt = icalrecurrencetype_from_string(str);
+ value = icalvalue_new_recur(rt);
+ break;
+ }
+
+ case ICAL_TIME_VALUE:
+ {
+ struct icaltimetype tt;
+ tt = icaltime_from_string(str);
+ value = icalvalue_new_time(tt);
+ break;
+ }
case ICAL_DATE_VALUE:
+ {
+ struct icaltimetype tt;
+ tt = icaltime_from_string(str);
+ value = icalvalue_new_date(tt);
+ break;
+ }
case ICAL_DATETIME_VALUE:
+ {
+ struct icaltimetype tt;
+ tt = icaltime_from_string(str);
+ value = icalvalue_new_datetime(tt);
+ break;
+ }
case ICAL_DATETIMEDATE_VALUE:
+ {
+ struct icaltimetype tt;
+ tt = icaltime_from_string(str);
+ value = icalvalue_new_datetimedate(tt);
+ break;
+ }
+
case ICAL_DATETIMEPERIOD_VALUE:
- case ICAL_TIME_VALUE:
- case ICAL_DURATION_VALUE:
- case ICAL_PERIOD_VALUE:
- case ICAL_TRIGGER_VALUE:
+ case ICAL_DURATION_VALUE:
+ case ICAL_PERIOD_VALUE:
{
value = icalparser_parse_value(kind,str,error);
break;
}
+
+ case ICAL_TRIGGER_VALUE:
+ {
+ struct icaltriggertype tr = icaltriggertype_from_string(str);
+ value = icalvalue_new_trigger(tr);
+ break;
+ }
default:
{
@@ -556,14 +595,15 @@ char* icalvalue_binary_as_ical_string(icalvalue* value) {
}
+#define MAX_INT_DIGITS 12 /* Enough for 2^32 + sign*/
char* icalvalue_int_as_ical_string(icalvalue* value) {
int data;
- char* str = (char*)icalmemory_tmp_buffer(2);
+ char* str = (char*)icalmemory_tmp_buffer(MAX_INT_DIGITS);
icalerror_check_arg_rz( (value!=0),"value");
data = icalvalue_get_integer(value);
- sprintf(str,"%d",data);
+ snprintf(str,MAX_INT_DIGITS,"%d",data);
return str;
}
@@ -608,101 +648,10 @@ char* icalvalue_string_as_ical_string(icalvalue* value) {
char* icalvalue_recur_as_ical_string(icalvalue* value)
{
- char* str;
- char *str_p;
- size_t buf_sz = 200;
- char temp[20];
- int i,j;
struct icalvalue_impl *impl = (struct icalvalue_impl*)value;
struct icalrecurrencetype *recur = impl->data.v_recur;
- 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){
- return 0;
- }
-
- str = (char*)icalmemory_tmp_buffer(buf_sz);
- str_p = str;
-
- icalmemory_append_string(&str,&str_p,&buf_sz,"FREQ=");
- icalmemory_append_string(&str,&str_p,&buf_sz,
- icalrecur_recurrence_to_string(recur->freq));
-
- if(recur->until.year != 0){
-
- temp[0] = 0;
- print_datetime_to_string(temp,&(recur->until));
-
- icalmemory_append_string(&str,&str_p,&buf_sz,";UNTIL=");
- icalmemory_append_string(&str,&str_p,&buf_sz, temp);
- }
-
- if(recur->count != 0){
- sprintf(temp,"%d",recur->count);
- icalmemory_append_string(&str,&str_p,&buf_sz,";COUNT=");
- icalmemory_append_string(&str,&str_p,&buf_sz, temp);
- }
-
- if(recur->interval != 0){
- sprintf(temp,"%d",recur->interval);
- icalmemory_append_string(&str,&str_p,&buf_sz,";INTERVAL=");
- icalmemory_append_string(&str,&str_p,&buf_sz, temp);
- }
-
- 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,recurmap[j].str);
-
- for(i=0; i< limit && array[i] != ICAL_RECURRENCE_ARRAY_MAX;
- i++){
- if (j == 3) { /* BYDAY */
- short dow = icalrecurrencetype_day_day_of_week(array[i]);
- const char *daystr = icalrecur_weekday_to_string(dow);
- short pos = icalrecurrencetype_day_position(array[i]);
-
- if (pos == 0)
- icalmemory_append_string(&str,&str_p,&buf_sz,daystr);
- else {
- sprintf(temp,"%d%s",pos,daystr);
- icalmemory_append_string(&str,&str_p,&buf_sz,temp);
- }
-
- } else {
- sprintf(temp,"%d",array[i]);
- icalmemory_append_string(&str,&str_p,&buf_sz, temp);
- }
-
- if( (i+1)<limit &&array[i+1]
- != ICAL_RECURRENCE_ARRAY_MAX){
- icalmemory_append_char(&str,&str_p,&buf_sz,',');
- }
- }
- }
- }
-
- return str;
+ return icalrecurrencetype_as_string(recur);
}
char* icalvalue_text_as_ical_string(icalvalue* value) {
@@ -826,67 +775,17 @@ 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 temp[TMP_BUF_SIZE];
-
- sprintf(temp,"%d",value);
-
- icalmemory_append_string(buf, buf_ptr, buf_size, temp);
- icalmemory_append_string(buf, buf_ptr, buf_size, sep);
-
-}
char* icalvalue_duration_as_ical_string(icalvalue* value)
{
struct icaldurationtype data;
- char *buf, *output_line;
- size_t buf_size = 256;
- char* buf_ptr = 0;
icalerror_check_arg_rz( (value!=0),"value");
data = icalvalue_get_duration(value);
- buf = (char*)icalmemory_new_buffer(buf_size);
- buf_ptr = buf;
-
- if (data.is_neg)
- icalmemory_append_string(&buf, &buf_ptr, &buf_size, "-");
- icalmemory_append_string(&buf, &buf_ptr, &buf_size, "P");
-
-
- if (data.weeks != 0 ) {
- append_duration_segment(&buf, &buf_ptr, &buf_size, "W", data.weeks);
- }
-
- if (data.days != 0 ) {
- append_duration_segment(&buf, &buf_ptr, &buf_size, "D", data.days);
- }
-
- if (data.hours != 0 || data.minutes != 0 || data.seconds != 0) {
-
- icalmemory_append_string(&buf, &buf_ptr, &buf_size, "T");
+ return icaldurationtype_as_ical_string(data);
- if (data.hours != 0 ) {
- append_duration_segment(&buf, &buf_ptr, &buf_size, "H", data.hours);
- }
- if (data.minutes != 0 ) {
- append_duration_segment(&buf, &buf_ptr, &buf_size, "M", data.minutes);
- }
- if (data.seconds != 0 ) {
- append_duration_segment(&buf, &buf_ptr, &buf_size, "S", data.seconds);
- }
-
- }
-
- output_line = icalmemory_tmp_copy(buf);
- icalmemory_free_buffer(buf);
-
- return output_line;
-
-
}
void print_time_to_string(char* str, struct icaltimetype *data)
@@ -1087,31 +986,20 @@ char* icalvalue_period_as_ical_string(icalvalue* value) {
char* icalvalue_trigger_as_ical_string(icalvalue* value)
{
- union icaltriggertype data;
+ struct icaltriggertype data;
char* str;
- icalvalue *e;
icalerror_check_arg_rz( (value!=0),"value");
data = icalvalue_get_trigger(value);
str = (char*)icalmemory_tmp_buffer(60);
- if (data.time.is_date != -1){
- /* use the absolute date */
- e = icalvalue_new_datetime(data.time);
-
- strcpy (str, icalvalue_datetime_as_ical_string(e));
-
+ if(!icaltime_is_null_time(data.time)){
+ return icaltime_as_ical_string(data.time);
} else {
- /* use the duration */
- e = icalvalue_new_duration(data.duration);
-
- strcpy (str, icalvalue_duration_as_ical_string(e));
-
- }
+ return icaldurationtype_as_ical_string(data.duration);
+ }
- icalvalue_free(e);
- return str;
}
const char*
@@ -1220,6 +1108,20 @@ icalvalue_isa_value (void* value)
}
+int icalvalue_is_time(icalvalue* a) {
+ icalvalue_kind kind = icalvalue_isa(a);
+
+ if(kind == ICAL_DATETIMEDATE_VALUE ||
+ kind == ICAL_DATETIME_VALUE ||
+ kind == ICAL_DATE_VALUE ||
+ kind == ICAL_TIME_VALUE ){
+ return 1;
+ }
+
+ return 0;
+
+}
+
icalparameter_xliccomparetype
icalvalue_compare(icalvalue* a, icalvalue *b)
{
@@ -1230,7 +1132,8 @@ icalvalue_compare(icalvalue* a, icalvalue *b)
icalerror_check_arg_rz( (b!=0), "b");
/* Not the same type; they can only be unequal */
- if (icalvalue_isa(a) != icalvalue_isa(b)){
+ if( ! (icalvalue_is_time(a) && icalvalue_is_time(b)) &&
+ icalvalue_isa(a) != icalvalue_isa(b)){
return ICAL_XLICCOMPARETYPE_NOTEQUAL;
}
@@ -1271,6 +1174,21 @@ icalvalue_compare(icalvalue* a, icalvalue *b)
}
}
+ case ICAL_DURATION_VALUE:
+ {
+ int a = icaldurationtype_as_int(impla->data.v_duration);
+ int b = icaldurationtype_as_int(implb->data.v_duration);
+
+ if (a > b){
+ return ICAL_XLICCOMPARETYPE_GREATER;
+ } else if (a < b){
+ return ICAL_XLICCOMPARETYPE_LESS;
+ } else {
+ return ICAL_XLICCOMPARETYPE_EQUAL;
+ }
+ }
+
+
case ICAL_TEXT_VALUE:
case ICAL_URI_VALUE:
case ICAL_CALADDRESS_VALUE:
@@ -1278,7 +1196,6 @@ icalvalue_compare(icalvalue* a, icalvalue *b)
case ICAL_DATE_VALUE:
case ICAL_DATETIME_VALUE:
case ICAL_DATETIMEDATE_VALUE:
- case ICAL_DURATION_VALUE: /* HACK. Not correct for DURATION */
case ICAL_TIME_VALUE:
case ICAL_DATETIMEPERIOD_VALUE:
{
@@ -1292,7 +1209,7 @@ icalvalue_compare(icalvalue* a, icalvalue *b)
} else if (r < 0){
return ICAL_XLICCOMPARETYPE_LESS;
} else {
- return 0;
+ return ICAL_XLICCOMPARETYPE_EQUAL;
}
@@ -1350,9 +1267,7 @@ icalproperty* icalvalue_get_parent(icalvalue* value)
-/* 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. */
+/* Recur is a special case, so it is not auto generated. */
icalvalue*
icalvalue_new_recur (struct icalrecurrencetype v)
{
diff --git a/libical/src/libical/icalyacc.y b/libical/src/libical/icalyacc.y
index 0512d6b585..982682d331 100644
--- a/libical/src/libical/icalyacc.y
+++ b/libical/src/libical/icalyacc.y
@@ -6,7 +6,7 @@
DESCRIPTION:
- $Id: icalyacc.y,v 1.10 2000/12/12 00:27:40 federico Exp $
+ $Id: icalyacc.y,v 1.11 2001/01/23 20:22:33 jpr Exp $
$Locker: $
(C) COPYRIGHT 1999 Eric Busboom
@@ -48,14 +48,10 @@ int utcsign;
/* Globals for DURATION values */
struct icaldurationtype duration;
-/* Globals for RECUR values */
-struct icalrecurrencetype recur;
-short skiplist[367];
-short skippos;
-int dow_pos;
+/* Globals for TRIGGER values */
+struct icaltriggertype trigger;
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);
@@ -179,13 +175,10 @@ int yylex(void); /* Or this. */
%%
value:
- binary_value
- | boolean_value
- | date_value
+ date_value
| datetime_value
| duration_value
| period_value
- | recur_value
| utcoffset_value
| error {
icalparser_yy_value = 0;
@@ -193,13 +186,6 @@ value:
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
{
@@ -369,87 +355,9 @@ period_value: DIGITS TIME_CHAR DIGITS utc_char '/' DIGITS TIME_CHAR DIGITS utc
}
-
-/* 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; }
- | MO { skiplist[skippos]=ICAL_MONDAY_WEEKDAY; }
- | TU { skiplist[skippos]=ICAL_TUESDAY_WEEKDAY; }
- | WE { skiplist[skippos]=ICAL_WEDNESDAY_WEEKDAY; }
- | TH { skiplist[skippos]=ICAL_THURSDAY_WEEKDAY; }
- | FR { skiplist[skippos]=ICAL_FRIDAY_WEEKDAY; }
- | SA { skiplist[skippos]=ICAL_SATURDAY_WEEKDAY; }
- ;
-
-/* HACK. The skippos has only 8 positions, but the spec permits any number */
-
-weekday_list:
- weekday {if( skippos<8) skippos++;}
- | DIGITS weekday { dow_pos = atoi($1);
- skiplist[skippos] += 8*dow_pos; if( skippos<8) skippos++; }
- | MINUS DIGITS weekday { dow_pos = atoi($2);
- skiplist[skippos] -= 8*dow_pos; if( skippos<8) skippos++; }
- | weekday_list COMMA weekday {if( skippos<8) skippos++;};
- | weekday_list COMMA DIGITS weekday { dow_pos = atoi($3);
- skiplist[skippos] += 8*dow_pos;if( skippos<8) skippos++;}
- | weekday_list COMMA MINUS DIGITS weekday { dow_pos = atoi($4);
- skiplist[skippos] -= 8*dow_pos;if( skippos<8) skippos++;}
+trigger:
-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 */
@@ -467,26 +375,8 @@ utcoffset_value:
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;
diff --git a/libical/src/libicalss/Makefile.am b/libical/src/libicalss/Makefile.am
index 0cbecbedea..732d970738 100644
--- a/libical/src/libicalss/Makefile.am
+++ b/libical/src/libicalss/Makefile.am
@@ -17,12 +17,12 @@ libicalss_la_LDFLAGS = -version-info 0:0:0
libicalss_la_SOURCES = \
icalclassify.c \
+ icalgauge.c \
+ icalgaugeimpl.h \
icaldirset.c \
icaldirsetimpl.h \
icalfileset.c \
icalfilesetimpl.h \
- icalgauge.c \
- icalgaugeimpl.h \
icalset.c \
icalsslexer.l \
icalssutil.c \
@@ -35,11 +35,11 @@ libicalss_la_SOURCES = \
libicalssincludedir = $(includedir)
COMBINEDHEADERS = \
+ icalgauge.h \
icalset.h \
icalfileset.h \
icaldirset.h \
icalcalendar.h \
- icalgauge.h \
icalssutil.h \
icalclassify.h \
icalspanlist.h \
diff --git a/libical/src/libicalss/icalcstp.h b/libical/src/libicalss/icalcstp.h
index 63f5af913f..2ebccd622a 100644
--- a/libical/src/libicalss/icalcstp.h
+++ b/libical/src/libicalss/icalcstp.h
@@ -52,9 +52,10 @@
1) Construct a new icalcstps, bound to your code via stubs
2) Repeat forever:
- 2a) Get string from client & give to icalcstps_next_input()
- 2b) Call icalcstps_next_output. Send string to client.
-
+ 2a) Get string from client & give to icalcstps_next_input()
+ 2b) Repeat until icalcstp_next_output returns 0:
+ 2b1) Call icalcstps_next_output.
+ 2b2) Send string to client.
*/
@@ -101,11 +102,11 @@ int icalcstps_next_input(icalcstps* cstp);
/* How to use:
1) Construct a new icalcstpc
- 2) Issue a command
+ 2) Issue a command by calling one of the command routines.
3) Repeat until both call icalcstpc_next_output and
icalcstpc_next_input return 0:
- 3a) Call icalcstpc_next_output. Send string to server.
- 3b) Get string from server, & give to icalcstp_next_input()
+ 3a) Call icalcstpc_next_output. Send string to server.
+ 3b) Get string from server, & give to icalcstp_next_input()
4) Iterate with icalcstpc_first_response & icalcstp_next_response to
get the servers responses
5) Repeat at #2
diff --git a/libical/src/test/Makefile.am b/libical/src/test/Makefile.am
index a2ebea7610..2830afdaa0 100644
--- a/libical/src/test/Makefile.am
+++ b/libical/src/test/Makefile.am
@@ -4,14 +4,14 @@ noinst_PROGRAMS = copycluster regression parser storage stow recur testmime test
LDADD = ../libicalss/libicalss.la ../libicalvcal/libicalvcal.la ../libical/libical.la
INCLUDES = \
- -I . \
+ -I. \
-I../libicalvcal \
- -I $(srcdir)/../libicalvcal \
- -I $(srcdir) \
+ -I$(srcdir)/../libicalvcal \
+ -I$(srcdir) \
-I../libical \
- -I $(srcdir)/../libical \
+ -I$(srcdir)/../libical \
-I../libicalss \
- -I $(srcdir)/../libicalss
+ -I$(srcdir)/../libicalss
copycluster_SOURCES = copycluster.c
regression_SOURCES = regression.c
diff --git a/libical/src/test/icaltestparser.c b/libical/src/test/icaltestparser.c
index 71f91b641f..e5973e0d4a 100644
--- a/libical/src/test/icaltestparser.c
+++ b/libical/src/test/icaltestparser.c
@@ -112,7 +112,6 @@ int main(int argc, char* argv[])
if (c != 0){
/*icalcomponent_convert_errors(c);*/
printf("%s",icalcomponent_as_ical_string(c));
- icalparser_claim(parser);
printf("\n---------------\n");
icalcomponent_free(c);
}
diff --git a/libical/src/test/regression.c b/libical/src/test/regression.c
index b14e8aa6f8..66307bb405 100644
--- a/libical/src/test/regression.c
+++ b/libical/src/test/regression.c
@@ -35,6 +35,10 @@
#include <stdlib.h> /* for malloc */
#include <stdio.h> /* for printf */
#include <time.h> /* for time() */
+#include <unistd.h> /* for unlink, fork */
+#include <sys/wait.h> /* For waitpid */
+#include <sys/types.h> /* For wait pid */
+#include <sys/time.h> /* for select */
/* This example creates and minipulates the ical object that appears
@@ -89,8 +93,8 @@ icalcomponent* create_simple_component()
icalcomponent* calendar;
struct icalperiodtype rtime;
- rtime.start = icaltime_from_timet( time(0),0,0);
- rtime.end = icaltime_from_timet( time(0),0,0);
+ rtime.start = icaltime_from_timet( time(0),0);
+ rtime.end = icaltime_from_timet( time(0),0);
rtime.end.hour++;
@@ -119,12 +123,12 @@ icalcomponent* create_new_component()
icalcomponent* timezone;
icalcomponent* tzc;
icalcomponent* event;
- struct icaltimetype atime = icaltime_from_timet( time(0),0,0);
+ struct icaltimetype atime = icaltime_from_timet( time(0),0);
struct icalperiodtype rtime;
icalproperty* property;
- rtime.start = icaltime_from_timet( time(0),0,0);
- rtime.end = icaltime_from_timet( time(0),0,0);
+ rtime.start = icaltime_from_timet( time(0),0);
+ rtime.end = icaltime_from_timet( time(0),0);
rtime.end.hour++;
@@ -328,11 +332,11 @@ icalcomponent* create_new_component_with_va_args()
{
icalcomponent* calendar;
- struct icaltimetype atime = icaltime_from_timet( time(0),0,0);
+ struct icaltimetype atime = icaltime_from_timet( time(0),0);
struct icalperiodtype rtime;
- rtime.start = icaltime_from_timet( time(0),0,0);
- rtime.end = icaltime_from_timet( time(0),0,0);
+ rtime.start = icaltime_from_timet( time(0),0);
+ rtime.end = icaltime_from_timet( time(0),0);
rtime.end.hour++;
@@ -521,9 +525,9 @@ void test_values()
icalvalue_free(copy);
- v = icalvalue_new_date(icaltime_from_timet( time(0),0,0));
+ v = icalvalue_new_date(icaltime_from_timet( time(0),0));
printf("date 1: %s\n",icalvalue_as_ical_string(v));
- icalvalue_set_date(v,icaltime_from_timet( time(0)+3600,0,0));
+ icalvalue_set_date(v,icaltime_from_timet( time(0)+3600,0));
printf("date 2: %s\n",icalvalue_as_ical_string(v));
copy = icalvalue_new_clone(v);
@@ -803,7 +807,7 @@ int test_store()
icaldirset *s = icaldirset_new("store");
int i;
- rtime.start = icaltime_from_timet( time(0),0,0);
+ rtime.start = icaltime_from_timet( time(0),0);
cluster = icalfileset_new("clusterin.vcd");
@@ -946,7 +950,6 @@ int test_store()
int test_compare()
{
icalvalue *v1, *v2;
- icalcomponent *c, *gauge;
v1 = icalvalue_new_caladdress("cap://value/1");
v2 = icalvalue_new_clone(v1);
@@ -978,43 +981,19 @@ int test_compare()
printf("%d\n",icalvalue_compare(v1,v2));
-
- gauge =
- icalcomponent_vanew(
- ICAL_VCALENDAR_COMPONENT,
- icalcomponent_vanew(
- ICAL_VEVENT_COMPONENT,
- icalproperty_vanew_comment(
- "Comment",
- icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_EQUAL),
- 0),
- 0),
- 0);
-
- c = icalcomponent_vanew(
- ICAL_VEVENT_COMPONENT,
- icalproperty_vanew_comment(
- "Comment",
- 0),
- 0);
-
- printf("%s",icalcomponent_as_ical_string(gauge));
-
- printf("%d\n",icalgauge_test(c,gauge));
-
return 0;
}
void test_restriction()
{
icalcomponent *comp;
- struct icaltimetype atime = icaltime_from_timet( time(0),0,0);
+ struct icaltimetype atime = icaltime_from_timet( time(0),0);
int valid;
struct icalperiodtype rtime;
- rtime.start = icaltime_from_timet( time(0),0,0);
- rtime.end = icaltime_from_timet( time(0),0,0);
+ rtime.start = icaltime_from_timet( time(0),0);
+ rtime.end = icaltime_from_timet( time(0),0);
rtime.end.hour++;
@@ -1098,7 +1077,7 @@ void test_calendar()
icaldirset *s;
icalcalendar* calendar = icalcalendar_new("calendar");
icalerrorenum error;
- struct icaltimetype atime = icaltime_from_timet( time(0),0,0);
+ struct icaltimetype atime = icaltime_from_timet( time(0),0);
comp = icalcomponent_vanew(
ICAL_VEVENT_COMPONENT,
@@ -1139,36 +1118,56 @@ void test_calendar()
void test_increment(void);
-void test_recur()
+void print_occur(struct icalrecurrencetype recur, struct icaltimetype start)
{
- icalvalue *v;
+ struct icaltimetype next;
+ icalrecur_iterator* ritr;
+
+ time_t tt = icaltime_as_timet(start);
- v = icalvalue_new_from_string(ICAL_RECUR_VALUE,
- "FREQ=DAILY;COUNT=5;BYDAY=MO,TU,WE,TH,FR");
+ printf("#### %s\n",icalrecurrencetype_as_string(&recur));
+ printf("#### %s\n",ctime(&tt ));
+
+ for(ritr = icalrecur_iterator_new(recur,start),
+ next = icalrecur_iterator_next(ritr);
+ !icaltime_is_null_time(next);
+ next = icalrecur_iterator_next(ritr)){
+
+ tt = icaltime_as_timet(next);
+
+ printf(" %s",ctime(&tt ));
+
+ }
- printf("%s\n",icalvalue_as_ical_string(v));
+ icalrecur_iterator_free(ritr);
+}
- v = icalvalue_new_from_string(ICAL_RECUR_VALUE,
- "FREQ=YEARLY;UNTIL=123456T123456;BYSETPOS=-1,2");
+void test_recur()
+{
+ struct icalrecurrencetype rt;
+ struct icaltimetype start;
+ time_t array[25];
+ int i;
- printf("%s\n",icalvalue_as_ical_string(v));
+ rt = icalrecurrencetype_from_string("FREQ=MONTHLY;UNTIL=19971224T000000Z;INTERVAL=1;BYDAY=TU,2FR,3SA");
+ start = icaltime_from_string("19970905T090000Z");
- v = icalvalue_new_from_string(ICAL_RECUR_VALUE,
- "FREQ=YEARLY;UNTIL=123456T123456;INTERVAL=2;BYMONTH=1;BYDAY=SU;BYHOUR=8,9;BYMINUTE=30");
+ print_occur(rt,start);
- printf("%s\n",icalvalue_as_ical_string(v));
+ printf("\n Using icalrecur_expand_recurrence\n");
- v = icalvalue_new_from_string(ICAL_RECUR_VALUE,
- "FREQ=MONTHLY;BYDAY=-1MO,TU,WE,TH,FR");
+ icalrecur_expand_recurrence("FREQ=MONTHLY;UNTIL=19971224T000000Z;INTERVAL=1;BYDAY=TU,2FR,3SA",
+ icaltime_as_timet(start),
+ 25,
+ array);
- printf("%s\n",icalvalue_as_ical_string(v));
+ for(i =0; array[i] != 0 && i < 25 ; i++){
+
+ printf(" %s",ctime(&(array[i])));
+ }
- v = icalvalue_new_from_string(ICAL_RECUR_VALUE,
- "FREQ=WEEKLY;INTERVAL=20;WKST=SU;BYDAY=TU");
-
- printf("%s\n",icalvalue_as_ical_string(v));
-
- test_increment();
+
+/* test_increment();*/
}
@@ -1210,7 +1209,7 @@ void icalrecurrencetype_test()
"FREQ=YEARLY;UNTIL=20060101T000000;INTERVAL=2;BYDAY=SU,WE;BYSECOND=15,30; BYMONTH=1,6,11");
struct icalrecurrencetype r = icalvalue_get_recur(v);
- struct icaltimetype t = icaltime_from_timet( time(0), 0, 0);
+ struct icaltimetype t = icaltime_from_timet( time(0), 0);
struct icaltimetype next;
time_t tt;
@@ -1228,129 +1227,124 @@ void icalrecurrencetype_test()
}
-void test_recur_expansion()
-{
+/* From Federico Mena Quintero <federico@helixcode.com> */
+void test_recur_parameter_bug(){
- icalvalue *v;
-
- v = icalvalue_new_from_string(ICAL_RECUR_VALUE,
- "FREQ=YEARLY;UNTIL=123456T123456;INTERVAL=2;BYMONTH=1;BYDAY=SU;BYHOUR=8,9;BYMINUTE=30");
-
- printf("%s\n",icalvalue_as_ical_string(v));
-
- icalrecurrencetype_test();
-}
-
-static const char test_icalcomp_str[] =
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ical.h>
+
+ static const char test_icalcomp_str[] =
"BEGIN:VEVENT\r\n"
-"UID\r\n"
-" :20001121T203327-22955-2183-22933-0@guanabana.helixcode.com\r\n"
-"DTSTAMP\r\n"
-" :20001121T203327\r\n"
-"DTSTART\r\n"
-" :20001121T170000\r\n"
-"DTEND\r\n"
-" :20001121T180000\r\n"
-"SUMMARY\r\n"
-" :recur on the second Friday every month\\, forever\r\n"
-"SEQUENCE\r\n"
-" :3\r\n"
-"CLASS\r\n"
-" :PRIVATE\r\n"
"RRULE\r\n"
-" :FREQ=MONTHLY;INTERVAL=1;BYDAY=-2WE,2FR,3SA,-2WE\n"
+" ;X-EVOLUTION-ENDDATE=20030209T081500\r\n"
+" :FREQ=DAILY;COUNT=10;INTERVAL=6\r\n"
"END:VEVENT\r\n";
+
+ icalcomponent *icalcomp;
+ icalproperty *prop;
+ struct icalrecurrencetype recur;
+ int n_errors;
+
+ icalcomp = icalparser_parse_string ((char *) test_icalcomp_str);
+ if (!icalcomp) {
+ fprintf (stderr, "main(): could not parse the component\n");
+ exit (EXIT_FAILURE);
+ }
+
+ printf("%s\n\n",icalcomponent_as_ical_string(icalcomp));
-void test_recur_bug()
-{
- icalcomponent *icalcomp;
- char *str;
- icalproperty *prop;
- struct icalrecurrencetype r;
-
- /* Print the original stuff */
-
- puts ("The original component is:\n\n");
- puts (test_icalcomp_str);
-
- /* Parse the component */
+ n_errors = icalcomponent_count_errors (icalcomp);
+ if (n_errors) {
+ icalproperty *p;
- icalcomp = icalparser_parse_string ((char *) test_icalcomp_str);
-
- if (!icalcomp) {
- fprintf (stderr, "main(): Could not parse the stuff\n");
- exit (EXIT_FAILURE);
- }
-
- if (icalcomponent_isa (icalcomp) != ICAL_VEVENT_COMPONENT) {
- fprintf (stderr, "main(): This is not the test data I want\n");
- exit (EXIT_FAILURE);
- }
-
- /* Watch the property */
-
- prop = icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY);
- if (!prop) {
- fprintf (stderr, "main(): This is not the test data I want\n");
- exit (EXIT_FAILURE);
+ for (p = icalcomponent_get_first_property (icalcomp,
+ ICAL_XLICERROR_PROPERTY);
+ p;
+ p = icalcomponent_get_next_property (icalcomp,
+ ICAL_XLICERROR_PROPERTY)) {
+ char *str;
+
+ str = icalproperty_as_ical_string (p);
+ fprintf (stderr, "error: %s\n", str);
}
+ }
+
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY);
+ if (!prop) {
+ fprintf (stderr, "main(): could not get the RRULE property");
+ exit (EXIT_FAILURE);
+ }
+
+ recur = icalproperty_get_rrule (prop);
+
+ printf("%s\n",icalrecurrencetype_as_string(&recur));
- r = icalproperty_get_rrule (prop);
- printf ("\nThe first BYDAY element is %d\n", r.by_day[0]);
+}
- printf ("Position is %d, weekday is %d\n",
- icalrecurrencetype_day_position (r.by_day[0]),
- (int) icalrecurrencetype_day_day_of_week (r.by_day[0]));
- /* Re-stringify */
+void test_duration()
+{
- puts ("\nThe component looks like this after re-stringification:\n\n");
- str = icalcomponent_as_ical_string (icalcomp);
- if (!str) {
- fprintf (stderr, "main(): Could not stringify the component\n");
- exit (EXIT_FAILURE);
- }
+ struct icaldurationtype d;
- puts (str);
- puts ("\n");
+ d = icaldurationtype_from_string("PT8H30M");
+ printf("%s\n",icaldurationtype_as_ical_string(d));
+ assert(icaldurationtype_as_int(d) == 30600);
+
+ d = icaldurationtype_from_string("-PT8H30M");
+ printf("%s\n",icaldurationtype_as_ical_string(d));
+ assert(icaldurationtype_as_int(d) == -30600);
-}
+ d = icaldurationtype_from_string("PT10H10M10S");
+ printf("%s\n",icaldurationtype_as_ical_string(d));
+ assert(icaldurationtype_as_int(d) == 36610);
+ d = icaldurationtype_from_string("P7W");
+ printf("%s\n",icaldurationtype_as_ical_string(d));
+ assert(icaldurationtype_as_int(d) == 4233600);
-void test_duration()
-{
+ d = icaldurationtype_from_string("P2DT8H30M");
+ printf("%s\n",icaldurationtype_as_ical_string(d));
+ assert(icaldurationtype_as_int(d) == 203400);
- icalvalue *v;
+ icalerror_errors_are_fatal = 0;
- v = icalvalue_new_from_string(ICAL_DURATION_VALUE,
- "PT8H30M");
+ d = icaldurationtype_from_string("P-2DT8H30M");
+ printf("%s\n",icaldurationtype_as_ical_string(d));
+ assert(icaldurationtype_as_int(d) == 0);
- printf("%s\n",icalvalue_as_ical_string(v));
+ d = icaldurationtype_from_string("P7W8H");
+ printf("%s\n",icaldurationtype_as_ical_string(d));
+ assert(icaldurationtype_as_int(d) == 0);
+ d = icaldurationtype_from_string("T10H");
+ printf("%s\n",icaldurationtype_as_ical_string(d));
+ assert(icaldurationtype_as_int(d) == 0);
- v = icalvalue_new_from_string(ICAL_DURATION_VALUE,
- "-PT8H30M");
- printf("%s\n",icalvalue_as_ical_string(v));
+ icalerror_errors_are_fatal = 1;
- icalvalue_free(v);
- v = icalvalue_new_from_string(ICAL_PERIOD_VALUE,
- "19971015T050000Z/PT8H30M");
+}
- printf("%s\n",icalvalue_as_ical_string(v));
+void test_period()
+{
- icalvalue_free(v);
- v = icalvalue_new_from_string(ICAL_PERIOD_VALUE,
- "19971015T050000Z/19971015T060000Z");
+ struct icalperiodtype p;
- printf("%s\n",icalvalue_as_ical_string(v));
- icalvalue_free(v);
+ p = icalperiodtype_from_string("19971015T050000Z/PT8H30M");
+ printf("%s\n",icalperiodtype_as_ical_string(p));
+ p = icalperiodtype_from_string("19971015T050000Z/19971015T060000Z");
+ printf("%s\n",icalperiodtype_as_ical_string(p));
}
-
void test_strings(){
icalvalue *v;
@@ -1423,62 +1417,117 @@ void test_requeststat()
st2 = icalreqstattype_from_string("2.1");
printf("%s\n",icalreqstattype_as_string(st2));
+#ifndef ICAL_ERRORS_ARE_FATAL
st2 = icalreqstattype_from_string("16.4");
assert(st2.code == ICAL_UNKNOWN_STATUS);
st2 = icalreqstattype_from_string("1.");
assert(st2.code == ICAL_UNKNOWN_STATUS);
-
+#endif
}
char ictt_str[1024];
char* ictt_as_string(struct icaltimetype t)
{
- sprintf(ictt_str,"%02d-%02d-%02d %02d:%02d:%02d %c",t.year,t.month,t.day,
- t.hour,t.minute,t.second,t.is_utc?'Z':' ');
+ sprintf(ictt_str,"%02d-%02d-%02d %02d:%02d:%02d%s",t.year,t.month,t.day,
+ t.hour,t.minute,t.second,t.is_utc?" Z":"");
return ictt_str;
}
-void test_time()
+
+char* ical_timet_string(time_t t)
+{
+ struct tm stm = *(gmtime(&t));
+
+ sprintf(ictt_str,"%02d-%02d-%02d %02d:%02d:%02d Z",stm.tm_year+1900,
+ stm.tm_mon+1,stm.tm_mday,stm.tm_hour,stm.tm_min,stm.tm_sec);
+
+ return ictt_str;
+
+}
+
+void do_test_time(char* zone)
{
- struct icaltimetype ictt, icttutc, icttny,icttphoenix;
- time_t tt,tt2;
+ struct icaltimetype ictt, icttutc, icttutczone, icttdayl,
+ icttla, icttny,icttphoenix, icttlocal, icttnorm;
+ time_t tt,tt2, tt_p200;
+ int offset_la, offset_tz;
icalvalue *v;
short day_of_week,start_day_of_week, day_of_year;
+ icalerror_errors_are_fatal = 0;
- tt = 973276230; /* Fri Nov 3 10:30:30 PST 2000 in UTC */
+ ictt = icaltime_from_string("20001103T183030Z");
- printf("\n Convert to and from lib c \n");
+ tt = icaltime_as_timet(ictt);
+
+ assert(tt==973276230); /* Fri Nov 3 10:30:30 PST 2000 in PST
+ Fri Nov 3 18:30:30 PST 2000 in UTC */
+
+ offset_la = icaltime_utc_offset(ictt,"America/Los_Angeles");
+ offset_tz = icaltime_utc_offset(ictt, zone);
- printf("System time is: %s",ctime(&tt));
+ printf(" Normalize \n");
+ printf("Orig (ical) : %s\n", ictt_as_string(ictt));
+ icttnorm = ictt;
+ icttnorm.second -= 60 * 60 * 24 * 5;
+ icttnorm = icaltime_normalize(ictt);
+ printf("-5d in sec : %s\n", ictt_as_string(icttnorm));
+ icttnorm.day += 60;
+ icttnorm = icaltime_normalize(ictt);
+ printf("+60 d : %s\n", ictt_as_string(icttnorm));
+
+
+ printf("\n As time_t \n");
+
+ tt2 = icaltime_as_timet(ictt);
+ printf("20001103T183030Z (timet): %s\n",ical_timet_string(tt2));
+ printf("20001103T183030Z : %s\n",ictt_as_string(ictt));
+ assert(tt2 == tt);
- ictt = icaltime_from_timet(tt,0,0);
+ icttlocal = icaltime_from_string("20001103T183030");
+ tt2 = icaltime_as_timet(icttlocal);
+ printf("20001103T183030 (timet): %s\n",ical_timet_string(tt2));
+ printf("20001103T183030 : %s\n",ictt_as_string(icttlocal));
+ assert(tt-tt2 == offset_tz);
+
+ printf("\n From time_t \n");
+
+ printf("Orig : %s\n",ical_timet_string(tt));
+ printf("As utc : %s\n", ictt_as_string(ictt));
+
+ icttlocal = icaltime_as_zone(ictt,zone);
+ printf("As local : %s\n", ictt_as_string(icttlocal));
+
+
+ printf("\n Convert to and from lib c \n");
+
+ printf("System time is: %s\n",ical_timet_string(tt));
v = icalvalue_new_datetime(ictt);
printf("System time from libical: %s\n",icalvalue_as_ical_string(v));
tt2 = icaltime_as_timet(ictt);
- printf("Converted back to libc: %s",ctime(&tt2));
+ printf("Converted back to libc: %s\n",ical_timet_string(tt2));
printf("\n Incrementing time \n");
- ictt.year++;
- tt2 = icaltime_as_timet(ictt);
- printf("Add a year: %s\n",ctime(&tt2));
+ icttnorm = ictt;
- ictt.month+=13;
- tt2 = icaltime_as_timet(ictt);
- printf("Add 13 months: %s",ctime(&tt2));
+ icttnorm.year++;
+ tt2 = icaltime_as_timet(icttnorm);
+ printf("Add a year: %s\n",ical_timet_string(tt2));
- ictt.second+=90;
- tt2 = icaltime_as_timet(ictt);
- printf("Add 90 seconds: %s",ctime(&tt2));
+ icttnorm.month+=13;
+ tt2 = icaltime_as_timet(icttnorm);
+ printf("Add 13 months: %s\n",ical_timet_string(tt2));
- ictt = icaltime_from_timet(tt,0,0);
+ icttnorm.second+=90;
+ tt2 = icaltime_as_timet(icttnorm);
+ printf("Add 90 seconds: %s\n",ical_timet_string(tt2));
printf("\n Day Of week \n");
@@ -1486,34 +1535,76 @@ void test_time()
start_day_of_week = icaltime_start_doy_of_week(ictt);
day_of_year = icaltime_day_of_year(ictt);
+
printf("Today is day of week %d, day of year %d\n",day_of_week,day_of_year);
printf("Week started n doy of %d\n",start_day_of_week);
+ assert(day_of_week == 6);
+ assert(day_of_year == 308);
+ assert(start_day_of_week == 303 );
+
+ printf("\n TimeZone Conversions \n");
- printf("\n To and From UTC\n");
+ icttla = icaltime_as_zone(ictt,"America/Los_Angeles");
+ assert(icttla.hour == 10);
- ictt = icaltime_from_timet(tt,0,1);
- printf("As utc : %s\n", ictt_as_string(ictt));
- ictt = icaltime_from_timet(tt,0,0);
- printf("As local : %s\n", ictt_as_string(ictt));
-
+ icttutc = icaltime_as_utc(icttla,"America/Los_Angeles");
+ assert(icaltime_compare(icttla,
+ icaltime_from_string("20001103T103030"))==0);
+ icttutczone = icaltime_as_zone(ictt,"Etc/GMT0");
+ icttutczone.is_utc = 1;
+ assert(icaltime_compare(icttutc, icttutczone) == 0);
+ assert(icaltime_compare(icttutc, ictt) == 0);
- printf("\n TimeZone Conversions \n");
+ icttny = icaltime_as_zone(ictt,"America/New_York");
+
+ icttphoenix = icaltime_as_zone(ictt,"America/Phoenix");
- ictt = icaltime_from_timet(tt,0,1);
+ printf("Orig (ctime): %s\n", ical_timet_string(tt) );
+ printf("Orig (ical) : %s\n", ictt_as_string(ictt));
+ printf("UTC : %s\n", ictt_as_string(icttutc));
+ printf("Los Angeles : %s\n", ictt_as_string(icttla));
+ printf("Phoenix : %s\n", ictt_as_string(icttphoenix));
+ printf("New York : %s\n", ictt_as_string(icttny));
+
+
+ /* Daylight savings test for New York */
+ printf("\n Daylight Savings \n");
+
+ printf("Orig (ctime): %s\n", ical_timet_string(tt) );
+ printf("Orig (ical) : %s\n", ictt_as_string(ictt));
+ printf("NY : %s\n", ictt_as_string(icttny));
+
+ assert(strcmp(ictt_as_string(icttny),"2000-11-03 13:30:30")==0);
+
+ tt_p200 = tt + 200 * 24 * 60 * 60 ; /* Add 200 days */
+
+ icttdayl = icaltime_from_timet(tt_p200,0);
+ icttny = icaltime_as_zone(icttdayl,"America/New_York");
- icttutc = icaltime_as_utc(ictt,"America/Los_Angeles");
+ printf("Orig +200d : %s\n", ical_timet_string(tt_p200) );
+ printf("NY+200D : %s\n", ictt_as_string(icttny));
- icttny = icaltime_as_zone(icttutc,"America/New_York");
+ assert(strcmp(ictt_as_string(icttny),"2001-05-22 14:30:30")==0);
- icttphoenix = icaltime_as_zone(icttutc,"America/Phoenix");
+ /* Daylight savings test for Los Angeles */
- printf("Orig : %s", ctime(&tt) );
- printf("UTC : %s\n", ictt_as_string(icttutc));
- printf("Los Angeles: %s\n", ictt_as_string(ictt));
- printf("Phoenix : %s\n", ictt_as_string(icttphoenix));
- printf("New York : %s\n", ictt_as_string(icttny));
+ icttla = icaltime_as_zone(ictt,"America/Los_Angeles");
+ printf("\nOrig (ctime): %s\n", ical_timet_string(tt) );
+ printf("Orig (ical) : %s\n", ictt_as_string(ictt));
+ printf("LA : %s\n", ictt_as_string(icttla));
+
+ assert(strcmp(ictt_as_string(icttla),"2000-11-03 10:30:30")==0);
+
+ icttla = icaltime_as_zone(icttdayl,"America/Los_Angeles");
+
+ printf("Orig +200d : %s\n", ical_timet_string(tt_p200) );
+ printf("LA+200D : %s\n", ictt_as_string(icttla));
+
+ assert(strcmp(ictt_as_string(icttla),"2001-05-22 11:30:30")==0);
+
+ icalerror_errors_are_fatal = 1;
}
void test_iterators()
@@ -1655,6 +1746,91 @@ void test_iterators()
}
+
+char* test_set_tz(const char* tzid)
+{
+ char *tzstr = 0;
+ char *tmp;
+
+ /* Put the new time zone into the environment */
+ if(getenv("TZ") != 0){
+ tzstr = (char*)strdup(getenv("TZ"));
+
+ if(tzstr == 0){
+ icalerror_set_errno(ICAL_NEWFAILED_ERROR);
+ return 0;
+ }
+ }
+
+ tmp = (char*)malloc(1024);
+
+ if(tmp == 0){
+ icalerror_set_errno(ICAL_NEWFAILED_ERROR);
+ return 0;
+ }
+
+ snprintf(tmp,1024,"TZ=%s",tzid);
+
+ /* HACK. In some libc versions, putenv gives the string to the
+ system and in some it gives a copy, so the following might be a
+ memory leak. THe linux man page says that glibc2.1.2 take
+ ownership ( no leak) while BSD4.4 uses a copy ( A leak ) */
+ putenv(tmp);
+
+ return tzstr; /* This will be zero if the TZ env var was not set */
+}
+
+void test_unset_tz(char* tzstr)
+{
+ /* restore the original environment */
+
+ if(tzstr!=0){
+ char temp[1024];
+ snprintf(temp,1024,"TZ=%s",tzstr);
+ putenv(temp);
+ free(tzstr);
+ } else {
+ putenv("TZ"); /* Delete from environment */
+ }
+}
+
+
+void test_time()
+{
+ char zones[6][40] = { "America/Los_Angeles","America/New_York","Europe/London","Asia/Shanghai", ""};
+ int i;
+ char* old_tz;
+ int orig_month;
+ time_t tt;
+ struct tm stm;
+
+ tt = time(0);
+
+ stm = *(localtime(&tt));
+
+ orig_month = stm.tm_mon;
+
+ do_test_time(0);
+
+ old_tz = test_set_tz(zones[0]);
+
+ for(i = 0; zones[i][0] != 0; i++){
+
+ if(zones[i][0] != 0){
+ test_set_tz(zones[i]);
+ }
+
+ printf(" ######### Timezone: %s ############\n",zones[i]);
+
+ do_test_time(zones[i]);
+
+ }
+
+ test_unset_tz(old_tz);
+
+}
+
+
void test_icalset()
{
icalcomponent *c;
@@ -1698,11 +1874,15 @@ void test_classify()
void print_span(int c, struct icaltime_span span ){
- printf("#%02d start: %s",c,ctime(&span.start));
- printf(" end : %s",ctime(&span.end));
+ printf("#%02d start: %s\n",c,ical_timet_string(span.start));
+ printf(" end : %s\n",ical_timet_string(span.end));
}
+struct icaltimetype icaltime_as_local(struct icaltimetype tt) {
+ return icaltime_as_zone(tt,0);
+}
+
void test_span()
{
time_t tm1 = 973378800; /*Sat Nov 4 23:00:00 UTC 2000,
@@ -1724,9 +1904,11 @@ void test_span()
c =
icalcomponent_vanew(
ICAL_VEVENT_COMPONENT,
- icalproperty_vanew_dtstart(icaltime_from_timet(tm1,0,0),
+ icalproperty_vanew_dtstart(
+ icaltime_as_local(icaltime_from_timet(tm1,0)),
icalparameter_new_tzid("US/Pacific"),0),
- icalproperty_vanew_dtend(icaltime_from_timet(tm2,0,0),
+ icalproperty_vanew_dtend(
+ icaltime_as_local(icaltime_from_timet(tm2,0)),
icalparameter_new_tzid("US/Pacific"),0),
0
);
@@ -1737,12 +1919,14 @@ void test_span()
print_span(1,span);
+ icalcomponent_free(c);
+
/* Use machine's local timezone. Same as above if run in US/Pacific */
c =
icalcomponent_vanew(
ICAL_VEVENT_COMPONENT,
- icalproperty_vanew_dtstart(icaltime_from_timet(tm1,0,0),0),
- icalproperty_vanew_dtend(icaltime_from_timet(tm2,0,0),0),
+ icalproperty_vanew_dtstart(icaltime_from_timet(tm1,0),0),
+ icalproperty_vanew_dtend(icaltime_from_timet(tm2,0),0),
0
);
@@ -1750,38 +1934,49 @@ void test_span()
print_span(2,span);
+ icalcomponent_free(c);
+
/* Specify different timezone */
c =
icalcomponent_vanew(
ICAL_VEVENT_COMPONENT,
- icalproperty_vanew_dtstart(icaltime_from_timet(tm1,0,0),
+ icalproperty_vanew_dtstart(
+ icaltime_as_local(icaltime_from_timet(tm1,0)),
icalparameter_new_tzid("US/Eastern"),0),
- icalproperty_vanew_dtend(icaltime_from_timet(tm2,0,0),
+ icalproperty_vanew_dtend(
+ icaltime_as_local(icaltime_from_timet(tm2,0)),
icalparameter_new_tzid("US/Eastern"),0),
0
);
span = icalcomponent_get_span(c);
print_span(3,span);
+ icalcomponent_free(c);
+
+
/* Specify different timezone for start and end*/
c =
icalcomponent_vanew(
ICAL_VEVENT_COMPONENT,
- icalproperty_vanew_dtstart(icaltime_from_timet(tm1,0,0),
+ icalproperty_vanew_dtstart(
+ icaltime_as_local(icaltime_from_timet(tm1,0)),
icalparameter_new_tzid("US/Eastern"),0),
- icalproperty_vanew_dtend(icaltime_from_timet(tm2,0,0),
+ icalproperty_vanew_dtend(
+ icaltime_as_local(icaltime_from_timet(tm2,0)),
icalparameter_new_tzid("US/Pacific"),0),
0
);
span = icalcomponent_get_span(c);
print_span(4,span);
+ icalcomponent_free(c);
/* Use Duration */
c =
icalcomponent_vanew(
ICAL_VEVENT_COMPONENT,
- icalproperty_vanew_dtstart(icaltime_from_timet(tm1,0,0),
+ icalproperty_vanew_dtstart(
+ icaltime_as_local(icaltime_from_timet(tm1,0)),
icalparameter_new_tzid("US/Pacific"),0),
icalproperty_new_duration(dur),
@@ -1790,21 +1985,27 @@ void test_span()
span = icalcomponent_get_span(c);
print_span(5,span);
+ icalcomponent_free(c);
+
+
#ifndef ICAL_ERRORS_ARE_FATAL
/* Both UTC and Timezone -- an error */
icalerror_clear_errno();
c =
icalcomponent_vanew(
ICAL_VEVENT_COMPONENT,
- icalproperty_vanew_dtstart(icaltime_from_timet(tm1,0,1),
+ icalproperty_vanew_dtstart(icaltime_from_timet(tm1,0),
icalparameter_new_tzid("US/Eastern"),0),
- icalproperty_vanew_dtend(icaltime_from_timet(tm2,0,1),
+ icalproperty_vanew_dtend(icaltime_from_timet(tm2,0),
icalparameter_new_tzid("US/Eastern"),0),
0
);
span = icalcomponent_get_span(c);
assert(icalerrno != ICAL_NO_ERROR);
+
+ icalcomponent_free(c);
+
#endif /*ICAL_ERRORS_ARE_FATAL*/
}
@@ -1813,6 +2014,8 @@ icalcomponent* icalclassify_find_overlaps(icalset* set, icalcomponent* comp);
void test_overlaps()
{
+
+#if 0 /* Hack, not working right now */
icalcomponent *cset,*c;
icalset *set;
time_t tm1 = 973378800; /*Sat Nov 4 23:00:00 UTC 2000,
@@ -1827,8 +2030,8 @@ void test_overlaps()
printf("-- 1 -- \n");
c = icalcomponent_vanew(
ICAL_VEVENT_COMPONENT,
- icalproperty_vanew_dtstart(icaltime_from_timet(tm1-hh,0,1),0),
- icalproperty_vanew_dtend(icaltime_from_timet(tm2-hh,0,1),0),
+ icalproperty_vanew_dtstart(icaltime_from_timet(tm1-hh,0),0),
+ icalproperty_vanew_dtend(icaltime_from_timet(tm2-hh,0),0),
0
);
@@ -1839,8 +2042,8 @@ void test_overlaps()
printf("-- 2 -- \n");
c = icalcomponent_vanew(
ICAL_VEVENT_COMPONENT,
- icalproperty_vanew_dtstart(icaltime_from_timet(tm1-hh,0,1),0),
- icalproperty_vanew_dtend(icaltime_from_timet(tm2,0,1),0),
+ icalproperty_vanew_dtstart(icaltime_from_timet(tm1-hh,0),0),
+ icalproperty_vanew_dtend(icaltime_from_timet(tm2,0),0),
0
);
@@ -1851,8 +2054,8 @@ void test_overlaps()
printf("-- 3 -- \n");
c = icalcomponent_vanew(
ICAL_VEVENT_COMPONENT,
- icalproperty_vanew_dtstart(icaltime_from_timet(tm1+5*hh,0,1),0),
- icalproperty_vanew_dtend(icaltime_from_timet(tm2+5*hh,0,1),0),
+ icalproperty_vanew_dtstart(icaltime_from_timet(tm1+5*hh,0),0),
+ icalproperty_vanew_dtend(icaltime_from_timet(tm2+5*hh,0),0),
0
);
@@ -1860,6 +2063,8 @@ void test_overlaps()
printf("%s\n",icalcomponent_as_ical_string(cset));
+#endif
+
}
void test_fblist()
@@ -1869,14 +2074,14 @@ void test_fblist()
struct icalperiodtype period;
sl = icalspanlist_new(set,
- icaltime_from_string("19970324T1200Z"),
+ icaltime_from_string("19970324T120000Z"),
icaltime_from_string("19990424T020000Z"));
printf("Restricted spanlist\n");
icalspanlist_dump(sl);
period= icalspanlist_next_free_time(sl,
- icaltime_from_string("19970801T1200Z"));
+ icaltime_from_string("19970801T120000Z"));
printf("Next Free time: %s\n",icaltime_as_ctime(period.start));
@@ -1888,7 +2093,7 @@ void test_fblist()
printf("Unrestricted spanlist\n");
sl = icalspanlist_new(set,
- icaltime_from_string("19970324T1200Z"),
+ icaltime_from_string("19970324T120000Z"),
icaltime_null_time());
printf("Restricted spanlist\n");
@@ -1896,7 +2101,7 @@ void test_fblist()
icalspanlist_dump(sl);
period= icalspanlist_next_free_time(sl,
- icaltime_from_string("19970801T1200Z"));
+ icaltime_from_string("19970801T120000Z"));
printf("Next Free time: %s\n",icaltime_as_ctime(period.start));
@@ -1917,8 +2122,8 @@ void test_convenience(){
ICAL_VCALENDAR_COMPONENT,
icalcomponent_vanew(
ICAL_VEVENT_COMPONENT,
- icalproperty_new_dtstart(icaltime_from_string("19970801T1200")),
- icalproperty_new_dtend(icaltime_from_string("19970801T1300")),
+ icalproperty_new_dtstart(icaltime_from_string("19970801T120000")),
+ icalproperty_new_dtend(icaltime_from_string("19970801T130000")),
0
),
0);
@@ -1926,7 +2131,7 @@ void test_convenience(){
printf("** 1 DTSTART and DTEND **\n%s\n\n",
icalcomponent_as_ical_string(c));
- duration = icaldurationtype_as_timet(icalcomponent_get_duration(c))/60;
+ duration = icaldurationtype_as_int(icalcomponent_get_duration(c))/60;
printf("Start: %s\n",ictt_as_string(icalcomponent_get_dtstart(c)));
printf("End: %s\n",ictt_as_string(icalcomponent_get_dtend(c)));
@@ -1938,7 +2143,7 @@ void test_convenience(){
ICAL_VCALENDAR_COMPONENT,
icalcomponent_vanew(
ICAL_VEVENT_COMPONENT,
- icalproperty_new_dtstart(icaltime_from_string("19970801T1200Z")),
+ icalproperty_new_dtstart(icaltime_from_string("19970801T120000Z")),
icalproperty_new_duration(icaldurationtype_from_string("PT1H30M")),
0
),
@@ -1947,7 +2152,7 @@ void test_convenience(){
printf("\n** 2 DTSTART and DURATION **\n%s\n\n",
icalcomponent_as_ical_string(c));
- duration = icaldurationtype_as_timet(icalcomponent_get_duration(c))/60;
+ duration = icaldurationtype_as_int(icalcomponent_get_duration(c))/60;
printf("Start: %s\n",ictt_as_string(icalcomponent_get_dtstart(c)));
printf("End: %s\n",ictt_as_string(icalcomponent_get_dtend(c)));
@@ -1959,8 +2164,8 @@ void test_convenience(){
ICAL_VCALENDAR_COMPONENT,
icalcomponent_vanew(
ICAL_VEVENT_COMPONENT,
- icalproperty_new_dtstart(icaltime_from_string("19970801T1200")),
- icalproperty_new_dtend(icaltime_from_string("19970801T1300")),
+ icalproperty_new_dtstart(icaltime_from_string("19970801T120000")),
+ icalproperty_new_dtend(icaltime_from_string("19970801T130000")),
0
),
0);
@@ -1970,7 +2175,7 @@ void test_convenience(){
printf("** 3 DTSTART and DTEND, Set DURATION **\n%s\n\n",
icalcomponent_as_ical_string(c));
- duration = icaldurationtype_as_timet(icalcomponent_get_duration(c))/60;
+ duration = icaldurationtype_as_int(icalcomponent_get_duration(c))/60;
printf("Start: %s\n",ictt_as_string(icalcomponent_get_dtstart(c)));
printf("End: %s\n",ictt_as_string(icalcomponent_get_dtend(c)));
@@ -1982,18 +2187,18 @@ void test_convenience(){
ICAL_VCALENDAR_COMPONENT,
icalcomponent_vanew(
ICAL_VEVENT_COMPONENT,
- icalproperty_new_dtstart(icaltime_from_string("19970801T1200Z")),
+ icalproperty_new_dtstart(icaltime_from_string("19970801T120000Z")),
icalproperty_new_duration(icaldurationtype_from_string("PT1H30M")),
0
),
0);
- icalcomponent_set_dtend(c,icaltime_from_string("19970801T1330Z"));
+ icalcomponent_set_dtend(c,icaltime_from_string("19970801T133000Z"));
printf("\n** 4 DTSTART and DURATION, set DTEND **\n%s\n\n",
icalcomponent_as_ical_string(c));
- duration = icaldurationtype_as_timet(icalcomponent_get_duration(c))/60;
+ duration = icaldurationtype_as_int(icalcomponent_get_duration(c))/60;
printf("Start: %s\n",ictt_as_string(icalcomponent_get_dtstart(c)));
printf("End: %s\n",ictt_as_string(icalcomponent_get_dtend(c)));
@@ -2009,14 +2214,14 @@ void test_convenience(){
),
0);
- icalcomponent_set_dtstart(c,icaltime_from_string("19970801T1200Z"));
- icalcomponent_set_dtend(c,icaltime_from_string("19970801T1330Z"));
+ icalcomponent_set_dtstart(c,icaltime_from_string("19970801T120000Z"));
+ icalcomponent_set_dtend(c,icaltime_from_string("19970801T133000Z"));
printf("\n** 5 Set DTSTART and DTEND **\n%s\n\n",
icalcomponent_as_ical_string(c));
- duration = icaldurationtype_as_timet(icalcomponent_get_duration(c))/60;
+ duration = icaldurationtype_as_int(icalcomponent_get_duration(c))/60;
printf("Start: %s\n",ictt_as_string(icalcomponent_get_dtstart(c)));
printf("End: %s\n",ictt_as_string(icalcomponent_get_dtend(c)));
@@ -2033,14 +2238,14 @@ void test_convenience(){
0);
- icalcomponent_set_dtstart(c,icaltime_from_string("19970801T1200Z"));
+ icalcomponent_set_dtstart(c,icaltime_from_string("19970801T120000Z"));
icalcomponent_set_duration(c,icaldurationtype_from_string("PT1H30M"));
printf("\n** 6 Set DTSTART and DURATION **\n%s\n\n",
icalcomponent_as_ical_string(c));
- duration = icaldurationtype_as_timet(icalcomponent_get_duration(c))/60;
+ duration = icaldurationtype_as_int(icalcomponent_get_duration(c))/60;
printf("Start: %s\n",ictt_as_string(icalcomponent_get_dtstart(c)));
printf("End: %s\n",ictt_as_string(icalcomponent_get_dtend(c)));
@@ -2050,92 +2255,824 @@ void test_convenience(){
}
-int main(int argc, char *argv[])
+void test_time_parser()
{
+ struct icaltimetype tt;
- printf("\n------------Test recur bug ----------\n");
- test_recur_bug();
+ icalerror_errors_are_fatal = 0;
- exit(0);
+ tt = icaltime_from_string("19970101T1000");
+ assert(icaltime_is_null_time(tt));
- printf("\n------------Test recur---------------\n");
- test_recur();
+ tt = icaltime_from_string("19970101X100000");
+ assert(icaltime_is_null_time(tt));
- printf("\n------------Test FBlist------------\n");
- test_fblist();
+ tt = icaltime_from_string("19970101T100000");
+ assert(!icaltime_is_null_time(tt));
+ printf("%s\n",icaltime_as_ctime(tt));
- printf("\n------------Test time----------------\n");
- test_time();
+ tt = icaltime_from_string("19970101T100000Z");
+ assert(!icaltime_is_null_time(tt));
+ printf("%s\n",icaltime_as_ctime(tt));
+ tt = icaltime_from_string("19970101");
+ assert(!icaltime_is_null_time(tt));
+ printf("%s\n",icaltime_as_ctime(tt));
- printf("\n------------Test Overlaps------------\n");
- test_overlaps();
+ icalerror_errors_are_fatal = 1;
+}
+
+void test_recur_parser()
+{
+ struct icalrecurrencetype rt;
- printf("\n------------Test Span----------------\n");
- test_span();
+ printf("FREQ=YEARLY;UNTIL=20000131T090000Z;BYMONTH=1,2,3,4,8;BYYEARDAY=34,65,76,78;BYDAY=-1TU,3WE,-4FR,SU,SA\n");
+ rt = icalrecurrencetype_from_string("FREQ=YEARLY;UNTIL=20000131T090000Z;BYMONTH=1,2,3,4,8;BYYEARDAY=34,65,76,78;BYDAY=-1TU,3WE,-4FR,SU,SA");
- printf("\n------------Test duration---------------\n");
- test_duration();
+ printf("%s\n\n",icalrecurrencetype_as_string(&rt));
- exit(0);
+ printf("FREQ=DAILY;COUNT=3;BYMONTH=1,2,3,4,8;BYYEARDAY=34,65,76,78;BYDAY=-1TU,3WE,-4FR,SU,S\n");
+
+ rt = icalrecurrencetype_from_string("FREQ=DAILY;COUNT=3;BYMONTH=1,2,3,4,8;BYYEARDAY=34,65,76,78;BYDAY=-1TU,3WE,-4FR,SU,SA");
+
+ printf("%s\n",icalrecurrencetype_as_string(&rt));
+
+}
+
+void test_doy()
+{
+ struct icaltimetype tt1, tt2;
+ short doy;
+
+ tt1 = icaltime_from_string("19950301");
+ doy = icaltime_day_of_year(tt1);
+ tt2 = icaltime_from_day_of_year(doy,1995);
+ printf("%d %s %s\n",doy, icaltime_as_ctime(tt1),icaltime_as_ctime(tt2));
+
+ tt1 = icaltime_from_string("19960301");
+ doy = icaltime_day_of_year(tt1);
+ tt2 = icaltime_from_day_of_year(doy,1996);
+ printf("%d %s %s\n",doy, icaltime_as_ctime(tt1),icaltime_as_ctime(tt2));
+
+ tt1 = icaltime_from_string("19970301");
+ doy = icaltime_day_of_year(tt1);
+ tt2 = icaltime_from_day_of_year(doy,1997);
+ printf("%d %s %s\n",doy, icaltime_as_ctime(tt1),icaltime_as_ctime(tt2));
+
+
+}
+
+void test_x(){
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ical.h>
+ static const char test_icalcomp_str[] =
+"BEGIN:VEVENT\r\n"
+"RRULE\r\n"
+" ;X-EVOLUTION-ENDDATE=20030209T081500\r\n"
+" :FREQ=DAILY;COUNT=10;INTERVAL=6\r\n"
+"X-COMMENT;X-FOO=BAR: Booga\r\n"
+"END:VEVENT\r\n";
+
+ icalcomponent *icalcomp;
+ icalproperty *prop;
+ struct icalrecurrencetype recur;
+ int n_errors;
+
+ icalcomp = icalparser_parse_string ((char *) test_icalcomp_str);
+ if (!icalcomp) {
+ fprintf (stderr, "main(): could not parse the component\n");
+ exit (EXIT_FAILURE);
+ }
+
+ printf("%s\n\n",icalcomponent_as_ical_string(icalcomp));
+
+ n_errors = icalcomponent_count_errors (icalcomp);
+ if (n_errors) {
+ icalproperty *p;
+
+ for (p = icalcomponent_get_first_property (icalcomp,
+ ICAL_XLICERROR_PROPERTY);
+ p;
+ p = icalcomponent_get_next_property (icalcomp,
+ ICAL_XLICERROR_PROPERTY)) {
+ char *str;
+
+ str = icalproperty_as_ical_string (p);
+ fprintf (stderr, "error: %s\n", str);
+ }
+ }
+
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY);
+ if (!prop) {
+ fprintf (stderr, "main(): could not get the RRULE property");
+ exit (EXIT_FAILURE);
+ }
+
+ recur = icalproperty_get_rrule (prop);
+
+ printf("%s\n",icalrecurrencetype_as_string(&recur));
+
+}
+
+void test_gauge_sql() {
+
+
+ icalgauge *g;
+
+ printf("\nSELECT DTSTART,DTEND,COMMENT FROM VEVENT,VTODO WHERE VEVENT.SUMMARY = 'Bongoa' AND SEQUENCE < 5\n");
+
+ g = icalgauge_new_from_sql("SELECT DTSTART,DTEND,COMMENT FROM VEVENT,VTODO WHERE VEVENT.SUMMARY = 'Bongoa' AND SEQUENCE < 5");
+
+ icalgauge_dump(g);
+
+ icalgauge_free(g);
+
+ printf("\nSELECT * FROM VEVENT,VTODO WHERE VEVENT.SUMMARY = 'Bongoa' AND SEQUENCE < 5 OR METHOD != 'CREATE'\n");
+
+ g = icalgauge_new_from_sql("SELECT * FROM VEVENT,VTODO WHERE VEVENT.SUMMARY = 'Bongoa' AND SEQUENCE < 5 OR METHOD != 'CREATE'");
+
+ icalgauge_dump(g);
+
+ icalgauge_free(g);
+
+}
+
+void test_gauge_compare() {
+
+ icalgauge *g;
+ icalcomponent *c;
+
+ /* Equality */
+
+ c = icalcomponent_vanew(ICAL_VCALENDAR_COMPONENT,
+ icalcomponent_vanew(ICAL_VEVENT_COMPONENT,
+ icalproperty_new_dtstart(
+ icaltime_from_string("20000101T000002")),0),0);
+
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART = '20000101T000002'");
+
+ printf("SELECT * FROM VEVENT WHERE DTSTART = '20000101T000002'\n");
+ assert(c!=0);
+ assert(g!=0);
+
+ assert(icalgauge_compare(g,c) == 1);
+
+ icalgauge_free(g);
+
+
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART = '20000101T000001'");
+
+ printf("SELECT * FROM VEVENT WHERE DTSTART = '20000101T000001'\n");
- printf("\n------------Test Convenience ------------\n");
- test_convenience();
+ assert(g!=0);
+ assert(icalgauge_compare(g,c) == 0);
+
+ icalgauge_free(g);
+
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART != '20000101T000003'");
+
+ printf("SELECT * FROM VEVENT WHERE DTSTART != '20000101T000003'\n");
+
+
+ assert(g!=0);
+ assert(icalgauge_compare(g,c) == 1);
+
+ icalgauge_free(g);
+
+
+ /* Less than */
+
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART < '20000101T000003'");
+
+ printf("SELECT * FROM VEVENT WHERE DTSTART < '20000101T000003'\n");
+
+ assert(icalgauge_compare(g,c) == 1);
+
+ assert(g!=0);
+ icalgauge_free(g);
+
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART < '20000101T000002'");
+
+ printf("SELECT * FROM VEVENT WHERE DTSTART < '20000101T000002'\n");
+
+
+ assert(g!=0);
+ assert(icalgauge_compare(g,c) == 0);
+
+ icalgauge_free(g);
+
+ /* Greater than */
+
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART > '20000101T000001'");
+
+ printf("SELECT * FROM VEVENT WHERE DTSTART > '20000101T000001'\n");
+
+
+ assert(g!=0);
+ assert(icalgauge_compare(g,c) == 1);
+
+ icalgauge_free(g);
+
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART > '20000101T000002'");
+
+ printf("SELECT * FROM VEVENT WHERE DTSTART > '20000101T000002'\n");
+
+
+ assert(g!=0);
+ assert(icalgauge_compare(g,c) == 0);
+
+ icalgauge_free(g);
+
+
+ /* Greater than or Equal to */
+
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART >= '20000101T000002'");
+
+ printf("SELECT * FROM VEVENT WHERE DTSTART >= '20000101T000002'\n");
+
+
+ assert(g!=0);
+ assert(icalgauge_compare(g,c) == 1);
+
+ icalgauge_free(g);
+
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART >= '20000101T000003'");
+
+ printf("SELECT * FROM VEVENT WHERE DTSTART >= '20000101T000003'\n");
+
+
+ assert(g!=0);
+ assert(icalgauge_compare(g,c) == 0);
+
+ icalgauge_free(g);
+
+ /* Less than or Equal to */
+
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART <= '20000101T000002'");
+
+ printf("SELECT * FROM VEVENT WHERE DTSTART <= '20000101T000002'\n");
+
+
+ assert(g!=0);
+ assert(icalgauge_compare(g,c) == 1);
+
+ icalgauge_free(g);
+
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART <= '20000101T000001'");
+
+ printf("SELECT * FROM VEVENT WHERE DTSTART <= '20000101T000001'\n");
+
+
+ assert(g!=0);
+ assert(icalgauge_compare(g,c) == 0);
+
+ icalgauge_free(g);
+
+ icalcomponent_free(c);
+
+
+ /* Complex comparisions */
+
+ c = icalcomponent_vanew(
+ ICAL_VCALENDAR_COMPONENT,
+ icalproperty_new_method(ICAL_METHOD_REQUEST),
+ icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_new_dtstart(
+ icaltime_from_string("20000101T000002")),
+ icalproperty_new_comment("foo"),
+ icalcomponent_vanew(
+ ICAL_VALARM_COMPONENT,
+ icalproperty_new_dtstart(
+ icaltime_from_string("20000101T120000")),
+
+ 0),
+ 0),
+ 0);
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE VALARM.DTSTART = '20000101T120000'");
+
+ printf("SELECT * FROM VEVENT WHERE VALARM.DTSTART = '20000101T120000'\n");
+
+ assert(icalgauge_compare(g,c) == 1);
+
+ icalgauge_free(g);
- printf("\n------------Test classify ---------------\n");
- test_classify();
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE COMMENT = 'foo'");
- printf("\n------------Test Memory---------------\n");
- test_memory();
+ printf("SELECT * FROM VEVENT WHERE COMMENT = 'foo'\n");
+ assert(icalgauge_compare(g,c) == 1);
- printf("\n------------Test Iterators-----------\n");
- test_iterators();
+ icalgauge_free(g);
- printf("\n------------Test Restriction---------------\n");
- test_restriction();
- printf("\n------------Test request status-------\n");
- test_requeststat();
+ g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE COMMENT = 'foo' AND VALARM.DTSTART = '20000101T120000'");
- printf("\n------------Test strings---------------\n");
- test_strings();
+ printf("SELECT * FROM VEVENT WHERE COMMENT = 'foo' AND VALARM.DTSTART = '20000101T120000'\n");
- printf("\n------------Test Compare---------------\n");
- test_compare();
+ assert(icalgauge_compare(g,c) == 1);
- printf("\n------------Test Values---------------\n");
- test_values();
+ icalgauge_free(g);
+
+ icalcomponent_free(c);
- printf("\n------------Test Parameters-----------\n");
- test_parameters();
+}
- printf("\n------------Test Properties-----------\n");
- test_properties();
+icalcomponent* make_component(int i){
+
+ icalcomponent *c;
- printf("\n------------Test Components ----------\n");
- test_components();
+ struct icaltimetype t = icaltime_from_string("20000101T120000Z");
- printf("\n------------Create Components --------\n");
- create_new_component();
+ t.day += i;
- printf("\n----- Create Components with vaargs ---\n");
- create_new_component_with_va_args();
+ icaltime_normalize(t);
+ c = icalcomponent_vanew(
+ ICAL_VCALENDAR_COMPONENT,
+ icalproperty_new_method(ICAL_METHOD_REQUEST),
+ icalcomponent_vanew(
+ ICAL_VEVENT_COMPONENT,
+ icalproperty_new_dtstart(t),
+ 0),
+ 0);
+
+ assert(c != 0);
+
+ return c;
+
+}
+void test_fileset()
+{
+ icalfileset *fs;
+ icalcomponent *c;
+ int i;
+ char *path = "test_fileset.ics";
+ icalgauge *g = icalgauge_new_from_sql(
+ "SELECT * FROM VEVENT WHERE DTSTART > '20000103T120000Z' AND DTSTART <= '20000106T120000Z'");
+
+
+ unlink(path);
+
+ fs = icalfileset_new(path);
- return 0;
+ assert(fs != 0);
+
+ for (i = 0; i!= 10; i++){
+ c = make_component(i);
+ icalfileset_add_component(fs,c);
+ }
+
+ icalfileset_commit(fs);
+
+ icalfileset_free(fs);
+ fs = icalfileset_new(path);
+
+
+ printf("== No Selections \n");
+
+ for (c = icalfileset_get_first_component(fs);
+ c != 0;
+ c = icalfileset_get_next_component(fs)){
+ struct icaltimetype t = icalcomponent_get_dtstart(c);
+
+ printf("%s\n",icaltime_as_ctime(t));
+ }
+
+ icalfileset_select(fs,g);
+
+ printf("\n== DTSTART > '20000103T120000Z' AND DTSTART <= '20000106T120000Z' \n");
+
+ for (c = icalfileset_get_first_component(fs);
+ c != 0;
+ c = icalfileset_get_next_component(fs)){
+ struct icaltimetype t = icalcomponent_get_dtstart(c);
- printf("\n------------Test icalset ---------------\n");
- test_icalset();
+ printf("%s\n",icaltime_as_ctime(t));
+ }
+
+ icalfileset_free(fs);
+}
+
+void microsleep(int us)
+{
+ struct timeval tv;
+
+ tv.tv_sec = 0;
+ tv.tv_usec = us;
+
+ select(0,0,0,0,&tv);
+
+}
+
+
+void test_file_locks()
+{
+ pid_t pid;
+ char *path = "test_fileset_locktest.ics";
+ icalfileset *fs;
+ icalcomponent *c, *c2;
+ struct icaldurationtype d;
+ int i;
+ int final,sec;
+
+ icalfileset_safe_saves = 1;
+
+ icalerror_clear_errno();
+
+ unlink(path);
+
+ fs = icalfileset_new(path);
+
+ if(icalfileset_get_first_component(fs)==0){
+ c = make_component(0);
+
+ d = icaldurationtype_from_int(1);
+
+ icalcomponent_set_duration(c,d);
+
+ icalfileset_add_component(fs,c);
+
+ c2 = icalcomponent_new_clone(c);
+
+ icalfileset_add_component(fs,c2);
+
+ icalfileset_commit(fs);
+ }
+
+ icalfileset_free(fs);
+
+ assert(icalerrno == ICAL_NO_ERROR);
+
+ pid = fork();
+
+ assert(pid >= 0);
+
+ if(pid == 0){
+ /*child*/
+ int i;
+
+ microsleep(rand()/(RAND_MAX/100));
+
+ for(i = 0; i< 50; i++){
+ fs = icalfileset_new(path);
+ assert(fs != 0);
+
+ c = icalfileset_get_first_component(fs);
+
+ assert(c!=0);
+
+ d = icalcomponent_get_duration(c);
+ d = icaldurationtype_from_int(icaldurationtype_as_int(d)+1);
+
+ icalcomponent_set_duration(c,d);
+ icalcomponent_set_summary(c,"Child");
+
+ c2 = icalcomponent_new_clone(c);
+ icalcomponent_set_summary(c2,"Child");
+ icalfileset_add_component(fs,c2);
+
+ icalfileset_mark(fs);
+ icalfileset_commit(fs);
+
+ icalfileset_free(fs);
+
+ microsleep(rand()/(RAND_MAX/20));
+
+
+ }
+
+ exit(0);
+
+ } else {
+ /* parent */
+ int i;
+
+ for(i = 0; i< 50; i++){
+ fs = icalfileset_new(path);
+
+ assert(fs != 0);
+
+ c = icalfileset_get_first_component(fs);
+
+ assert(c!=0);
+
+ d = icalcomponent_get_duration(c);
+ d = icaldurationtype_from_int(icaldurationtype_as_int(d)+1);
+
+ icalcomponent_set_duration(c,d);
+ icalcomponent_set_summary(c,"Parent");
+
+ c2 = icalcomponent_new_clone(c);
+ icalcomponent_set_summary(c2,"Parent");
+ icalfileset_add_component(fs,c2);
+
+ icalfileset_mark(fs);
+ icalfileset_commit(fs);
+ icalfileset_free(fs);
+
+ putc('.',stdout);
+ fflush(stdout);
+
+ }
+ }
+
+ assert(waitpid(pid,0,0)==pid);
+
+
+ fs = icalfileset_new(path);
+
+ i=1;
+
+ c = icalfileset_get_first_component(fs);
+ final = icaldurationtype_as_int(icalcomponent_get_duration(c));
+ for (c = icalfileset_get_next_component(fs);
+ c != 0;
+ c = icalfileset_get_next_component(fs)){
+ struct icaldurationtype d = icalcomponent_get_duration(c);
+ sec = icaldurationtype_as_int(d);
+
+ /*printf("%d,%d ",i,sec);*/
+ assert(i == sec);
+ i++;
+ }
+
+ printf("\nFinal: %d\n",final);
+
+
+ assert(sec == final);
+}
+
+
+void test_trigger()
+{
+
+ static const char test_icalcomp_str[] =
+"BEGIN:VEVENT\n"
+"TRIGGER;VALUE=DATE-TIME:19980403T120000\n"
+"TRIGGER:-PT15M\n"
+"TRIGGER:19980403T120000\n"
+"END:VEVENT\r\n";
+
+ icalcomponent *c;
+ icalproperty *p;
+ struct icaltriggertype tr;
+
+
+ c = icalparser_parse_string ((char *) test_icalcomp_str);
+ if (!c) {
+ fprintf (stderr, "main(): could not parse the component\n");
+ exit (EXIT_FAILURE);
+ }
+
+ printf("%s\n\n",icalcomponent_as_ical_string(c));
+
+ for(p = icalcomponent_get_first_property(c,ICAL_TRIGGER_PROPERTY);
+ p != 0;
+ p = icalcomponent_get_next_property(c,ICAL_TRIGGER_PROPERTY)){
+ tr = icalproperty_get_trigger(p);
+
+ if(!icaltime_is_null_time(tr.time)){
+ printf("value=DATE-TIME:%s\n", icaltime_as_ical_string(tr.time));
+ } else {
+ printf("value=DURATION:%s\n", icaldurationtype_as_ical_string(tr.duration));
+ }
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ int c;
+ extern char *optarg;
+ extern int optind, optopt;
+ int errflg=0;
+ char* program_name = strrchr(argv[0],'/');
+ int ttime=0, trecur=0,tspan=0, tmisc=0, tgauge = 0, tfile = 0;
+
+ if(argc==1) {
+ ttime = trecur = tspan = tmisc = tgauge = tfile = 1;
+ }
+
+ while ((c = getopt(argc, argv, "t:s:r:m:g:f:")) != -1) {
+ switch (c) {
+
+ case 't': {
+ ttime = atoi(optarg);
+ break;
+ }
+
+ case 's': {
+ tspan = atoi(optarg);
+ break;
+ }
+
+ case 'r': {
+ trecur = atoi(optarg);
+ break;
+ }
+
+
+ case 'm': {
+ tmisc = atoi(optarg);
+ break;
+ }
+
+
+ case 'g': {
+ tgauge = atoi(optarg);
+ break;
+ }
+
+ case 'f': {
+ tfile = atoi(optarg);
+ break;
+ }
+
+ case ':': {/* Option given without an operand */
+ fprintf(stderr,
+ "%s: Option -%c requires an operand\n",
+ program_name,optopt);
+ errflg++;
+ break;
+ }
+ case '?': {
+ errflg++;
+ }
+
+ }
+
+ }
+
+
+ if(ttime==1 || ttime==2){
+ printf("\n------------Test time parser ----------\n");
+ test_time_parser();
+
+ }
+
+ if(ttime==1 || ttime==3){
+ printf("\n------------Test time----------------\n");
+ test_time();
+ }
+
+ if(ttime==1 || ttime==4){
+ printf("\n------------Test day of year---------\n");
+ test_doy();
+ }
+
+ if(ttime==1 || ttime==5){
+ printf("\n------------Test duration---------------\n");
+ test_duration();
+ }
+
+ if(ttime==1 || ttime==6){
+ printf("\n------------Test period ----------------\n");
+ test_period();
+ }
+
+
+
+ if(trecur==1 || trecur==2){
+ printf("\n------------Test recur parser ----------\n");
+ test_recur_parser();
+ }
+
+ if(trecur==1 || trecur==3){
+ printf("\n------------Test recur---------------\n");
+ test_recur();
+ }
+
+ if(trecur==1 || trecur==4){
+ printf("\n------------Test parameter bug---------\n");
+ test_recur_parameter_bug();
+ }
+
+
+ if(tspan==1 || tspan==2){
+ printf("\n------------Test FBlist------------\n");
+ test_fblist();
+ }
+
+ if(tspan==1 || tspan==3){
+ printf("\n------------Test Overlaps------------\n");
+ test_overlaps();
+ }
+
+ if(tspan==1 || tspan==4){
+ printf("\n------------Test Span----------------\n");
+ test_span();
+ }
+
+ if(tgauge == 1 || tgauge == 2){
+ printf("\n------------Test Gauge SQL----------------\n");
+ test_gauge_sql();
+ }
+
+ if(tgauge == 1 || tgauge == 3){
+ printf("\n------------Test Gauge Compare--------------\n");
+ test_gauge_compare();
+ }
+
+ if(tfile ==1 || tfile == 2){
+ printf("\n------------Test File Set--------------\n");
+ test_fileset();
+ }
+
+ if(tfile ==1 || tfile == 3){
+ printf("\n------------Test File Locks--------------\n");
+ test_file_locks();
+ }
+
+
+
+ if(tmisc == 1 || tmisc == 2){
+ printf("\n------------Test X Props and Params--------\n");
+ test_x();
+ }
+
+ if(tmisc == 1 || tmisc == 3){
+ printf("\n------------Test Trigger ------------------\n");
+ test_trigger();
+ }
+
+
+ if(tmisc == 1){
+
+ printf("\n------------Test Convenience ------------\n");
+ test_convenience();
+
+
+ printf("\n------------Test classify ---------------\n");
+ test_classify();
+
+
+ printf("\n------------Test Iterators-----------\n");
+ test_iterators();
+
+ printf("\n------------Test Restriction---------------\n");
+ test_restriction();
+
+ printf("\n-----------Test request status-------\n");
+ test_requeststat();
+
+ printf("\n------------Test strings---------------\n");
+ test_strings();
+
+ printf("\n------------Test Compare---------------\n");
+ test_compare();
+
+ printf("\n------------Test Values---------------\n");
+ test_values();
+
+ printf("\n------------Test Parameters-----------\n");
+ test_parameters();
+
+ printf("\n------------Test Properties-----------\n");
+ test_properties();
+
+ printf("\n------------Test Components ----------\n");
+ test_components();
+
+ printf("\n------------Create Components --------\n");
+ create_new_component();
+
+ printf("\n----- Create Components with vaargs ---\n");
+ create_new_component_with_va_args();
+
+ printf("\n------------Test Memory---------------\n");
+ test_memory();
+ }
+
+ return 0;
}
diff --git a/libical/src/test/storage.c b/libical/src/test/storage.c
index 8251babefe..2d8bc586f4 100644
--- a/libical/src/test/storage.c
+++ b/libical/src/test/storage.c
@@ -113,7 +113,7 @@ void test_fileset()
struct icaltimetype start, end;
icalcomponent *c,*clone, *itr;
- start = icaltime_from_timet( time(0),0,0);
+ start = icaltime_from_timet( time(0),0);
end = start;
end.hour++;
@@ -244,7 +244,7 @@ int test_dirset()
assert(s != 0);
- rtime.start = icaltime_from_timet( time(0),0,0);
+ rtime.start = icaltime_from_timet( time(0),0);
cluster = icalfileset_new(OUTPUT_FILE);
diff --git a/libical/src/test/stow.c b/libical/src/test/stow.c
index a305d161fe..2570e3ad0c 100644
--- a/libical/src/test/stow.c
+++ b/libical/src/test/stow.c
@@ -745,7 +745,6 @@ icalcomponent* read_nonmime_component(struct options_struct *opt)
comp = icalparser_add_line(parser,line);
if (comp != 0){
- icalparser_claim(parser);
return comp;
}