diff options
author | Seth Alves <alves@src.gnome.org> | 2000-04-19 02:17:07 +0800 |
---|---|---|
committer | Seth Alves <alves@src.gnome.org> | 2000-04-19 02:17:07 +0800 |
commit | 25e1b34aafe43ba6cf1040340a38dd38a90aad33 (patch) | |
tree | 0b4e666e45bf457edcc0095634f0ae6f429b8b5a /libical/src | |
parent | bc17057ec598cd5f755fd66244c429ecc51cff01 (diff) | |
download | gsoc2013-evolution-25e1b34aafe43ba6cf1040340a38dd38a90aad33.tar.gz gsoc2013-evolution-25e1b34aafe43ba6cf1040340a38dd38a90aad33.tar.zst gsoc2013-evolution-25e1b34aafe43ba6cf1040340a38dd38a90aad33.zip |
import of libical-0.16
svn path=/trunk/; revision=2484
Diffstat (limited to 'libical/src')
36 files changed, 3272 insertions, 1197 deletions
diff --git a/libical/src/Makefile.am b/libical/src/Makefile.am index ef64080346..37dc5e39cb 100644 --- a/libical/src/Makefile.am +++ b/libical/src/Makefile.am @@ -1 +1 @@ -SUBDIRS = libical libicalss +SUBDIRS = libical libicalss test diff --git a/libical/src/libical/.cvsignore b/libical/src/libical/.cvsignore index 9dc64874d6..3bd9f3bca3 100644 --- a/libical/src/libical/.cvsignore +++ b/libical/src/libical/.cvsignore @@ -3,6 +3,9 @@ Makefile.in icalitipy.c icalitipy.h icalitipl.c +icallexer.c +icalyacc.c +icalyacc.h *.lo *.la .libs diff --git a/libical/src/libical/Makefile.am b/libical/src/libical/Makefile.am index 4e74c8c207..54c66b58ec 100644 --- a/libical/src/libical/Makefile.am +++ b/libical/src/libical/Makefile.am @@ -1,39 +1,85 @@ -lib_LTLIBRARIES = libical.la - -CFLAGS=-g - -libical_la_SOURCES = \ - ical.h \ - icalcomponent.c \ - icalcomponent.h \ - icalenums.c \ - icalenums.h \ - icalerror.c \ - icalerror.h \ - icalirip.h \ - icalitipy.y \ - icalitipl.l \ - icalmemory.c \ - icalmemory.h \ - icalparameter.c \ - icalparameter.h \ - icalparser.c \ - icalparser.h \ - icalproperty.c \ - icalproperty.h \ - icalrestriction.c \ - icalrestriction.h \ - icaltypes.c \ - icaltypes.h \ - icalvalue.c \ - icalvalue.h \ - icalvcal.h \ - locking.c \ - pvl.c \ +#AUTOMAKE_OPTIONS = no-dependencies + +#noinst_LTLIBRARIES = libical.la +lib_LIBRARIES = libical.a + +YFLAGS =-d -v -t + +libical_a_SOURCES = \ + ical.h \ + icalcomponent.c \ + icalcomponent.h \ + icalenums.c \ + icalenums.h \ + icalerror.c \ + icalerror.h \ + icalyacc.y \ + icallexer.l \ + icalmemory.c \ + icalmemory.h \ + icalparameter.c \ + icalparameter.h \ + icalparser.c \ + icalparser.h \ + icalproperty.c \ + icalproperty.h \ + icalrestriction.c \ + icalrestriction.h \ + icaltypes.c \ + icaltypes.h \ + icalvalue.c \ + icalvalue.h \ + icalvcal.h \ + pvl.c \ + pvl.h + +include_HEADERS=\ + ical.h \ + icalcomponent.h \ + icalenums.h \ + icalerror.h \ + icalmemory.h \ + icalparameter.h \ + icalparser.h \ + icalproperty.h \ + icalrestriction.h \ + icaltypes.h \ + icalvalue.h \ + icalvcal.h \ + icalversion.h \ pvl.h -EXTRA_DIST = .gdbinit base64.c filelock.c filelock.h -YFLAGS=-picalparser_yy -d -LFLAGS=-Picalparser_yy -olex.yy.c + +EXTRA_DIST = icallexer.c icalyacc.c icalyacc.h + +CONFIG_CLEAN_FILES = y.output *~ + +DESIGNDATA = ../../design-data +ICALSCRIPTS = ../../scripts +derived: icalproperty icalparameter icalvalue + +icalproperty: + $(ICALSCRIPTS)/mkderivedproperties.pl -i icalproperty.h -h $(DESIGNDATA)/prop-to-value.txt ${DESIGNDATA}/value-c-types.txt > icalproperty.newh + mv icalproperty.newh icalproperty.h + + $(ICALSCRIPTS)/mkderivedproperties.pl -i icalproperty.c -c $(DESIGNDATA)/prop-to-value.txt ${DESIGNDATA}/value-c-types.txt > icalproperty.newc + mv icalproperty.newc icalproperty.c + + +icalparameter: + $(ICALSCRIPTS)/mkderivedparameters.pl -i icalparameter.h -h $(DESIGNDATA)/param-c-types.txt > icalparameter.newh + mv icalparameter.newh icalparameter.h + + $(ICALSCRIPTS)/mkderivedparameters.pl -i icalparameter.c -c $(DESIGNDATA)/param-c-types.txt > icalparameter.newc + mv icalparameter.newc icalparameter.c + +icalvalue: + $(ICALSCRIPTS)/mkderivedvalues.pl -i icalvalue.h -h $(DESIGNDATA)/value-c-types.txt > icalvalue.newh + mv icalvalue.newh icalvalue.h + + $(ICALSCRIPTS)/mkderivedvalues.pl -i icalvalue.c -c $(DESIGNDATA)/value-c-types.txt > icalvalue.newc + mv icalvalue.newc icalvalue.c + + diff --git a/libical/src/libical/ical.h b/libical/src/libical/ical.h index cd5ca31dd5..d0f33cd1a1 100644 --- a/libical/src/libical/ical.h +++ b/libical/src/libical/ical.h @@ -25,6 +25,7 @@ #ifndef ICAL_H #define ICAL_H +#include "icalversion.h" #include "icalenums.h" #include "icalvalue.h" #include "icalparameter.h" @@ -36,7 +37,6 @@ #include "icalerror.h" #include "icalrestriction.h" - #endif /* !ICAL_H */ diff --git a/libical/src/libical/icalcomponent.c b/libical/src/libical/icalcomponent.c index a1a2535e7a..bd2b13189c 100644 --- a/libical/src/libical/icalcomponent.c +++ b/libical/src/libical/icalcomponent.c @@ -24,6 +24,11 @@ ======================================================================*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "ical.h" #include "pvl.h" /* "Pointer-to-void list" */ #include <stdlib.h> /* for malloc */ @@ -35,6 +40,8 @@ #include "icalmemory.h" #include "icalenums.h" +#define MAX_TMP 1024 + /* icalproperty functions that only components get to use */ void icalproperty_set_parent(icalproperty* property, @@ -85,7 +92,6 @@ icalcomponent_new_impl (icalcomponent_kind kind) if ( ( comp = (struct icalcomponent_impl*) malloc(sizeof(struct icalcomponent_impl))) == 0) { - errno = ENOMEM; icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } @@ -236,6 +242,12 @@ icalcomponent_as_ical_string (icalcomponent* component) char* tmp_buf; size_t buf_size = 1024; char* buf_ptr = 0; + +#ifdef ICAL_UNIX_NEWLINE + char newline[] = "\n"; +#else + char newline[] = "\r\n"; +#endif icalcomponent *c; icalproperty *p; @@ -255,7 +267,7 @@ icalcomponent_as_ical_string (icalcomponent* component) icalmemory_append_string(&buf, &buf_ptr, &buf_size, "BEGIN:"); icalmemory_append_string(&buf, &buf_ptr, &buf_size, kind_string); - icalmemory_append_string(&buf, &buf_ptr, &buf_size, "\n"); + icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); for(p = icalcomponent_get_first_property(component,ICAL_ANY_PROPERTY); @@ -281,7 +293,7 @@ icalcomponent_as_ical_string (icalcomponent* component) icalmemory_append_string(&buf, &buf_ptr, &buf_size, "END:"); icalmemory_append_string(&buf, &buf_ptr, &buf_size, icalenum_component_kind_to_string(kind)); - icalmemory_append_string(&buf, &buf_ptr, &buf_size, "\n"); + icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); out_buf = icalmemory_tmp_copy(buf); free(buf); @@ -680,9 +692,79 @@ void icalcomponent_strip_errors(icalcomponent* component) icalcomponent_strip_errors(c); } +} + + +void icalcomponent_convert_errors(icalcomponent* component) +{ + icalproperty *p, *next_p; + icalcomponent *c; + + for(p = icalcomponent_get_first_property(component,ICAL_ANY_PROPERTY); + p != 0; + p = next_p){ + + next_p = icalcomponent_get_next_property(component,ICAL_ANY_PROPERTY); + + if(icalproperty_isa(p) == ICAL_XLICERROR_PROPERTY) + { + struct icalreqstattype rst; + char tmp[MAX_TMP]; + icalparameter *param = icalproperty_get_first_parameter + (p,ICAL_XLICERRORTYPE_PARAMETER); + + rst.code = ICAL_UNKNOWN_STATUS; + rst.desc = 0; + + switch(icalparameter_get_xlicerrortype(param)){ + + case ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR: { + rst.code = ICAL_3_2_INVPARAM_STATUS; + break; + } + case ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR: { + rst.code = ICAL_3_3_INVPARAMVAL_STATUS; + break; + } + case ICAL_XLICERRORTYPE_PROPERTYPARSEERROR: { + rst.code = ICAL_3_0_INVPROPNAME_STATUS; + break; + } + case ICAL_XLICERRORTYPE_VALUEPARSEERROR: { + rst.code = ICAL_3_1_INVPROPVAL_STATUS; + break; + } + case ICAL_XLICERRORTYPE_COMPONENTPARSEERROR: { + rst.code = ICAL_3_4_INVCOMP_STATUS; + break; + } + + default: { + } + } + if (rst.code != ICAL_UNKNOWN_STATUS){ + + rst.debug = icalproperty_get_xlicerror(p); + icalcomponent_add_property(component, + icalproperty_new_requeststatus( + icalreqstattype_as_string(rst) + ) + ); + + icalcomponent_remove_property(component,p); + } + } + } + for(c = icalcomponent_get_first_component(component,ICAL_ANY_COMPONENT); + c != 0; + c = icalcomponent_get_next_component(component,ICAL_ANY_COMPONENT)){ + + icalcomponent_convert_errors(c); + } } + icalcomponent* icalcomponent_get_parent(icalcomponent* component) { struct icalcomponent_impl *c = (struct icalcomponent_impl*)component; diff --git a/libical/src/libical/icalcomponent.h b/libical/src/libical/icalcomponent.h index 9e0e9f5a9f..8d9f22ca76 100644 --- a/libical/src/libical/icalcomponent.h +++ b/libical/src/libical/icalcomponent.h @@ -101,8 +101,12 @@ icalproperty** icalcomponent_get_component(icalcomponent* component, /* Working with embedded error properties */ int icalcomponent_count_errors(icalcomponent* component); + +/* Remove all X-LIC-ERROR properties*/ void icalcomponent_strip_errors(icalcomponent* component); +/* Convert some X-LIC-ERROR properties into RETURN-STATUS properties*/ +void icalcomponent_convert_errors(icalcomponent* component); /* Internal operations. You don't see these... */ icalcomponent* icalcomponent_get_parent(icalcomponent* component); diff --git a/libical/src/libical/icalenums.c b/libical/src/libical/icalenums.c index 70931d03d0..95f308eec6 100644 --- a/libical/src/libical/icalenums.c +++ b/libical/src/libical/icalenums.c @@ -24,6 +24,11 @@ ======================================================================*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "icalenums.h" struct icalproperty_kind_map { @@ -224,6 +229,7 @@ static struct icalvalue_kind_map value_map[] = { ICAL_TIME_VALUE, "TIME"}, { ICAL_URI_VALUE, "URI"}, { ICAL_UTCOFFSET_VALUE, "UTC-OFFSET"}, + { ICAL_METHOD_VALUE, "METHOD"}, /* Not an RFC2445 type */ { ICAL_GEO_VALUE, "FLOAT"}, /* Not an RFC2445 type */ { ICAL_ATTACH_VALUE, "XATTACH"}, /* Not an RFC2445 type */ { ICAL_DATETIMEDATE_VALUE, "XDATETIMEDATE"}, /* Not an RFC2445 type */ @@ -281,7 +287,8 @@ static struct icalcomponent_kind_map component_map[] = /* libical private components */ { ICAL_XLICINVALID_COMPONENT, "X-LIC-UNKNOWN" }, - { ICAL_XROOT_COMPONENT, "ROOT" }, + { ICAL_ANY_COMPONENT, "ANY" }, + { ICAL_XROOT_COMPONENT, "XROOT" }, /* End of list */ { ICAL_NO_COMPONENT, "" }, @@ -326,7 +333,7 @@ struct icalproperty_kind_value_map { static struct icalproperty_kind_value_map propval_map[] = { { ICAL_CALSCALE_PROPERTY, ICAL_TEXT_VALUE }, - { ICAL_METHOD_PROPERTY, ICAL_TEXT_VALUE }, + { ICAL_METHOD_PROPERTY, ICAL_METHOD_VALUE }, { ICAL_PRODID_PROPERTY, ICAL_TEXT_VALUE }, { ICAL_VERSION_PROPERTY, ICAL_TEXT_VALUE }, { ICAL_CATEGORIES_PROPERTY, ICAL_TEXT_VALUE }, @@ -481,7 +488,7 @@ struct { {ICAL_3_1_INVPROPVAL_STATUS, 3,1,"Invalid property value."}, {ICAL_3_2_INVPARAM_STATUS, 3,2,"Invalid property parameter."}, {ICAL_3_3_INVPARAMVAL_STATUS, 3,3,"Invalid property parameter value."}, - {ICAL_3_4_INVCOMP_STATUS, 3,4,"Invalid calendar component sequence."}, + {ICAL_3_4_INVCOMP_STATUS, 3,4,"Invalid calendar component."}, {ICAL_3_5_INVTIME_STATUS, 3,5,"Invalid date or time."}, {ICAL_3_6_INVRULE_STATUS, 3,6,"Invalid rule."}, {ICAL_3_7_INVCU_STATUS, 3,7,"Invalid Calendar User."}, @@ -496,9 +503,65 @@ struct { {ICAL_5_0_MAYBE_STATUS, 5,0,"Request MAY supported."}, {ICAL_5_1_UNAVAIL_STATUS, 5,1,"Service unavailable."}, {ICAL_5_2_NOSERVICE_STATUS, 5,2,"Invalid calendar service."}, - {ICAL_5_3_NOSCHED_STATUS, 5,3,"No scheduling support for user."} + {ICAL_5_3_NOSCHED_STATUS, 5,3,"No scheduling support for user."}, + {ICAL_UNKNOWN_STATUS, 0,0,"Error: Unknown request status"} }; + +char* icalenum_reqstat_desc(icalrequeststatus stat) +{ + + int i; + + for (i=0; status_map[i].kind != ICAL_UNKNOWN_STATUS; i++) { + if ( status_map[i].kind == stat) { + return status_map[i].str; + } + } + + return 0; +} + + +short icalenum_reqstat_major(icalrequeststatus stat) +{ + int i; + + for (i=0; status_map[i].kind != ICAL_UNKNOWN_STATUS; i++) { + if ( status_map[i].kind == stat) { + return status_map[i].major; + } + } + return -1; +} + +short icalenum_reqstat_minor(icalrequeststatus stat) +{ + int i; + + for (i=0; status_map[i].kind != ICAL_UNKNOWN_STATUS; i++) { + if ( status_map[i].kind == stat) { + return status_map[i].minor; + } + } + return -1; +} + + +icalrequeststatus icalenum_num_to_reqstat(short major, short minor) +{ + int i; + + for (i=0; status_map[i].kind != ICAL_UNKNOWN_STATUS; i++) { + if ( status_map[i].major == major && status_map[i].minor == minor) { + return status_map[i].kind; + } + } + return 0; +} + + + struct {icalproperty_method method; char* str;} method_map[] = { {ICAL_METHOD_PUBLISH,"PUBLISH"}, {ICAL_METHOD_REQUEST,"REQUEST"}, @@ -537,6 +600,11 @@ icalproperty_method icalenum_string_to_method(char* str) { int i; + while(*str == ' '){ + str++; + } + + for (i=0; method_map[i].method != ICAL_METHOD_NONE; i++) { if ( strcmp(method_map[i].str, str) == 0) { return method_map[i].method; diff --git a/libical/src/libical/icalenums.h b/libical/src/libical/icalenums.h index e60d230854..ff7cee486e 100644 --- a/libical/src/libical/icalenums.h +++ b/libical/src/libical/icalenums.h @@ -36,8 +36,8 @@ typedef enum icalcomponent_kind { ICAL_NO_COMPONENT, - ICAL_ANY_COMPONENT, /* Used in get_components to select all components*/ - ICAL_XROOT_COMPONENT, /* Root component returned by parser */ + ICAL_ANY_COMPONENT, /* Used to select all components*/ + ICAL_XROOT_COMPONENT, ICAL_XATTACH_COMPONENT, /* MIME attached data, returned by parser. */ ICAL_VEVENT_COMPONENT, ICAL_VTODO_COMPONENT, @@ -210,9 +210,10 @@ typedef enum icalvalue_kind { ICAL_FLOAT_VALUE, ICAL_GEO_VALUE, /* Non-Standard */ ICAL_INTEGER_VALUE, - ICAL_METHOD_VALUE, + ICAL_METHOD_VALUE, /* Non-Standard */ ICAL_PERIOD_VALUE, ICAL_RECUR_VALUE, + ICAL_STRING_VALUE, /* Non-Standard */ ICAL_TEXT_VALUE, ICAL_TIME_VALUE, ICAL_TRIGGER_VALUE, /* Non-Standard */ @@ -318,7 +319,8 @@ typedef enum icalparameter_role { typedef enum icalparameter_xlicerrortype { ICAL_XLICERRORTYPE_COMPONENTPARSEERROR, - ICAL_XLICERRORTYPE_PARAMETERPARSEERROR, + ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR, + ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR, ICAL_XLICERRORTYPE_PROPERTYPARSEERROR, ICAL_XLICERRORTYPE_VALUEPARSEERROR, ICAL_XLICERRORTYPE_INVALIDITIP @@ -396,6 +398,7 @@ char* icalenum_weekday_to_string(icalrecurrencetype_weekday kind); **********************************************************************/ typedef enum icalrequeststatus { + ICAL_UNKNOWN_STATUS, ICAL_2_0_SUCCESS_STATUS, ICAL_2_1_FALLBACK_STATUS, ICAL_2_2_IGPROP_STATUS, @@ -431,6 +434,10 @@ typedef enum icalrequeststatus { } icalrequeststatus; +char* icalenum_reqstat_desc(icalrequeststatus stat); +short icalenum_reqstat_major(icalrequeststatus stat); +short icalenum_reqstat_minor(icalrequeststatus stat); +icalrequeststatus icalenum_num_to_reqstat(short major, short minor); /*********************************************************************** * Conversion functions diff --git a/libical/src/libical/icalerror.c b/libical/src/libical/icalerror.c index d84c288d3a..fb9e152b16 100644 --- a/libical/src/libical/icalerror.c +++ b/libical/src/libical/icalerror.c @@ -25,6 +25,11 @@ ======================================================================*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "icalerror.h" icalerrorenum icalerrno; @@ -35,6 +40,15 @@ void icalerror_stop_here(void) foo++; /* Keep optimizers from removing routine */ } +void icalerror_crash_here(void) +{ + int *p=0; + *p = 1; + + assert( *p); +} + + void icalerror_clear_errno() { icalerrno = ICAL_NO_ERROR; diff --git a/libical/src/libical/icalerror.h b/libical/src/libical/icalerror.h index 429d680022..124699c21b 100644 --- a/libical/src/libical/icalerror.h +++ b/libical/src/libical/icalerror.h @@ -36,6 +36,8 @@ below */ void icalerror_stop_here(void); +void icalerror_crash_here(void); + #ifdef ICAL_ERRORS_ARE_FATAL #undef NDEBUG #endif diff --git a/libical/src/libical/icallexer.l b/libical/src/libical/icallexer.l new file mode 100644 index 0000000000..9026b9ae41 --- /dev/null +++ b/libical/src/libical/icallexer.l @@ -0,0 +1,282 @@ +%{ +/* -*- Mode: C -*- + ====================================================================== + FILE: icallexer.l + CREATOR: eric 10 June 1999 + + DESCRIPTION: + + $Id: icallexer.l,v 1.1 2000/04/18 18:17:04 alves Exp $ + $Locker: $ + + (C) COPYRIGHT 1999 Eric Busboom + http://www.softwarestudio.org + + The contents of this file are subject to the Mozilla Public License + Version 1.0 (the "License"); you may not use this file except in + compliance with the License. You may obtain a copy of the License at + http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and + limitations under the License. + + The original author is Eric Busboom + The original code is icalitip.y + + + + ======================================================================*/ +#include "icalyacc.h" +#include "icalparser.h" +#include "icalenums.h" +#include "icalmemory.h" +#include "assert.h" + +#include <string.h> /* For strdup() */ + +int icalparser_flex_input(char* buf, int max_size); +void icalparser_clear_flex_input(); + + +#define ICAL_MAX_STR_CONST 1024 + +#undef YY_INPUT +#define YY_INPUT(b,r,ms) ( r= icalparser_flex_input(b,ms)) +#undef yywrap + +#undef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yyerror(msg) + +icalvalue_kind value_kind=ICAL_NO_VALUE; +void set_parser_value_state(); +extern int yydebug; + +void yyerror(char *s); + +void init_str_buf(); + +int last_state; + +char *str_buf; +char *str_buf_p; +size_t buf_sz; /* = ICAL_MAX_STR_CONST;*/ + + +%} + +crlf \x0D?\x0A +space [ ] +qsafechar [^\x00-\x1F\"] +safechar [^\x00-\x1F\"\:\;\,] +tsafechar [\x20-\x21\x23-\x2B\x2D-\x39\x3C-\x5B\x5D-\x7E] +valuechar [^\x00-\x08\x10-\x1F] +xname X-[a-zA-Z0-9\-]+ +xname2 [a-zA-Z0-9\-\ ] +paramtext {safechar}+ +value {valuechar}+ +quotedstring \"{qsafechar}+\" +digit [0-9] + +%array /* Make yytext an array. Slow, but handy. HACK */ + +%option caseless + +%s quoted_string +%s binary_value boolean_value uri_value time_value duration_value number_value period_value recur_value text_value utcoffset_value +%s enum_param_value string_param_value stringlist_param_value keyword line_start component seperator parameter end_of_value paramtext + + + +%% + +%{ +%} + + +<binary_value>{ +.* { yylval.v_string= icalmemory_tmp_copy(yytext); + return STRING;} +{crlf} { return EOL;} + +} + +<boolean_value>{ +. { return CHARACTER; } +{crlf} { return EOL;} + +} + +<uri_value>{ +.* { yylval.v_string= icalmemory_tmp_copy(yytext); + return STRING;} +{crlf} { return EOL;} + +} + + +<time_value>{ +{digit}* { yylval.v_string= icalmemory_tmp_copy(yytext); + return DIGITS; } +T { return TIME_CHAR; } +Z { return UTC_CHAR; } +{crlf} { return EOL;} +} + +<duration_value>{ +{digit}+ { yylval.v_string =icalmemory_tmp_copy(yytext); + return DIGITS; } +T { return TIME_CHAR; } +[\+\-PTWHMSD] { return yytext[0]; } +{crlf} { return EOL;} + +} + +<number_value>{ +[\+\-\.0-9]+ { yylval.v_int=atoi(yytext); return INTNUMBER; } +{crlf} { return EOL;} +} + +<period_value>{ +{digit}+ { yylval.v_string =icalmemory_tmp_copy(yytext) ; + return DIGITS; } +T { return TIME_CHAR; } +Z { return UTC_CHAR; } +[\/\+\-PWHMSD] { return yytext[0]; } +{crlf} { return EOL;} + +} + +<recur_value>{ +INTERVAL { return INTERVAL; } +COUNT { return COUNT; } +UNTIL { return UNTIL; } +FREQ { return FREQ; } +BYDAY { return BYDAY; } +BYHOUR { return BYHOUR; } +BYMINUTE { return BYMINUTE; } +BYMONTH { return BYMONTH; } +BYMONTHDAY { return BYMONTHDAY; } +BYSECOND { return BYSECOND; } +BYSETPOS { return BYSETPOS; } +BYWEEKNO { return BYWEEKNO; } +BYYEARDAY { return BYYEARDAY; } +DAILY { return DAILY; } +SECONDLY { return SECONDLY; } +MINUTELY { return MINUTELY; } +HOURLY { return HOURLY; } +MONTHLY { return MONTHLY; } +WEEKLY { return WEEKLY; } +YEARLY { return YEARLY; } +WKST { return WKST; } +MO { return MO; } +SA { return SA; } +SU { return SU; } +TU { return TU; } +WE { return WE; } +TH { return TH; } +FR { return FR; } += { return EQUALS; } +, { return COMMA; } +; { return SEMICOLON; } +[\-\+0-9]+ { yylval.v_string= icalmemory_tmp_copy(yytext); + return DIGITS; } +T { return TIME_CHAR; } +Z { return UTC_CHAR; } +{crlf} { return EOL;} +} + +<utcoffset_value>{ +{crlf} { return EOL;} +\-|\+ { return yytext[0]; } +{digit}{digit} { yylval.v_int=atoi(yytext); return INTNUMBER; } + +} + +<enum_param_value>{ +. { return CHARACTER; } +{crlf} { return EOL;} + +} + +<seperator>{ +, { BEGIN(last_state); return COMMA; } +} + + +%% + +int yywrap() +{ + return 1; +} + + +void set_parser_value_state(icalvalue_kind kind) +{ + + switch (kind){ + + case ICAL_ATTACH_VALUE: + case ICAL_BINARY_VALUE: + {BEGIN(binary_value);break;} + + case ICAL_BOOLEAN_VALUE: + case ICAL_INTEGER_VALUE: + case ICAL_FLOAT_VALUE: + {BEGIN(number_value);break;} + + case ICAL_UTCOFFSET_VALUE: + {BEGIN(utcoffset_value);break;} + + case ICAL_TEXT_VALUE: + {BEGIN(text_value); + init_str_buf(); + break;} + + case ICAL_CALADDRESS_VALUE: + case ICAL_URI_VALUE: + {BEGIN(uri_value);break;} + + case ICAL_DATE_VALUE: + case ICAL_DATETIME_VALUE: + case ICAL_DATETIMEDATE_VALUE: + case ICAL_DATETIMEPERIOD_VALUE: + case ICAL_TIME_VALUE: + {BEGIN(time_value);break;} + + case ICAL_DURATION_VALUE: + {BEGIN(duration_value);break;} + + case ICAL_PERIOD_VALUE: + {BEGIN(period_value);break;} + + case ICAL_GEO_VALUE: + case ICAL_QUERY_VALUE: + {BEGIN(text_value);break;} + + case ICAL_RECUR_VALUE: + {BEGIN(recur_value);break;} + + case ICAL_NO_VALUE: + { + /* The value is probably actually a component name */ + {BEGIN(component); break;} + } + default: + { + assert(1==0); + } + } +} + +void init_str_buf() +{ + str_buf = icalmemory_tmp_buffer(ICAL_MAX_STR_CONST); + str_buf_p = str_buf; + buf_sz = ICAL_MAX_STR_CONST; + + +} + diff --git a/libical/src/libical/icalmemory.c b/libical/src/libical/icalmemory.c index 7d99eb62b3..e89451fbce 100644 --- a/libical/src/libical/icalmemory.c +++ b/libical/src/libical/icalmemory.c @@ -35,14 +35,19 @@ * several buffers active simultaneously, which is handy when creating * string representations of components. */ - #define ICALMEMORY_C +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + #include "icalmemory.h" #include "icalerror.h" #include <stdio.h> /* for printf (debugging) */ #include <stdlib.h> /* for malloc, realloc */ +#include <string.h> /* for memset() */ #define BUFFER_RING_SIZE 25 #define MIN_BUFFER_SIZE 200 diff --git a/libical/src/libical/icalparameter.c b/libical/src/libical/icalparameter.c index ff9c76f79c..cf37eb07b2 100644 --- a/libical/src/libical/icalparameter.c +++ b/libical/src/libical/icalparameter.c @@ -28,6 +28,10 @@ ======================================================================*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "ical.h" #include "icalerror.h" #include <stdlib.h> /* for malloc() */ @@ -68,7 +72,6 @@ struct icalparameter_impl* icalparameter_new_impl(icalparameter_kind kind) if ( ( v = (struct icalparameter_impl*) malloc(sizeof(struct icalparameter_impl))) == 0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); - errno = ENOMEM; return 0; } @@ -412,8 +415,11 @@ icalparameter* icalparameter_new_from_string(icalparameter_kind kind, char* val) else if(strcmp(val,"PROPERTY_PARSE_ERROR") == 0){ param = icalparameter_new_xlicerrortype(ICAL_XLICERRORTYPE_PROPERTYPARSEERROR); } - else if(strcmp(val,"PARAMETER_PARSE_ERROR") == 0){ - param = icalparameter_new_xlicerrortype(ICAL_XLICERRORTYPE_PARAMETERPARSEERROR); + else if(strcmp(val,"PARAMETER_NAME_PARSE_ERROR") == 0){ + param = icalparameter_new_xlicerrortype(ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR); + } + else if(strcmp(val,"PARAMETER_VALUE_PARSE_ERROR") == 0){ + param = icalparameter_new_xlicerrortype(ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR); } else if(strcmp(val,"VALUE_PARSE_ERROR") == 0){ param = icalparameter_new_xlicerrortype(ICAL_XLICERRORTYPE_VALUEPARSEERROR); @@ -423,6 +429,37 @@ icalparameter* icalparameter_new_from_string(icalparameter_kind kind, char* val) } break; } + + case ICAL_XLICCOMPARETYPE_PARAMETER: + { + + if(strcmp(val,"EQUAL") == 0){ + param = icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_EQUAL); + } + else if(strcmp(val,"NOTEQUAL") == 0){ + param = icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_NOTEQUAL); + } + else if(strcmp(val,"LESS") == 0){ + param = icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_LESS); + } + else if(strcmp(val,"GREATER") == 0){ + param = icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_GREATER); + } + else if(strcmp(val,"LESSEQUAL") == 0){ + param = icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_LESSEQUAL); + } + else if(strcmp(val,"GREATEREQUAL") == 0){ + param = icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_GREATEREQUAL); + } + else if(strcmp(val,"REGEX") == 0){ + param = icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_REGEX); + } else { + param = 0; + } + break; + } + + case ICAL_X_PARAMETER: { param = icalparameter_new(ICAL_FBTYPE_PARAMETER); @@ -767,7 +804,7 @@ icalparameter_as_ical_string (icalparameter* parameter) strcpy(tend,impl->string);break; } default:{ - strcpy(tend,"ERROR");break; + strcpy(tend,"ERROR"); icalerror_set_errno(ICAL_BADARG_ERROR);break; } } @@ -786,9 +823,13 @@ icalparameter_as_ical_string (icalparameter* parameter) { strcpy(tend,"PROPERTY_PARSE_ERROR");break; } - case ICAL_XLICERRORTYPE_PARAMETERPARSEERROR: + case ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR: + { + strcpy(tend,"PARAMETER_NAME_PARSE_ERROR");break; + } + case ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR: { - strcpy(tend,"PARAMETER_PARSE_ERROR");break; + strcpy(tend,"PARAMETER_VALUE_PARSE_ERROR");break; } case ICAL_XLICERRORTYPE_VALUEPARSEERROR: { @@ -1026,7 +1067,7 @@ char* icalparameter_get_altrep(icalparameter* param) void icalparameter_set_altrep(icalparameter* param, char* v) { - icalerror_check_arg_rz( (v!=0),"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -1062,7 +1103,7 @@ char* icalparameter_get_cn(icalparameter* param) void icalparameter_set_cn(icalparameter* param, char* v) { - icalerror_check_arg_rz( (v!=0),"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -1139,7 +1180,7 @@ char* icalparameter_get_delegatedfrom(icalparameter* param) void icalparameter_set_delegatedfrom(icalparameter* param, char* v) { - icalerror_check_arg_rz( (v!=0),"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -1175,7 +1216,7 @@ char* icalparameter_get_delegatedto(icalparameter* param) void icalparameter_set_delegatedto(icalparameter* param, char* v) { - icalerror_check_arg_rz( (v!=0),"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -1211,7 +1252,7 @@ char* icalparameter_get_dir(icalparameter* param) void icalparameter_set_dir(icalparameter* param, char* v) { - icalerror_check_arg_rz( (v!=0),"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -1329,7 +1370,7 @@ char* icalparameter_get_fmttype(icalparameter* param) void icalparameter_set_fmttype(icalparameter* param, char* v) { - icalerror_check_arg_rz( (v!=0),"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -1365,7 +1406,7 @@ char* icalparameter_get_language(icalparameter* param) void icalparameter_set_language(icalparameter* param, char* v) { - icalerror_check_arg_rz( (v!=0),"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -1401,7 +1442,7 @@ char* icalparameter_get_member(icalparameter* param) void icalparameter_set_member(icalparameter* param, char* v) { - icalerror_check_arg_rz( (v!=0),"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -1473,9 +1514,6 @@ icalparameter_range icalparameter_get_range(icalparameter* param) { icalerror_clear_errno(); icalerror_check_arg( (param!=0), "param"); - if ( ((struct icalparameter_impl*)param)->string != 0){ - return ICAL_PARTSTAT_XNAME; - } return ((struct icalparameter_impl*)param)->data.v_range; @@ -1514,9 +1552,6 @@ icalparameter_related icalparameter_get_related(icalparameter* param) { icalerror_clear_errno(); icalerror_check_arg( (param!=0), "param"); - if ( ((struct icalparameter_impl*)param)->string != 0){ - return ICAL_PARTSTAT_XNAME; - } return ((struct icalparameter_impl*)param)->data.v_related; @@ -1637,9 +1672,6 @@ int icalparameter_get_rsvp(icalparameter* param) { icalerror_clear_errno(); icalerror_check_arg( (param!=0), "param"); - if ( ((struct icalparameter_impl*)param)->string != 0){ - return ICAL_ROLE_XNAME; - } return ((struct icalparameter_impl*)param)->data.v_rsvp; @@ -1683,7 +1715,7 @@ char* icalparameter_get_sentby(icalparameter* param) void icalparameter_set_sentby(icalparameter* param, char* v) { - icalerror_check_arg_rz( (v!=0),"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -1719,7 +1751,7 @@ char* icalparameter_get_tzid(icalparameter* param) void icalparameter_set_tzid(icalparameter* param, char* v) { - icalerror_check_arg_rz( (v!=0),"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -1796,7 +1828,7 @@ char* icalparameter_get_x(icalparameter* param) void icalparameter_set_x(icalparameter* param, char* v) { - icalerror_check_arg_rz( (v!=0),"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); @@ -1827,9 +1859,6 @@ icalparameter_xlicerrortype icalparameter_get_xlicerrortype(icalparameter* param { icalerror_clear_errno(); icalerror_check_arg( (param!=0), "param"); - if ( ((struct icalparameter_impl*)param)->string != 0){ - return ICAL_VALUE_XNAME; - } return ((struct icalparameter_impl*)param)->data.v_xlicerrortype; @@ -1868,9 +1897,6 @@ icalparameter_xliccomparetype icalparameter_get_xliccomparetype(icalparameter* p { icalerror_clear_errno(); icalerror_check_arg( (param!=0), "param"); - if ( ((struct icalparameter_impl*)param)->string != 0){ - return ICAL_VALUE_XNAME; - } return ((struct icalparameter_impl*)param)->data.v_xliccomparetype; diff --git a/libical/src/libical/icalparser.c b/libical/src/libical/icalparser.c index b4c1822a68..8541ae4fab 100644 --- a/libical/src/libical/icalparser.c +++ b/libical/src/libical/icalparser.c @@ -16,25 +16,30 @@ the License for the specific language governing rights and limitations under the License. - The Original Code is eric. The Initial Developer of the Original - Code is + The Initial Developer of the Original Code is Eric Busboom (C) COPYRIGHT 1999 The Software Studio. http://www.softwarestudio.org ======================================================================*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + #include "ical.h" #include "pvl.h" #include "icalparser.h" #include "icalmemory.h" -#include <string.h> /* For strncpy */ +#include <string.h> /* For strncpy & size_t */ #include <stdio.h> /* For FILE and fgets and sprintf */ #include <stdlib.h> /* for free */ extern icalvalue* icalparser_yy_value; void set_parser_value_state(icalvalue_kind kind); -int icalparser_yyparse(void); +int ical_yy_parse(void); char* icalparser_get_next_char(char c, char *str); char* icalparser_get_next_parameter(char* line,char** end); @@ -42,7 +47,77 @@ char* icalparser_get_next_value(char* line, char **end, icalvalue_kind kind); char* icalparser_get_prop_name(char* line, char** end); char* icalparser_get_param_name(char* line, char **end); -icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind, char* str, icalproperty **error); +#define TMP_BUF_SIZE 80 + +struct icalparser_impl +{ + int buffer_full; + size_t tmp_buf_size; + char temp[TMP_BUF_SIZE]; + icalcomponent *root_component; + icalcomponent *tail; + int version; + int level; + int lineno; + icalparser_state state; + pvl_list components; + + void *line_gen_data; + +}; + + +icalparser* icalparser_new() +{ + struct icalparser_impl* impl = 0; + + if ( ( impl = (struct icalparser_impl*) + malloc(sizeof(struct icalparser_impl))) == 0) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return 0; + } + + impl->root_component = 0; + impl->components = pvl_newlist(); + impl->level = 0; + impl->state = ICALPARSER_SUCCESS; + + impl->tmp_buf_size = TMP_BUF_SIZE; + impl->buffer_full = 0; + impl->lineno = 0; + + memset(impl->temp,0, TMP_BUF_SIZE); + + return (icalparser*)impl; +} + +void icalparser_free(icalparser* parser) +{ + struct icalparser_impl* impl = (struct icalparser_impl*)parser; + icalcomponent *c; + + if (impl->root_component != 0){ + icalcomponent_free(impl->root_component); + } + + while( (c=pvl_pop(impl->components)) != 0){ + icalcomponent_free(c); + } + + pvl_free(impl->components); +} + +void icalparser_set_gen_data(icalparser* parser, void* data) +{ + struct icalparser_impl* impl = (struct icalparser_impl*)parser; + + impl->line_gen_data = data; +} + + +icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind, + char* str, + icalproperty **error); @@ -114,7 +189,7 @@ void icalparser_clear_flex_input() /* Cal the flex parser to parse a complex value */ icalvalue* icalparser_parse_value(icalvalue_kind kind, - char* str, icalproperty** error) + char* str, icalproperty** error) { int r; input_buffer_p = input_buffer = str; @@ -122,7 +197,7 @@ icalvalue* icalparser_parse_value(icalvalue_kind kind, set_parser_value_state(kind); icalparser_yy_value = 0; - r = icalparser_yyparse(); + r = ical_yy_parse(); /* Error. Parse failed */ if( icalparser_yy_value == 0 || r != 0){ @@ -176,7 +251,7 @@ char* icalparser_get_param_name(char* line, char **end) next = icalparser_get_next_char('=',line); if (next == 0) { - return 0; + return 0; } str = make_segment(line,next); @@ -223,50 +298,50 @@ char* icalparser_get_next_value(char* line, char **end, icalvalue_kind kind) p = line; while(1){ - next = icalparser_get_next_char(',',p); + next = icalparser_get_next_char(',',p); - /* Unforunately, RFC2445 says that for the RECUR value, COMMA - can both seperate digits in a list, and it can seperate - multiple recurrence specifications. This is not a friendly - part of the spec. This weirdness tries to - distinguish the two uses. it is probably a HACK*/ + /* Unforunately, RFC2445 says that for the RECUR value, COMMA + can both seperate digits in a list, and it can seperate + multiple recurrence specifications. This is not a friendly + part of the spec. This weirdness tries to + distinguish the two uses. it is probably a HACK*/ - if( kind == ICAL_RECUR_VALUE ) { - if ( next != 0 && - (*end+length) > next+5 && - strncmp(next,"FREQ",4) == 0 - ) { - /* The COMMA was followed by 'FREQ', is it a real seperator*/ - /* Fall through */ - printf("%s\n",next); - } else if (next != 0){ - /* Not real, get the next COMMA */ - p = next+1; - next = 0; - continue; - } - } - - /* If the comma is preceeded by a '\', then it is a literal and - not a value seperator*/ + if( kind == ICAL_RECUR_VALUE ) { + if ( next != 0 && + (*end+length) > next+5 && + strncmp(next,"FREQ",4) == 0 + ) { + /* The COMMA was followed by 'FREQ', is it a real seperator*/ + /* Fall through */ + printf("%s\n",next); + } else if (next != 0){ + /* Not real, get the next COMMA */ + p = next+1; + next = 0; + continue; + } + } + + /* If the comma is preceeded by a '\', then it is a literal and + not a value seperator*/ - if ( (next!=0 && *(next-1) == '\\') || - (next!=0 && *(next-3) == '\\') - ) - /*second clause for '/' is on prev line. HACK may be out of bounds */ - { - p = next+1; - } else { - break; - } + if ( (next!=0 && *(next-1) == '\\') || + (next!=0 && *(next-3) == '\\') + ) + /*second clause for '/' is on prev line. HACK may be out of bounds */ + { + p = next+1; + } else { + break; + } } if (next == 0){ next = (char*)(size_t)line+length; - *end = next; + *end = next; } else { - *end = next+1; + *end = next+1; } if (next == line){ @@ -305,22 +380,18 @@ char* icalparser_get_next_parameter(char* line,char** end) } } -/* HACK. This is not threadsafe */ -int buffer_full=0; -size_t tmp_buf_size = 80; -char temp[80]; - - /* Get a single property line, from the property name through the final new line, and include any continuation lines */ -char* icalparser_get_line(char* (*line_gen_func)(char *s, size_t size, void *d), int *lineno) +char* icalparser_get_line(icalparser *parser, + char* (*line_gen_func)(char *s, size_t size, void *d)) { char *line; char *line_p; - size_t buf_size = tmp_buf_size; - + struct icalparser_impl* impl = (struct icalparser_impl*)parser; + size_t buf_size = impl->tmp_buf_size; + line_p = line = icalmemory_new_buffer(buf_size); line[0] = '\0'; @@ -328,43 +399,63 @@ char* icalparser_get_line(char* (*line_gen_func)(char *s, size_t size, void *d), /* The buffer is not clear, so transfer the data in it to the output. This may be left over from a previous call */ - if (temp[0] != '\0' ) { - if (temp[tmp_buf_size-1] == 0){ - buffer_full = 1; + if (impl->temp[0] != '\0' ) { + + /* If the last position in the temp buffer is occupied, + mark the buffer as full. The means we will do another + read later, because the line is not finished */ + if (impl->temp[impl->tmp_buf_size-1] == 0){ + impl->buffer_full = 1; } else { - buffer_full = 0; + impl->buffer_full = 0; } - icalmemory_append_string(&line,&line_p,&buf_size,temp); - temp[0] = '\0' ; + + /* Copy the temp to the output and clear the temp buffer. */ + icalmemory_append_string(&line,&line_p,&buf_size,impl->temp); + impl->temp[0] = '\0' ; } - temp[tmp_buf_size-1] = 1; /* Mark end of buffer */ + impl->temp[impl->tmp_buf_size-1] = 1; /* Mark end of buffer */ + + if ((*line_gen_func)(impl->temp,impl->tmp_buf_size,impl->line_gen_data) + ==0){/* Get more data */ + + /* If the first position is clear, it means we didn't get + any more data from the last call to line_ge_func*/ + if (impl->temp[0] == '\0'){ - if ((*line_gen_func)(temp,tmp_buf_size,0)==0){/* Get more data */ - if (temp[0] == '\0'){ if(line[0] != '\0'){ + /* There is data in the output, so fall trhough and process it*/ break; } else { + /* No data in output; return and signal that there + is no more input*/ free(line); return 0; } } } + + + /* If the output line ends in a '\n' and the temp buffer + begins with a ' ', then the buffer holds a continuation + line, so keep reading. */ - if ( line_p > line+1 && *(line_p-1) == '\n' && temp[0] == ' ') { - - /* If the output line ends in a '\n' and the temp buffer - begins with a ' ', then the buffer holds a continuation - line, so keep reading. */ + if ( line_p > line+1 && *(line_p-1) == '\n' && impl->temp[0] == ' ') { /* back up the pointer to erase the continuation characters */ line_p--; + if ( *(line_p-1) == '\r'){ + line_p--; + } + /* shift the temp buffer down to eliminate the leading space*/ - memmove(&(temp[0]),&(temp[1]),tmp_buf_size); - temp[tmp_buf_size-1] = temp[tmp_buf_size-2]; + memmove(&(impl->temp[0]),&(impl->temp[1]),impl->tmp_buf_size); + + impl->temp[impl->tmp_buf_size-1] = impl->temp[impl->tmp_buf_size-2]; - } else if ( buffer_full == 1 ) { + } else if ( impl->buffer_full == 1 ) { /* The buffer was filled on the last read, so read again */ @@ -377,10 +468,13 @@ char* icalparser_get_line(char* (*line_gen_func)(char *s, size_t size, void *d), } - /* Erase the final newline */ - if ( line_p > line+1 && *(line_p-1) == '\n') { - + /* Erase the final newline and/or carriage return*/ + if ( line_p > line+1 && *(line_p-1) == '\n') { *(line_p-1) = '\0'; + if ( *(line_p-2) == '\r'){ + *(line_p-2) = '\0'; + } + } else { *(line_p) = '\0'; } @@ -389,111 +483,6 @@ char* icalparser_get_line(char* (*line_gen_func)(char *s, size_t size, void *d), } -#if 0 -char* icalparser_old_get_line(char* (*line_gen_func)(char *s, size_t size, void *d), int *lineno) -{ - char *line, *output_line; - char *line_p; - char last_line = 0; - size_t buf_size = tmp_buf_size; - int break_flag = 0; - - line_p = line = icalmemory_new_buffer(buf_size); - - /* If the hold buffer is empty, read a line. Otherwise, use the data that - is still in 'temp'*/ - if (hold == 1){ - /* Do nothing */ - } else { - temp[tmp_buf_size-1] = 1; /* Mark end of buffer */ - (*line_gen_func)(temp,tmp_buf_size,0); - } - - /* Append the hold buffer or new line into the output */ - icalmemory_append_string(&line,&line_p,&buf_size,temp); - - if ( temp[tmp_buf_size-1] == 0 ) { /* Check if mark was overwritten */ - buffer_full = 1; - } else { - buffer_full = 0; - } - - /* Try to suck up any continuation lines */ - while(last_line == 0){ - - temp[tmp_buf_size-1] = 1; /* Mark end of buffer */ - if ((*line_gen_func)(temp,tmp_buf_size,0) == 0){ - /* No more lines -- we are finished */ - if (hold == 1) { - hold = 0; - break_flag = 1; - } else { - icalmemory_free_buffer(line); - return 0; - } - } else { - if ( temp[tmp_buf_size-1] == 0 ) { - buffer_full = 1; - } else { - buffer_full = 0; - } - } - - /* keep track of line numbers */ - if (lineno != 0){ - (*lineno)++; - } - - - /* Determine wether to copy the line to the output, or - save it in the hold buffer */ - - if ( line_p > line+1 && *(line_p-1) == '\n' && temp[0] == ' ') { - - /* If the last line ( in the 'line' string ) ends in a '\n' - and the current line begins with a ' ', then the current line - is a continuation line, so append it. */ - - /* back up the pointer to erase the continuation characters */ - line_p--; - icalmemory_append_string(&line,&line_p,&buf_size,&(temp[1])); - - hold = 0; - buffer_full= 0; - - } else if (buffer_full == 1) { - - /* The last line that was read filled up the read - buffer. Append it and read again */ - - icalmemory_append_string(&line,&line_p,&buf_size,temp); - - hold = 0; - - } else if (break_flag != 1 ){ - /* Nope -- the line was not a continuation line. - Save the line for the next call */ - - hold =1; - break; - } else { - break; - } - } - - /* Erase the final newline */ - if ( line_p > line+1 && *(line_p-1) == '\n') { - - *(line_p-1) = '\0'; - } - - output_line = icalmemory_tmp_copy(line); - icalmemory_free_buffer(line); - - return output_line; -} -#endif - void insert_error(icalcomponent* comp, char* text, char* message, icalparameter_xlicerrortype type) { @@ -513,389 +502,489 @@ void insert_error(icalcomponent* comp, char* text, 0)); } -icalcomponent* icalparser_parse(char* (*line_gen_func)(char *s, size_t size, void* d)) +icalcomponent* icalparser_parse(icalparser *parser, + char* (*line_gen_func)(char *s, size_t size, + void* d)) { - char *line = 0; + char* line; + icalcomponent *c=0; + icalcomponent *root_component=0; + + icalerror_check_arg_rz((parser !=0),"parser"); + + do{ + line = icalparser_get_line(parser, line_gen_func); + + if ((c = icalparser_add_line(parser,line)) != 0){ + if (root_component == 0){ + /* Just one component */ + icalparser_claim(parser); + root_component = c; + } else if(icalcomponent_isa(root_component) + != ICAL_XROOT_COMPONENT) { + /*Got a second component, so move the two components under + an XROOT container */ + icalcomponent *tempc; + tempc = icalcomponent_new(ICAL_XROOT_COMPONENT); + icalcomponent_add_component(tempc, root_component); + icalparser_claim(parser); + icalcomponent_add_component(tempc, c); + root_component = tempc; + } else { + /* Already have an XROOT container, so add the component + to it*/ + icalcomponent_add_component(root_component, c); + icalparser_claim(parser); + } + } + } while ( line != 0); + + return root_component; + +} + +icalcomponent* icalparser_add_line(icalparser* parser, + char* line) +{ char *p; char *str; char *end; - int lineno = 0; - int vcount = 0; - - icalcomponent *root_component = 0; - icalcomponent *tail = 0; icalproperty *prop; icalvalue *value; + icalvalue_kind value_kind = ICAL_NO_VALUE; - icalvalue_kind value_kind; - - pvl_list components = pvl_newlist(); - - do { - value_kind = ICAL_NO_VALUE; + struct icalparser_impl *impl = (struct icalparser_impl*)parser; + icalerror_check_arg_rz((parser != 0),"parser"); - /* Get a single property line, from a property name through a - newline */ - if (line!=0){ - free(line); - } - - line = icalparser_get_line(line_gen_func,&lineno); - if (line == 0){ - continue; - } + if (line == 0) + { + impl->state = ICALPARSER_ERROR; + return 0; + } - end = 0; + /* Begin by getting the property name at the start of the line. The + property name may end up being "BEGIN" or "END" in which case it + is not really a property, but the market for the start or end of + a component */ - str = icalparser_get_prop_name(line, &end); + end = 0; + str = icalparser_get_prop_name(line, &end); - if (str == 0){ - tail = pvl_data(pvl_tail(components)); + if (str == 0){ + /* Could not get a property name */ + icalcomponent *tail = pvl_data(pvl_tail(impl->components)); - if (tail){ - insert_error(tail,line, - "Got a data line, but could not find a property name or component begin tag", - ICAL_XLICERRORTYPE_COMPONENTPARSEERROR); - } - tail = 0; - continue; + if (tail){ + insert_error(tail,line, + "Got a data line, but could not find a property name or component begin tag", + ICAL_XLICERRORTYPE_COMPONENTPARSEERROR); } + tail = 0; + impl->state = ICALPARSER_ERROR; + return 0; + } -/********************************************************************** - * Handle begin and end of components - **********************************************************************/ + /********************************************************************** + * Handle begin and end of components + **********************************************************************/ - /* If the property name is BEGIN or END, we are actually - starting or ending a new component */ + /* If the property name is BEGIN or END, we are actually + starting or ending a new component */ - if(strcmp(str,"BEGIN") == 0){ - icalcomponent *c; ; + if(strcmp(str,"BEGIN") == 0){ + icalcomponent *c; - str = icalparser_get_next_value(end,&end, value_kind); + impl->level++; + str = icalparser_get_next_value(end,&end, value_kind); - c = icalcomponent_new_from_string(str); + c = icalcomponent_new_from_string(str); - if (c == 0){ - c = icalcomponent_new(ICAL_XLICINVALID_COMPONENT); - insert_error(c,str,"Parse error in component name", - ICAL_XLICERRORTYPE_COMPONENTPARSEERROR); - } + if (c == 0){ + c = icalcomponent_new(ICAL_XLICINVALID_COMPONENT); + insert_error(c,str,"Parse error in component name", + ICAL_XLICERRORTYPE_COMPONENTPARSEERROR); + } - pvl_push(components,c); + pvl_push(impl->components,c); - continue; - } else if (strcmp(str,"END") == 0 ) { + impl->state = ICALPARSER_BEGIN_COMP; + return 0; - str = icalparser_get_next_value(end,&end, value_kind); + } else if (strcmp(str,"END") == 0 ) { + icalcomponent* tail; - root_component = pvl_pop(components); + impl->level--; + str = icalparser_get_next_value(end,&end, value_kind); - tail = pvl_data(pvl_tail(components)); + impl->root_component = pvl_pop(impl->components); - if(tail != 0){ - icalcomponent_add_component(tail,root_component); - } + tail = pvl_data(pvl_tail(impl->components)); - tail = 0; - continue; + if(tail != 0){ + icalcomponent_add_component(tail,impl->root_component); } + tail = 0; - /* There is no point in continuing if we have not seen a - component yet */ - - if(pvl_data(pvl_tail(components)) == 0){ - continue; + /* Return the component if we are back to the 0th level */ + if (impl->level == 0){ + impl->state = ICALPARSER_SUCCESS; + return impl->root_component; + } else { + impl->state = ICALPARSER_END_COMP; + return 0; } + } + + + /* There is no point in continuing if we have not seen a + component yet */ + if(pvl_data(pvl_tail(impl->components)) == 0){ + impl->state = ICALPARSER_ERROR; + return 0; + } -/********************************************************************** - * Handle property names - **********************************************************************/ - /* At this point, the property name really is a property name, - (Not a component name) so make a new property and add it to - the component */ - prop = icalproperty_new_from_string(str); + /********************************************************************** + * Handle property names + **********************************************************************/ + /* At this point, the property name really is a property name, + (Not a component name) so make a new property and add it to + the component */ - if (prop != 0){ - tail = pvl_data(pvl_tail(components)); + prop = icalproperty_new_from_string(str); - icalcomponent_add_property(tail, prop); + if (prop != 0){ + icalcomponent *tail = pvl_data(pvl_tail(impl->components)); - /* Set the value kind for the default for this type of - property. This may be re-set by a VALUE parameter */ - value_kind = - icalenum_property_kind_to_value_kind( - icalproperty_isa(prop)); - } else { - icalcomponent* tail = pvl_data(pvl_tail(components)); + icalcomponent_add_property(tail, prop); + + /* Set the value kind for the default for this type of + property. This may be re-set by a VALUE parameter */ + value_kind = + icalenum_property_kind_to_value_kind( + icalproperty_isa(prop)); - insert_error(tail,str,"Parse error in property name", - ICAL_XLICERRORTYPE_PROPERTYPARSEERROR); + } else { + icalcomponent* tail = pvl_data(pvl_tail(impl->components)); + + insert_error(tail,str,"Parse error in property name", + ICAL_XLICERRORTYPE_PROPERTYPARSEERROR); - tail = 0; - continue; - } + tail = 0; + impl->state = ICALPARSER_ERROR; + return 0; + } -/********************************************************************** - * Handle parameter values - **********************************************************************/ + /********************************************************************** + * Handle parameter values + **********************************************************************/ - /* Now, add any parameters to the last property */ + /* Now, add any parameters to the last property */ - p = 0; - while(1) { + p = 0; + while(1) { - if (*(end-1) == ':'){ - /* if the last seperator was a ":" and the value is a - URL, icalparser_get_next_parameter will find the - ':' in the URL, so better break now. */ - break; - } + if (*(end-1) == ':'){ + /* if the last seperator was a ":" and the value is a + URL, icalparser_get_next_parameter will find the + ':' in the URL, so better break now. */ + break; + } - str = icalparser_get_next_parameter(end,&end); + str = icalparser_get_next_parameter(end,&end); - if (str != 0){ - char* name; - char* pvalue; - icalparameter *param = 0; - icalparameter_kind kind; - - tail = pvl_data(pvl_tail(components)); + if (str != 0){ + char* name; + char* pvalue; + + icalparameter *param = 0; + icalparameter_kind kind; + icalcomponent *tail = pvl_data(pvl_tail(impl->components)); - name = icalparser_get_param_name(str,&pvalue); + name = icalparser_get_param_name(str,&pvalue); - if (name == 0){ - insert_error(tail, str, "Can't parse parameter name", - ICAL_XLICERRORTYPE_PARAMETERPARSEERROR); - tail = 0; - break; - } + if (name == 0){ + /* 'tail' defined above */ + insert_error(tail, str, "Can't parse parameter name", + ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR); + tail = 0; + break; + } - kind = icalenum_string_to_parameter_kind(name); - if (kind != ICAL_NO_PARAMETER){ - param = icalparameter_new_from_string(kind,pvalue); - } else { + kind = icalenum_string_to_parameter_kind(name); - /* Error. Failed to parse the parameter*/ - insert_error(tail, str, "Can't parse parameter name", - ICAL_XLICERRORTYPE_PARAMETERPARSEERROR); - tail = 0; - continue; - } + if (kind != ICAL_NO_PARAMETER){ + param = icalparameter_new_from_string(kind,pvalue); + } else { + /* Error. Failed to parse the parameter*/ + /* 'tail' defined above */ + insert_error(tail, str, "Can't parse parameter name", + ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR); + tail = 0; + impl->state = ICALPARSER_ERROR; + return 0; + } - if (param == 0){ - insert_error(tail,str,"Can't parse parameter value", - ICAL_XLICERRORTYPE_PARAMETERPARSEERROR); + if (param == 0){ + /* 'tail' defined above */ + insert_error(tail,str,"Can't parse parameter value", + ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR); - tail = 0; - continue; - } + tail = 0; + impl->state = ICALPARSER_ERROR; + continue; + } - /* If it is a VALUE parameter, set the kind of value*/ - if (icalparameter_isa(param)==ICAL_VALUE_PARAMETER){ + /* If it is a VALUE parameter, set the kind of value*/ + if (icalparameter_isa(param)==ICAL_VALUE_PARAMETER){ - value_kind = (icalvalue_kind) - icalparameter_get_value(param); + value_kind = (icalvalue_kind) + icalparameter_get_value(param); - if (value_kind == ICAL_NO_VALUE){ + if (value_kind == ICAL_NO_VALUE){ - /* Ooops, could not parse the value of the - parameter ( it was not one of the defined - values ), so reset the value_kind */ + /* Ooops, could not parse the value of the + parameter ( it was not one of the defined + values ), so reset the value_kind */ - icalcomponent* tail - = pvl_data(pvl_tail(components)); + insert_error( + tail, str, + "Got a VALUE parameter with an unknown type", + ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR); + icalparameter_free(param); - insert_error( - tail, str, - "Got a VALUE parameter with an unknown type", - ICAL_XLICERRORTYPE_PARAMETERPARSEERROR); - icalparameter_free(param); + value_kind = + icalenum_property_kind_to_value_kind( + icalproperty_isa(prop)); - value_kind = - icalenum_property_kind_to_value_kind( - icalproperty_isa(prop)); - - icalparameter_free(param); - tail = 0; - continue; - } - } + icalparameter_free(param); + tail = 0; + impl->state = ICALPARSER_ERROR; + return 0; + } + } - /* Everything is OK, so add the parameter */ - icalproperty_add_parameter(prop,param); - tail = 0; + /* Everything is OK, so add the parameter */ + icalproperty_add_parameter(prop,param); + tail = 0; - } else { - /* If we did not get a param string, go on to looking - for a value */ - break; - } - } + } else { /* if ( str != 0) */ + /* If we did not get a param string, go on to looking + for a value */ + break; + } /* if ( str != 0) */ + + } /* while(1) */ -/********************************************************************** - * Handle values - **********************************************************************/ + /********************************************************************** + * Handle values + **********************************************************************/ - /* Look for values. If there are ',' characters in the values, - then there are multiple values, so clone the current - parameter and add one part of the value to each clone */ + /* Look for values. If there are ',' characters in the values, + then there are multiple values, so clone the current + parameter and add one part of the value to each clone */ - vcount=0; - while(1) { - str = icalparser_get_next_value(end,&end, value_kind); + vcount=0; + while(1) { + str = icalparser_get_next_value(end,&end, value_kind); - if (str != 0){ + if (str != 0){ - if (vcount > 0){ - /* Actually, only clone after the second value */ - icalproperty* clone = icalproperty_new_clone(prop); - tail = pvl_data(pvl_tail(components)); + if (vcount > 0){ + /* Actually, only clone after the second value */ + icalproperty* clone = icalproperty_new_clone(prop); + icalcomponent* tail = pvl_data(pvl_tail(impl->components)); - icalcomponent_add_property(tail, clone); - prop = clone; - tail = 0; - } + icalcomponent_add_property(tail, clone); + prop = clone; + tail = 0; + } - value = icalvalue_new_from_string(value_kind, str); + value = icalvalue_new_from_string(value_kind, str); - /* Don't add properties without value */ - if (value == 0){ - char temp[1024]; + /* Don't add properties without value */ + if (value == 0){ + char temp[200]; /* HACK */ - icalproperty_kind prop_kind = icalproperty_isa(prop); - tail = pvl_data(pvl_tail(components)); + icalproperty_kind prop_kind = icalproperty_isa(prop); + icalcomponent* tail = pvl_data(pvl_tail(impl->components)); - sprintf(temp,"Can't parse as %s value in %s property. Removing entire property", - icalenum_value_kind_to_string(value_kind), - icalenum_property_kind_to_string(prop_kind)); + sprintf(temp,"Can't parse as %s value in %s property. Removing entire property", + icalenum_value_kind_to_string(value_kind), + icalenum_property_kind_to_string(prop_kind)); - insert_error(tail, str, temp, - ICAL_XLICERRORTYPE_VALUEPARSEERROR); + insert_error(tail, str, temp, + ICAL_XLICERRORTYPE_VALUEPARSEERROR); - /* Remove the troublesome property */ - icalcomponent_remove_property(tail,prop); - icalproperty_free(prop); - prop = 0; - tail = 0; - break; + /* Remove the troublesome property */ + icalcomponent_remove_property(tail,prop); + icalproperty_free(prop); + prop = 0; + tail = 0; + impl->state = ICALPARSER_ERROR; + return 0; - } else { - vcount++; - icalproperty_set_value(prop, value); - } + } else { + vcount++; + icalproperty_set_value(prop, value); + } - } else { + } else { + if (vcount == 0){ + char temp[200]; /* HACK */ + icalproperty_kind prop_kind = icalproperty_isa(prop); + icalcomponent *tail = pvl_data(pvl_tail(impl->components)); + + sprintf(temp,"No value for %s property. Removing entire property", + icalenum_property_kind_to_string(prop_kind)); + + insert_error(tail, str, temp, + ICAL_XLICERRORTYPE_VALUEPARSEERROR); + + /* Remove the troublesome property */ + icalcomponent_remove_property(tail,prop); + icalproperty_free(prop); + prop = 0; + tail = 0; + impl->state = ICALPARSER_ERROR; + return 0; + } else { + break; } } + } - } while( !feof(stdin) && line !=0 ); + /**************************************************************** + * End of component parsing. + *****************************************************************/ - - if (pvl_data(pvl_tail(components)) == 0){ - /* A nice, clean exit */ - pvl_free(components); - free(line); - return root_component; + if (pvl_data(pvl_tail(impl->components)) == 0 && + impl->level == 0){ + impl->state = ICALPARSER_SUCCESS; + return impl->root_component; + } else { + impl->state = ICALPARSER_IN_PROGRESS; + return 0; } - /* Clear off any component that may be left in the list */ - /* This will happen if some components did not have an "END" tag*/ +} + +icalparser_state icalparser_get_state(icalparser* parser) +{ + struct icalparser_impl* impl = (struct icalparser_impl*) parser; + return impl->state; + +} + +icalcomponent* icalparser_claim(icalparser* parser) +{ + struct icalparser_impl* impl = (struct icalparser_impl*) parser; + icalcomponent *c = impl->root_component; + + impl->root_component = 0; + + return c; + +} + + +icalcomponent* icalparser_clean(icalparser* parser) +{ + struct icalparser_impl* impl = (struct icalparser_impl*) parser; + icalcomponent *tail = pvl_data(pvl_tail(impl->components)); - while((tail=pvl_data(pvl_tail(components))) != 0){ + icalerror_check_arg_rz((parser != 0 ),"parser"); + + /* We won't get a clean exit if some components did not have an + "END" tag. Clear off any component that may be left in the list */ + + + while((tail=pvl_data(pvl_tail(impl->components))) != 0){ insert_error(tail," ", "Missing END tag for this component. Closing component at end of input.", ICAL_XLICERRORTYPE_COMPONENTPARSEERROR); - root_component = pvl_pop(components); - tail=pvl_data(pvl_tail(components)); + impl->root_component = pvl_pop(impl->components); + tail=pvl_data(pvl_tail(impl->components)); if(tail != 0){ - icalcomponent_add_component(tail,root_component); + icalcomponent_add_component(tail,impl->root_component); } } - free(line); - return root_component; + return impl->root_component; + } -char* string_line_generator_pos=0; -char* string_line_generator_str; +struct slg_data { + char* pos; + char* str; +}; + char* string_line_generator(char *out, size_t buf_size, void *d) { char *n; - - if(string_line_generator_pos==0){ - string_line_generator_pos=string_line_generator_str; + size_t size; + struct slg_data* data = (struct slg_data*)d; + + if(data->pos==0){ + data->pos=data->str; } /* If the pointer is at the end of the string, we are done */ - if (*string_line_generator_pos ==0){ + if (*(data->pos)==0){ return 0; } - n = strchr(string_line_generator_pos,'\n'); + n = strchr(data->pos,'\n'); - /* If no newline, take the rest of the string, and leave the - pointer at the \0 */ - - if (n == 0) { - n = string_line_generator_pos + strlen(string_line_generator_pos); + if (n == 0){ + size = strlen(data->pos); } else { - n++; + n++; /* include newline in output */ + size = (n-data->pos); } - strncpy(out,string_line_generator_pos,(n-string_line_generator_pos)); - - *(out+(n-string_line_generator_pos)) = '\0'; - - string_line_generator_pos = n; - - return out; + if (size > buf_size-1){ + size = buf_size-1; + } -} -void _test_string_line_generator(char* str) -{ - char *line; - int lineno=0; - string_line_generator_str = str; - string_line_generator_pos = 0; - - while((line = icalparser_get_line(string_line_generator,&lineno))){ - printf("#%d: %s\n",lineno,line); - } + strncpy(out,data->pos,size); + *(out+size) = '\0'; - string_line_generator_pos = 0; - string_line_generator_str = 0; -} - + data->pos += size; + return out; +} icalcomponent* icalparser_parse_string(char* str) { - icalcomponent *c; - - string_line_generator_str = str; - string_line_generator_pos = 0; - c = icalparser_parse(string_line_generator); - string_line_generator_pos = 0; - string_line_generator_str = 0; - + struct slg_data d; + icalparser *p; + + d.pos = 0; + d.str = str; + + p = icalparser_new(); + icalparser_set_gen_data(p,&d); + c = icalparser_parse(p,string_line_generator); + icalparser_free(p); + return c; } diff --git a/libical/src/libical/icalparser.h b/libical/src/libical/icalparser.h index 9e47e38bfb..25c07eca9f 100644 --- a/libical/src/libical/icalparser.h +++ b/libical/src/libical/icalparser.h @@ -31,6 +31,16 @@ #include "ical.h" #include <stdio.h> /* For FILE* */ +typedef void* icalparser; +typedef enum icalparser_state { + ICALPARSER_ERROR, + ICALPARSER_SUCCESS, + ICALPARSER_BEGIN_COMP, + ICALPARSER_END_COMP, + ICALPARSER_IN_PROGRESS +} icalparser_state; + + /*********************************************************************** * Message oriented parsing. icalparser_parse takes a string that * holds the text ( in RFC 2445 format ) and returns a pointer to an @@ -38,29 +48,28 @@ * pointer to a function that returns one content line per invocation **********************************************************************/ -icalcomponent* icalparser_parse(char* (*line_gen_func)()); +icalcomponent* icalparser_parse(icalparser *parser, + char* (*line_gen_func)(char *s, size_t size, void *d)); -/* Parse directly from a string */ +/* A simple, and incorrect interface - can only return one component*/ icalcomponent* icalparser_parse_string(char* str); -/* icalparser_flex_input is the routine that is called from the macro - YYINPUT in the flex lexer. */ -int icalparser_flex_input(char* buf, int max_size); -void icalparser_clear_flex_input(); /*********************************************************************** * Line-oriented parsing. * * Create a new parser via icalparse_new_parser, then add ines one at - * a time with icalparse_add_line(). After adding the last line, call - * icalparse_close() to return the parsed component. + * a time with icalparse_add_line(). icalparser_add_line() will return + * non-zero when it has finished with a component. ***********************************************************************/ -/* These are not implemented yet */ -typedef void* icalparser; -icalparser icalparse_new_parser(); -void icalparse_add_line(icalparser* parser ); -icalcomponent* icalparse_close(icalparser* parser); +icalparser* icalparser_new(); +void icalparser_set_gen_data(icalparser* parser, void* data); +icalcomponent* icalparser_add_line(icalparser* parser, char* str ); +icalcomponent* icalparser_claim(icalparser* parser); +icalcomponent* icalparser_clean(icalparser* parser); +icalparser_state icalparser_get_state(icalparser* parser); +void icalparser_free(icalparser* parser); /*********************************************************************** * Parser support functions @@ -69,11 +78,17 @@ icalcomponent* icalparse_close(icalparser* parser); /* Use the flex/bison parser to turn a string into a value type */ icalvalue* icalparser_parse_value(icalvalue_kind kind, char* str, icalcomponent** errors); -char* icalparser_get_line(char* (*line_gen_func)(char *s, size_t size, void *d), int *lineno); - +/* Given a line generator function, return a single iCal content line.*/ +char* icalparser_get_line(icalparser* parser, char* (*line_gen_func)(char *s, size_t size, void *d)); -/* a line_gen_function that returns lines from a string */ +/* a line_gen_function that returns lines from a string. To use it, + set string_line_generator_str to point to the input string, and set + string_line_generator_pos to 0. These globals make the routine not + thead-safe. */ +extern char* string_line_generator_str; +extern char* string_line_generator_pos; +char* string_line_generator(char *out, size_t buf_size, void *d); #endif /* !ICALPARSE_H */ diff --git a/libical/src/libical/icalproperty.c b/libical/src/libical/icalproperty.c index 3dd761b1f8..c3fe7c9073 100644 --- a/libical/src/libical/icalproperty.c +++ b/libical/src/libical/icalproperty.c @@ -25,6 +25,10 @@ ======================================================================*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <string.h> /* For strdup, rindex */ #include <assert.h> #include <stdlib.h> @@ -38,6 +42,8 @@ #include "icalerror.h" #include "icalmemory.h" +#define TMP_BUF_SIZE 1024 + /* Private routines for icalproperty */ void icalvalue_set_parent(icalvalue* value, icalproperty* property); @@ -89,7 +95,6 @@ icalproperty_new_impl (icalproperty_kind kind) if ( ( prop = (struct icalproperty_impl*) malloc(sizeof(struct icalproperty_impl))) == 0) { - errno = ENOMEM; icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } @@ -196,7 +201,7 @@ icalproperty_free (icalproperty* prop) icalparameter* param; - icalerror_check_arg_re((prop!=0),"prop",ICAL_BADARG_ERROR); + icalerror_check_arg_rv((prop!=0),"prop"); p = (struct icalproperty_impl*)prop; @@ -254,6 +259,12 @@ icalproperty_as_ical_string (icalproperty* prop) icalvalue* value; char *out_buf; +#ifdef ICAL_UNIX_NEWLINE + char newline[] = "\n"; +#else + char newline[] = "\r\n"; +#endif + struct icalproperty_impl *impl = (struct icalproperty_impl*)prop; icalerror_check_arg_rz( (prop!=0),"prop"); @@ -275,7 +286,7 @@ icalproperty_as_ical_string (icalproperty* prop) icalmemory_append_string(&buf, &buf_ptr, &buf_size, property_name); - icalmemory_append_string(&buf, &buf_ptr, &buf_size, "\n"); + icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); /* Append parameters */ for(param = icalproperty_get_first_parameter(prop,ICAL_ANY_PARAMETER); @@ -285,15 +296,15 @@ icalproperty_as_ical_string (icalproperty* prop) char* kind_string = icalparameter_as_ical_string(param); if (kind_string == 0 ) { - char temp[1024]; - sprintf(temp, "Got a parameter of unknown kind in %s property",property_name); + char temp[TMP_BUF_SIZE]; + snprintf(temp, TMP_BUF_SIZE,"Got a parameter of unknown kind in %s property",property_name); icalerror_warn(temp); continue; } icalmemory_append_string(&buf, &buf_ptr, &buf_size, " ;"); icalmemory_append_string(&buf, &buf_ptr, &buf_size, kind_string); - icalmemory_append_string(&buf, &buf_ptr, &buf_size, "\n"); + icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); } @@ -311,7 +322,7 @@ icalproperty_as_ical_string (icalproperty* prop) } - icalmemory_append_string(&buf, &buf_ptr, &buf_size, "\n"); + icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); /* Now, copy the buffer to a tmp_buffer, which is safe to give to the caller without worring about de-allocating it. */ @@ -1740,7 +1751,7 @@ void icalproperty_set_requeststatus(icalproperty* prop, char* v) icalerror_check_arg_rv( (prop!=0),"prop"); - value = icalvalue_new_text(v); + value = icalvalue_new_string(v); icalproperty_set_value(prop,value); @@ -1753,7 +1764,7 @@ char* icalproperty_get_requeststatus(icalproperty* prop) value = icalproperty_get_value(prop); - return icalvalue_get_text(value); + return icalvalue_get_string(value); } /* EXDATE */ diff --git a/libical/src/libical/icalrestriction.c b/libical/src/libical/icalrestriction.c index 9393b3ea34..d5ffb784ef 100644 --- a/libical/src/libical/icalrestriction.c +++ b/libical/src/libical/icalrestriction.c @@ -18,9 +18,15 @@ ======================================================================*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "icalenums.h" #include "icalrestriction.h" +#define TMP_BUF_SIZE 1024 + /* Define the structs for the restrictions. these data are filled out in machine generated code below */ @@ -48,7 +54,9 @@ icalrestriction_property_record icalrestriction_property_records[]; /* The each row gives the result of comparing a restriction against a count. The columns in each row represent 0,1,2+. '-1' indicates - 'invalid, 'don't care' or 'needs more analysis' */ + 'invalid, 'don't care' or 'needs more analysis' So, for + ICAL_RESTRICTION_ONE, if there is 1 of a property with that + restriction, it passes, but if there are 0 or 2+, it fails. */ char compare_map[ICAL_RESTRICTION_UNKNOWN+1][3] = { { 1, 1, 1},/*ICAL_RESTRICTION_NONE*/ @@ -129,9 +137,9 @@ int icalrestriction_check_component(icalproperty_method method, if (compare == 0){ - char temp[1024]; + char temp[TMP_BUF_SIZE]; - sprintf(temp, "Failed iTIP restrictions for property %s. Expected %s instances of the property and got %d", + snprintf(temp, TMP_BUF_SIZE,"Failed iTIP restrictions for property %s. Expected %s instances of the property and got %d", icalenum_property_kind_to_string(kind), restr_string_map[restr], count); diff --git a/libical/src/libical/icaltypes.c b/libical/src/libical/icaltypes.c index 14daa2915d..2800b4857f 100644 --- a/libical/src/libical/icaltypes.c +++ b/libical/src/libical/icaltypes.c @@ -24,15 +24,21 @@ The original code is icaltypes.c ======================================================================*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include "icaltypes.h" #include "icalerror.h" +#include "icalmemory.h" #include <stdlib.h> /* for malloc */ #include <errno.h> /* for errno */ #include <string.h> /* for strdup */ #include <assert.h> #include <limits.h> /* for SHRT_MAX */ +#define TEMP_MAX 1024 + void* icalattachtype_get_data (struct icalattachtype* type); @@ -198,3 +204,83 @@ void icalrecurrencetype_clear(struct icalrecurrencetype *recur) recur->until.year = 0; recur->count = 0; } + + +struct icalreqstattype icalreqstattype_from_string(char* str) +{ + char *p1,*p2; + size_t len; + struct icalreqstattype stat; + int major, minor; + + icalerror_check_arg((str != 0),"str"); + + stat.code = ICAL_UNKNOWN_STATUS; + stat.debug = 0; + + stat.desc = 0; + + /* Get the status numbers */ + + sscanf(str, "%d.%d",&major, &minor); + + if (major <= 0 || minor < 0){ + icalerror_set_errno(ICAL_BADARG_ERROR); + return stat; + } + + stat.code = icalenum_num_to_reqstat(major, minor); + + if (stat.code == ICAL_UNKNOWN_STATUS){ + icalerror_set_errno(ICAL_BADARG_ERROR); + return stat; + } + + + p1 = strchr(str,';'); + + if (p1 == 0){ + icalerror_set_errno(ICAL_BADARG_ERROR); + return stat; + } + + /* Just ignore the second clause; it will be taken from inside the library + */ + + + + p2 = strchr(p1+1,';'); + if (p2 != 0 && *p2 != 0){ + stat.debug = p2+1; + } + + return stat; + +} + +char* icalreqstattype_as_string(struct icalreqstattype stat) +{ + char format[20]; + char *temp; + + temp = (char*)icalmemory_tmp_buffer(TEMP_MAX); + + icalerror_check_arg_rz((stat.code != ICAL_UNKNOWN_STATUS),"Status"); + + if (stat.desc == 0){ + stat.desc = icalenum_reqstat_desc(stat.code); + } + + if(stat.debug != 0){ + snprintf(temp,TEMP_MAX,"%d.%d;%s;%s", icalenum_reqstat_major(stat.code), + icalenum_reqstat_minor(stat.code), + stat.desc, stat.debug); + + } else { + snprintf(temp,TEMP_MAX,"%d.%d;%s", icalenum_reqstat_major(stat.code), + icalenum_reqstat_minor(stat.code), + stat.desc); + } + + return temp; +} diff --git a/libical/src/libical/icaltypes.h b/libical/src/libical/icaltypes.h index c33e8acd7d..77a67fae80 100644 --- a/libical/src/libical/icaltypes.h +++ b/libical/src/libical/icaltypes.h @@ -157,12 +157,26 @@ union icaltriggertype struct icaldurationtype duration; }; -struct icalrequestsstatustype { - short minor; - short major; +/* struct icalreqstattype. This struct contains two string pointers, +but don't try to free either of them. The "desc" string is a pointer +to a static table inside the library. Don't try to free it. The +"debug" string is a pointer into the string that the called passed +into to icalreqstattype_from_string. Don't try to free it either, and +don't use it after the original string has been freed. +BTW, you would get that original string from +*icalproperty_get_requeststatus() or icalvalue_get_text(), when +operating on a the value of a request_status property. */ + +struct icalreqstattype { + + icalrequeststatus code; + char* desc; + char* debug; }; +struct icalreqstattype icalreqstattype_from_string(char* str); +char* icalreqstattype_as_string(struct icalreqstattype); #endif /* !ICALTYPES_H */ diff --git a/libical/src/libical/icalvalue.c b/libical/src/libical/icalvalue.c index 1ed83a0c6e..ec332a0f04 100644 --- a/libical/src/libical/icalvalue.c +++ b/libical/src/libical/icalvalue.c @@ -28,6 +28,10 @@ ======================================================================*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "ical.h" #include "icalerror.h" @@ -38,6 +42,7 @@ #include <stdlib.h> /* for malloc */ #include <stdio.h> /* for sprintf */ #include <string.h> /* For memset, others */ +#include <stddef.h> /* For offsetof() macro */ #include <errno.h> #include <time.h> /* for mktime */ #include <stdlib.h> /* for atoi and atof */ @@ -47,6 +52,8 @@ #include "strdup.h" #endif +#define TMP_BUF_SIZE 1024 + void print_datetime_to_string(char* str, struct icaltimetype *data); void print_date_to_string(char* str, struct icaltimetype *data); void print_time_to_string(char* str, struct icaltimetype *data); @@ -97,7 +104,6 @@ struct icalvalue_impl* icalvalue_new_impl(icalvalue_kind kind){ if ( ( v = (struct icalvalue_impl*) malloc(sizeof(struct icalvalue_impl))) == 0) { - errno = ENOMEM; icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } @@ -147,6 +153,7 @@ icalvalue* icalvalue_new_clone(icalvalue* value){ /* HACK ugh. I don't feel like impleenting this */ } + case ICAL_STRING_VALUE: case ICAL_TEXT_VALUE: case ICAL_CALADDRESS_VALUE: case ICAL_URI_VALUE: @@ -207,7 +214,7 @@ icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind,char* str,ic value = 0; if (error != 0){ - char temp[1024]; + char temp[TMP_BUF_SIZE]; sprintf(temp,"ATTACH Values are not implemented"); *error = icalproperty_vanew_xlicerror( temp, @@ -226,7 +233,7 @@ icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind,char* str,ic value = 0; if (error != 0){ - char temp[1024]; + char temp[TMP_BUF_SIZE]; sprintf(temp,"BINARY Values are not implemented"); *error = icalproperty_vanew_xlicerror( temp, @@ -245,7 +252,7 @@ icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind,char* str,ic value = 0; if (error != 0){ - char temp[1024]; + char temp[TMP_BUF_SIZE]; sprintf(temp,"BOOLEAN Values are not implemented"); *error = icalproperty_vanew_xlicerror( temp, @@ -282,6 +289,13 @@ icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind,char* str,ic break; } + + case ICAL_STRING_VALUE: + { + value = icalvalue_new_string(str); + break; + } + case ICAL_CALADDRESS_VALUE: { value = icalvalue_new_caladdress(str); @@ -298,6 +312,8 @@ icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind,char* str,ic { icalproperty_method method = icalenum_string_to_method(str); value = icalvalue_new_method(method); + break; + } case ICAL_GEO_VALUE: { @@ -305,7 +321,7 @@ icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind,char* str,ic /* HACK */ if (error != 0){ - char temp[1024]; + char temp[TMP_BUF_SIZE]; sprintf(temp,"GEO Values are not implemented"); *error = icalproperty_vanew_xlicerror( temp, @@ -337,15 +353,10 @@ icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind,char* str,ic { if (error != 0 ){ - char temp[1024]; + char temp[TMP_BUF_SIZE]; - if (strlen(str) > 265) { - sprintf(temp,"Unknown type for \'%256s...\'",str); - } else { - sprintf(temp,"Unknown type for \'%s\'",str); + snprintf(temp,TMP_BUF_SIZE,"Unknown type for \'%s\'",str); - } - *error = icalproperty_vanew_xlicerror( temp, icalparameter_new_xlicerrortype( @@ -360,14 +371,9 @@ icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind,char* str,ic if (error != 0 && *error == 0 && value == 0){ - char temp[1024]; + char temp[TMP_BUF_SIZE]; - if (strlen(str) > 265) { - sprintf(temp,"Failed to parse value: \'%256s...\'",str); - } else { - sprintf(temp,"Failed to parse value: \'%s\'",str); - - } + snprintf(temp,TMP_BUF_SIZE,"Failed to parse value: \'%s\'",str); *error = icalproperty_vanew_xlicerror( temp, @@ -529,20 +535,22 @@ char* icalvalue_recur_as_ical_string(icalvalue* value) struct icalvalue_impl *impl = (struct icalvalue_impl*)value; struct icalrecurrencetype *recur = impl->data.v_recur; - struct { char* str; short* array; short limit; } map[] = - { - {";BYSECOND=",recur->by_second,60}, - {";BYMINUTE=",recur->by_minute,60}, - {";BYHOUR=",recur->by_hour,24}, - {";BYDAY=",recur->by_day,7}, - {";BYMONTHDAY=",recur->by_month_day,31}, - {";BYYEARDAY=",recur->by_year_day,366}, - {";BYWEEKNO=",recur->by_week_no,52}, - {";BYMONTH=",recur->by_month,12}, - {";BYSETPOS=",recur->by_set_pos,366}, - {0,0,0}, - }; - + struct { char* str;size_t offset; short limit; } recurmap[] = + { + {";BYSECOND=",offsetof(struct icalrecurrencetype,by_second),60}, + {";BYMINUTE=",offsetof(struct icalrecurrencetype,by_minute),60}, + {";BYHOUR=",offsetof(struct icalrecurrencetype,by_hour),24}, + {";BYDAY=",offsetof(struct icalrecurrencetype,by_day),7}, + {";BYMONTHDAY=",offsetof(struct icalrecurrencetype,by_month_day),31}, + {";BYYEARDAY=",offsetof(struct icalrecurrencetype,by_year_day),366}, + {";BYWEEKNO=",offsetof(struct icalrecurrencetype,by_week_no),52}, + {";BYMONTH=",offsetof(struct icalrecurrencetype,by_month),12}, + {";BYSETPOS=",offsetof(struct icalrecurrencetype,by_set_pos),366}, + {0,0,0}, + }; + + + icalerror_check_arg_rz((value != 0),"value"); if(recur->freq == ICAL_NO_RECURRENCE){ @@ -577,14 +585,14 @@ char* icalvalue_recur_as_ical_string(icalvalue* value) icalmemory_append_string(&str,&str_p,&buf_sz, temp); } - for(j =0; map[j].str != 0; j++){ - short* array = map[j].array; - short limit = map[j].limit; + for(j =0; recurmap[j].str != 0; j++){ + short* array = (short*)(recurmap[j].offset+ (size_t)recur); + short limit = recurmap[j].limit; /* Skip unused arrays */ if( array[0] != ICAL_RECURRENCE_ARRAY_MAX ) { - icalmemory_append_string(&str,&str_p,&buf_sz,map[j].str); + icalmemory_append_string(&str,&str_p,&buf_sz,recurmap[j].str); for(i=0; i< limit && array[i] != ICAL_RECURRENCE_ARRAY_MAX; i++){ @@ -731,11 +739,11 @@ char* icalvalue_attach_as_ical_string(icalvalue* value) { void append_duration_segment(char** buf, char** buf_ptr, size_t* buf_size, char* sep, unsigned int value) { - char digits[256]; /* HACK: large hardcoded limit */ + char temp[TMP_BUF_SIZE]; - sprintf(digits,"%d",value); + sprintf(temp,"%d",value); - icalmemory_append_string(buf, buf_ptr, buf_size, digits); + icalmemory_append_string(buf, buf_ptr, buf_size, temp); icalmemory_append_string(buf, buf_ptr, buf_size, sep); } @@ -1025,6 +1033,7 @@ icalvalue_as_ical_string (icalvalue* value) case ICAL_TEXT_VALUE: return icalvalue_text_as_ical_string(value); + case ICAL_STRING_VALUE: case ICAL_URI_VALUE: case ICAL_CALADDRESS_VALUE: return icalvalue_string_as_ical_string(value); @@ -1155,7 +1164,7 @@ icalvalue_compare(icalvalue* a, icalvalue *b) case ICAL_DATE_VALUE: case ICAL_DATETIME_VALUE: case ICAL_DATETIMEDATE_VALUE: - case ICAL_DURATION_VALUE: + case ICAL_DURATION_VALUE: /* HACK. Not correct for DURATION */ case ICAL_TIME_VALUE: case ICAL_DATETIMEPERIOD_VALUE: { @@ -1216,7 +1225,9 @@ icalproperty* icalvalue_get_parent(icalvalue* value) -/* Recur is a special case, so it is not auto generated */ +/* Recur is a special case, so it is not auto generated. Well, + actually, it is auto-generated, but you will have to manually + remove the auto-generated version after each generation. */ icalvalue* icalvalue_new_recur (struct icalrecurrencetype v) { @@ -1762,89 +1773,74 @@ icalvalue_get_period(icalvalue* value) icalvalue* -icalvalue_new_text (char* v) +icalvalue_new_string (char* v) { - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_TEXT_VALUE); + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_STRING_VALUE); icalerror_check_arg_rz( (v!=0),"v"); - icalvalue_set_text((icalvalue*)impl,v); + icalvalue_set_string((icalvalue*)impl,v); return (icalvalue*)impl; } void -icalvalue_set_text(icalvalue* value, char* v) +icalvalue_set_string(icalvalue* value, char* v) { struct icalvalue_impl* impl; - char *p,*d; - + icalerror_check_arg_rv( (value!=0),"value"); icalerror_check_arg_rv( (v!=0),"v"); - icalerror_check_value_type(value, ICAL_TEXT_VALUE); + icalerror_check_value_type(value, ICAL_STRING_VALUE); impl = (struct icalvalue_impl*)value; - impl->data.v_string = malloc(strlen(v)+1); + impl->data.v_string = strdup(v); if (impl->data.v_string == 0){ errno = ENOMEM; - return; } - for(d=impl->data.v_string,p=v; *p!=0; p++){ +} - if (*p == '\\') { - p++; +char* +icalvalue_get_string(icalvalue* value) +{ + icalerror_check_arg( (value!=0),"value"); + icalerror_check_value_type(value, ICAL_STRING_VALUE); + + return ((struct icalvalue_impl*)value)->data.v_string; +} - if (p == 0){ - break; - } - switch(*p){ - case 'n': { - *d='\n';d++; - break; - } +icalvalue* +icalvalue_new_text (char* v) +{ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_TEXT_VALUE); + + icalerror_check_arg_rz( (v!=0),"v"); - case '\\': { - *d='\\';d++; - break; - } - - case 't': { - *d='\n';d++; - break; - } - case 'r': { - *d='\r';d++; - break; - } - case 'b': { - *d='\b';d++; - break; - } - case 'f': { - *d='\f';d++; - break; - } - - case ';': - case ',':{ - *d=*p;d++; - break; - } + icalvalue_set_text((icalvalue*)impl,v); - case '"':{ - *d='\"';d++; - break; - } - } - } else { - *d=*p;d++; - } + return (icalvalue*)impl; +} + +void +icalvalue_set_text(icalvalue* value, char* v) +{ + struct icalvalue_impl* impl; + + icalerror_check_arg_rv( (value!=0),"value"); + icalerror_check_arg_rv( (v!=0),"v"); + + icalerror_check_value_type(value, ICAL_TEXT_VALUE); + + impl = (struct icalvalue_impl*)value; + impl->data.v_string = strdup(v); + + if (impl->data.v_string == 0){ + errno = ENOMEM; } - *d='\0'; } diff --git a/libical/src/libical/icalvalue.h b/libical/src/libical/icalvalue.h index b5a2e6da9e..ec7457d6aa 100644 --- a/libical/src/libical/icalvalue.h +++ b/libical/src/libical/icalvalue.h @@ -131,6 +131,11 @@ icalvalue* icalvalue_new_recur(struct icalrecurrencetype v); struct icalrecurrencetype icalvalue_get_recur(icalvalue* value); void icalvalue_set_recur(icalvalue* value, struct icalrecurrencetype v); +/* STRING # Non-std */ +icalvalue* icalvalue_new_string(char* v); +char* icalvalue_get_string(icalvalue* value); +void icalvalue_set_string(icalvalue* value, char* v); + /* TEXT */ icalvalue* icalvalue_new_text(char* v); char* icalvalue_get_text(icalvalue* value); diff --git a/libical/src/libical/icalversion.h b/libical/src/libical/icalversion.h new file mode 100644 index 0000000000..3d5f132a3f --- /dev/null +++ b/libical/src/libical/icalversion.h @@ -0,0 +1,3 @@ + +#define ICAL_PACKAGE "libical" +#define ICAL_VERSION "0.16" diff --git a/libical/src/libical/icalversion.h.in b/libical/src/libical/icalversion.h.in new file mode 100644 index 0000000000..aaeeed6666 --- /dev/null +++ b/libical/src/libical/icalversion.h.in @@ -0,0 +1,3 @@ + +#define ICAL_PACKAGE "@PACKAGE@" +#define ICAL_VERSION "@VERSION@" diff --git a/libical/src/libical/icalyacc.y b/libical/src/libical/icalyacc.y new file mode 100644 index 0000000000..63fff212a2 --- /dev/null +++ b/libical/src/libical/icalyacc.y @@ -0,0 +1,480 @@ +%{ +/* -*- Mode: C -*- + ====================================================================== + FILE: icalitip.y + CREATOR: eric 10 June 1999 + + DESCRIPTION: + + $Id: icalyacc.y,v 1.1 2000/04/18 18:17:05 alves Exp $ + $Locker: $ + + (C) COPYRIGHT 1999 Eric Busboom + http://www.softwarestudio.org + + The contents of this file are subject to the Mozilla Public License + Version 1.0 (the "License"); you may not use this file except in + compliance with the License. You may obtain a copy of the License at + http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and + limitations under the License. + + The original author is Eric Busboom + The original code is icalitip.y + + + + ================================b======================================*/ + +#include <stdlib.h> +#include <string.h> /* for strdup() */ +#include <limits.h> /* for SHRT_MAX*/ +#include "icalparser.h" +#include "ical.h" +#include "pvl.h" +#define YYERROR_VERBOSE +#define YYDEBUG 1 + + +icalvalue *icalparser_yy_value; /* Current Value */ + +/* Globals for UTCOFFSET values */ +int utc; +int utc_b; +int utcsign; + +/* Globals for DURATION values */ +struct icaldurationtype duration; + +/* Globals for RECUR values */ +struct icalrecurrencetype recur; +short skiplist[367]; +short skippos; + +void copy_list(short* array, size_t size); +void clear_recur(); +void add_prop(icalproperty_kind); +void icalparser_fill_date(struct tm* t, char* dstr); +void icalparser_fill_time(struct tm* t, char* tstr); +void set_value_type(icalvalue_kind kind); +void set_parser_value_state(); +struct icaltimetype fill_datetime(char* d, char* t); +void ical_yy_error(char *s); /* Don't know why I need this.... */ +/*int yylex(void); /* Or this. */ + + + +/* Set the state of the lexer so it will interpret values ( iCAL + VALUEs, that is, ) correctly. */ + +%} + +%union { + float v_float; + int v_int; + char* v_string; + + /* Renaming hack */ +#define yymaxdepth ical_yy_maxdepth +#define yyparse ical_yy_parse +#define yylex ical_yy_lex +#define yyerror ical_yy_error +#define yylval ical_yy_lval +#define yychar ical_yy_char +#define yydebug ical_yy_debug +#define yypact ical_yy_pact +#define yyr1 ical_yy_r1 +#define yyr2 ical_yy_r2 +#define yydef ical_yy_def +#define yychk ical_yy_chk +#define yypgo ical_yy_pgo +#define yyact ical_yy_act +#define yyexca ical_yy_exca +#define yyerrflag ical_yy_errflag +#define yynerrs ical_yy_nerrs +#define yyps ical_yy_ps +#define yypv ical_yy_pv +#define yys ical_yy_s +#define yy_yys ical_yy_yys +#define yystate ical_yy_state +#define yytmp ical_yy_tmp +#define yyv ical_yy_v +#define yy_yyv ical_yy_yyv +#define yyval ical_yy_val +#define yylloc ical_yy_lloc +#define yyreds ical_yy_reds +#define yytoks ical_yy_toks +#define yylhs ical_yy_yylhs +#define yylen ical_yy_yylen +#define yydefred ical_yy_yydefred +#define yydgoto ical_yy_yydgoto +#define yydefred ical_yy_yydefred +#define yydgoto ical_yy_yydgoto +#define yysindex ical_yy_yysindex +#define yyrindex ical_yy_yyrindex +#define yygindex ical_yy_yygindex +#define yytable ical_yy_yytable +#define yycheck ical_yy_yycheck +#define yyname ical_yy_yyname +#define yyrule ical_yy_yyrule + + + +} + +%token <v_string> DIGITS +%token <v_int> INTNUMBER +%token <v_float> FLOATNUMBER +%token <v_string> STRING +%token EOL EQUALS CHARACTER COLON COMMA SEMICOLON TIMESEPERATOR + +%token TRUE FALSE + +%token FREQ BYDAY BYHOUR BYMINUTE BYMONTH BYMONTHDAY BYSECOND BYSETPOS BYWEEKNO +%token BYYEARDAY DAILY MINUTELY MONTHLY SECONDLY WEEKLY HOURLY YEARLY +%token INTERVAL COUNT UNTIL WKST MO SA SU TU WE TH FR + +%token BIT8 ACCEPTED ADD AUDIO BASE64 BINARY BOOLEAN BUSY BUSYTENTATIVE +%token BUSYUNAVAILABLE CALADDRESS CANCEL CANCELLED CHAIR CHILD COMPLETED +%token CONFIDENTIAL CONFIRMED COUNTER DATE DATETIME DECLINECOUNTER DECLINED +%token DELEGATED DISPLAY DRAFT DURATION EMAIL END FINAL FLOAT FREE GREGORIAN +%token GROUP INDIVIDUAL INPROCESS INTEGER NEEDSACTION NONPARTICIPANT +%token OPAQUE OPTPARTICIPANT PARENT PERIOD PRIVATE PROCEDURE PUBLIC PUBLISH +%token RECUR REFRESH REPLY REQPARTICIPANT REQUEST RESOURCE ROOM SIBLING +%token START TENTATIVE TEXT THISANDFUTURE THISANDPRIOR TIME TRANSPAENT +%token UNKNOWN UTCOFFSET XNAME + +%token ALTREP CN CUTYPE DAYLIGHT DIR ENCODING EVENT FBTYPE FMTTYPE LANGUAGE +%token MEMBER PARTSTAT RANGE RELATED RELTYPE ROLE RSVP SENTBY STANDARD URI + +%token TIME_CHAR UTC_CHAR + + +%% + +value: + binary_value + | boolean_value + | date_value + | datetime_value + | duration_value + | period_value + | recur_value + | utcoffset_value + | error { + icalparser_yy_value = 0; + icalparser_clear_flex_input(); + yyclearin; + } + +binary_value: "unimplemented2" + +boolean_value: + TRUE + { icalparser_yy_value = icalvalue_new_boolean(1); } + | FALSE + { icalparser_yy_value = icalvalue_new_boolean(0); } + +date_value: DIGITS + { + struct icaltimetype stm; + + stm = fill_datetime($1,0); + + stm.hour = -1; + stm.minute = -1; + stm.second = -1; + stm.is_utc = 0; + stm.is_date = 1; + + icalparser_yy_value = icalvalue_new_date(stm); + } + +utc_char: + /*empty*/ {utc = 0;} + | UTC_CHAR {utc = 1;} + +/* This is used in the period_value, where there may be two utc characters per rule. */ +utc_char_b: + /*empty*/ {utc_b = 0;} + | UTC_CHAR {utc_b = 1;} + +datetime_value: + DIGITS TIME_CHAR DIGITS utc_char + { + struct icaltimetype stm; + stm = fill_datetime($1, $3); + stm.is_utc = utc; + stm.is_date = 0; + + icalparser_yy_value = + icalvalue_new_datetime(stm); + } + + +/* Duration */ + + +dur_date: dur_day + | dur_day dur_time + +dur_week: DIGITS 'W' + { + duration.weeks = atoi($1); + } + +dur_time: TIME_CHAR dur_hour + { + } + | TIME_CHAR dur_minute + { + } + | TIME_CHAR dur_second + { + } + +dur_hour: DIGITS 'H' + { + duration.hours = atoi($1); + } + | DIGITS 'H' dur_minute + { + duration.hours = atoi($1); + } + +dur_minute: DIGITS 'M' + { + duration.minutes = atoi($1); + } + | DIGITS 'M' dur_second + { + duration.minutes = atoi($1); + } + +dur_second: DIGITS 'S' + { + duration.seconds = atoi($1); + } + +dur_day: DIGITS 'D' + { + duration.days = atoi($1); + } + +dur_prefix: /* empty */ + { + } + | '+' + { + } + | '-' + { + } + +duration_value: dur_prefix 'P' dur_date + { + icalparser_yy_value = icalvalue_new_duration(duration); + memset(&duration,0, sizeof(duration)); + } + | dur_prefix 'P' dur_time + { + icalparser_yy_value = icalvalue_new_duration(duration); + memset(&duration,0, sizeof(duration)); + } + | dur_prefix 'P' dur_week + { + icalparser_yy_value = icalvalue_new_duration(duration); + memset(&duration,0, sizeof(duration)); + } + + +/* Period */ + +period_value: DIGITS TIME_CHAR DIGITS utc_char '/' DIGITS TIME_CHAR DIGITS utc_char_b + { + struct icalperiodtype p; + + p.start = fill_datetime($1,$3); + p.start.is_utc = utc; + p.start.is_date = 0; + + + p.end = fill_datetime($6,$8); + p.end.is_utc = utc_b; + p.end.is_date = 0; + + p.duration.days = -1; + p.duration.weeks = -1; + p.duration.hours = -1; + p.duration.minutes = -1; + p.duration.seconds = -1; + + icalparser_yy_value = icalvalue_new_period(p); + } + | DIGITS TIME_CHAR DIGITS utc_char '/' duration_value + { + struct icalperiodtype p; + + p.start = fill_datetime($1,$3); + p.start.is_utc = utc; + p.start.is_date = 0; + + p.end.year = -1; + p.end.month = -1; + p.end.day = -1; + p.end.hour = -1; + p.end.minute = -1; + p.end.second = -1; + + /* The duration_value rule setes the global 'duration' + variable, but it also creates a new value in + icalparser_yy_value. So, free that, then copy + 'duration' into the icalperiodtype struct. */ + + p.duration = icalvalue_get_duration(icalparser_yy_value); + icalvalue_free(icalparser_yy_value); + icalparser_yy_value = 0; + + icalparser_yy_value = icalvalue_new_period(p); + + } + + + +/* Recur */ + +recur_start: + FREQ EQUALS SECONDLY {clear_recur();recur.freq = ICAL_SECONDLY_RECURRENCE;} + | FREQ EQUALS MINUTELY {clear_recur();recur.freq = ICAL_MINUTELY_RECURRENCE;} + | FREQ EQUALS HOURLY {clear_recur();recur.freq = ICAL_HOURLY_RECURRENCE;} + | FREQ EQUALS DAILY {clear_recur();recur.freq = ICAL_DAILY_RECURRENCE;} + | FREQ EQUALS WEEKLY {clear_recur();recur.freq = ICAL_WEEKLY_RECURRENCE;} + | FREQ EQUALS MONTHLY {clear_recur();recur.freq = ICAL_MONTHLY_RECURRENCE;} + | FREQ EQUALS YEARLY {clear_recur();recur.freq = ICAL_YEARLY_RECURRENCE;} + ; + + +weekday: + SU { skiplist[skippos]=ICAL_SUNDAY_WEEKDAY; if( skippos<8) skippos++;} + | MO { skiplist[skippos]=ICAL_MONDAY_WEEKDAY;if( skippos<8) skippos++;} + | TU { skiplist[skippos]=ICAL_TUESDAY_WEEKDAY;if( skippos<8) skippos++;} + | WE { skiplist[skippos]=ICAL_WEDNESDAY_WEEKDAY;if( skippos<8) skippos++;} + | TH { skiplist[skippos]=ICAL_THURSDAY_WEEKDAY;if( skippos<8) skippos++;} + | FR { skiplist[skippos]=ICAL_FRIDAY_WEEKDAY;if( skippos<8) skippos++;} + | SA { skiplist[skippos]=ICAL_SATURDAY_WEEKDAY;if( skippos<8) skippos++;} + ; + + +weekday_list: + weekday + | DIGITS weekday { } /* HACK Incorectly handles int in BYDAY */ + | weekday_list COMMA weekday + + +recur_list: + DIGITS { skiplist[skippos] = atoi($1); skippos++;} + | recur_list COMMA DIGITS { skiplist[skippos] = atoi($3); if (skippos<367) skippos++;} + ; + +recur_skip: + INTERVAL EQUALS DIGITS {recur.interval = atoi($3);} + | WKST EQUALS SU {recur.week_start = ICAL_SUNDAY_WEEKDAY;} + | WKST EQUALS MO {recur.week_start = ICAL_MONDAY_WEEKDAY;} + | WKST EQUALS TU {recur.week_start = ICAL_TUESDAY_WEEKDAY;} + | WKST EQUALS WE {recur.week_start = ICAL_WEDNESDAY_WEEKDAY;} + | WKST EQUALS TH {recur.week_start = ICAL_THURSDAY_WEEKDAY;} + | WKST EQUALS FR {recur.week_start = ICAL_FRIDAY_WEEKDAY;} + | WKST EQUALS SA {recur.week_start = ICAL_SATURDAY_WEEKDAY;} + | BYSECOND EQUALS recur_list{copy_list(recur.by_second,60);} + | BYMINUTE EQUALS recur_list{copy_list(recur.by_minute,60);} + | BYHOUR EQUALS recur_list{copy_list(recur.by_hour,24);} + | BYDAY EQUALS weekday_list{copy_list(recur.by_day,7);} + | BYMONTH EQUALS recur_list{copy_list(recur.by_month,12);} + | BYMONTHDAY EQUALS recur_list{copy_list(recur.by_month_day,31);} + | BYYEARDAY EQUALS recur_list{copy_list(recur.by_year_day,366);} + | BYWEEKNO EQUALS recur_list{copy_list(recur.by_week_no,53);} + | BYSETPOS EQUALS recur_list{copy_list(recur.by_set_pos,366);} + | UNTIL EQUALS datetime_value + { recur.until = icalvalue_get_datetime(icalparser_yy_value); + icalvalue_free(icalparser_yy_value); icalparser_yy_value=0;} + | UNTIL EQUALS date_value + { recur.until = icalvalue_get_date(icalparser_yy_value); + icalvalue_free(icalparser_yy_value); icalparser_yy_value=0;} + | COUNT EQUALS DIGITS + { recur.count = atoi($3); } + ; + +recur_skip_list: + /* empty */ + | recur_skip_list SEMICOLON recur_skip + +recur_value: + recur_start recur_skip_list + { icalparser_yy_value = icalvalue_new_recur(recur); } + + + +/* UTC Offset */ + +plusminus: '+' { utcsign = 1; } + | '-' { utcsign = -1; } + +utcoffset_value: + plusminus INTNUMBER INTNUMBER + { + icalparser_yy_value = icalvalue_new_utcoffset( utcsign * ($2*3600) + ($3*60) ); + } + + | plusminus INTNUMBER INTNUMBER INTNUMBER + { + icalparser_yy_value = icalvalue_new_utcoffset(utcsign * ($2*3600) + ($3*60) +($4)); + } + + + +%% + + +void clear_recur() +{ + memset(&skiplist, ICAL_RECURRENCE_ARRAY_MAX_BYTE, sizeof(skiplist)); + skippos = 0; + + icalrecurrencetype_clear(&recur); +} + +void copy_list(short* array, size_t size) +{ + memcpy(array, skiplist, size*sizeof(short)); + memset(&skiplist,ICAL_RECURRENCE_ARRAY_MAX_BYTE, sizeof(skiplist)); + skippos = 0; +} + +struct icaltimetype fill_datetime(char* datestr, char* timestr) +{ + struct icaltimetype stm; + + memset(&stm,0,sizeof(stm)); + + if (datestr != 0){ + sscanf(datestr,"%4d%2d%2d",&(stm.year), &(stm.month), + &(stm.day)); + } + + if (timestr != 0){ + sscanf(timestr,"%2d%2d%2d", &(stm.hour), &(stm.minute), + &(stm.second)); + } + + return stm; + +} + +void yyerror(char* s) +{ + /*fprintf(stderr,"Parse error \'%s\'\n", s);*/ +} + diff --git a/libical/src/libical/pvl.c b/libical/src/libical/pvl.c index b88272a6a0..d5225a541e 100644 --- a/libical/src/libical/pvl.c +++ b/libical/src/libical/pvl.c @@ -17,6 +17,10 @@ limitations under the License. ======================================================================*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "pvl.h" #include <errno.h> #include <assert.h> diff --git a/libical/src/libicalss/Makefile.am b/libical/src/libicalss/Makefile.am index d2f65de885..4d05257e8b 100644 --- a/libical/src/libicalss/Makefile.am +++ b/libical/src/libicalss/Makefile.am @@ -1,13 +1,21 @@ -INCLUDES = \ - -I$(top_srcdir)/src/libical - -lib_LTLIBRARIES = libicalss.la - -libicalss_la_SOURCES = \ - icalcalendar.c \ - icalcalendar.h \ - icalcluster.c \ - icalcluster.h \ - icalcomponent.h \ - icalstore.c \ + + +#noinst_LTLIBRARIES = libicalss.la +lib_LIBRARIES = libicalss.a + +libicalss_a_SOURCES =\ + icalcalendar.c \ + icalcalendar.h \ + icalcluster.c \ + icalcluster.h \ + icalstore.c \ + icalstore.h + +include_HEADERS =\ + icalcalendar.h \ + icalcluster.h \ icalstore.h + + +INCLUDES = -I../libical/ + diff --git a/libical/src/libicalss/icalcalendar.c b/libical/src/libicalss/icalcalendar.c index 0933df1e31..0f2231b1d7 100644 --- a/libical/src/libicalss/icalcalendar.c +++ b/libical/src/libicalss/icalcalendar.c @@ -26,6 +26,11 @@ ======================================================================*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + #include "icalcalendar.h" #include "icalcluster.h" #include <limits.h> diff --git a/libical/src/libicalss/icalcluster.c b/libical/src/libicalss/icalcluster.c index c0160cc6c3..36bdccc743 100644 --- a/libical/src/libicalss/icalcluster.c +++ b/libical/src/libicalss/icalcluster.c @@ -26,6 +26,11 @@ ======================================================================*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + #include "icalcluster.h" #include <errno.h> #include <limits.h> /* For PATH_MAX */ @@ -33,11 +38,16 @@ #include <unistd.h> /* for stat, getpid */ #include <stdlib.h> #include <string.h> +#include <fcntl.h> /* for fcntl */ +#include <unistd.h> /* for fcntl */ + +icalerrorenum icalcluster_create_cluster(char *path); struct icalcluster_impl { char *path; icalcomponent* cluster; int changed; + FILE* stream; }; icalcluster* icalcluster_new_impl() @@ -54,136 +64,24 @@ icalcluster* icalcluster_new_impl() return comp; } -icalerrorenum icalcluster_create_cluster(char *path) -{ - - FILE* f; - int r; - icalcomponent *c; - struct icaltimetype tt; - - icalerror_clear_errno(); - - f = fopen(path,"w"); - - if (f == 0){ - icalerror_set_errno(ICAL_FILE_ERROR); - return ICAL_FILE_ERROR; - } - - /* Create the root component in the cluster. This component holds - all of the other components and stores a count of - components. */ - - memset(&tt,0,sizeof(struct icaltimetype)); - - c = icalcomponent_vanew( - ICAL_VCALENDAR_COMPONENT, - icalproperty_new_xlicclustercount(0), - icalproperty_new_dtstart(tt), /* dtstart of earliest comp */ - icalproperty_new_dtend(tt), /* dtend of latest comp, excl. recuring */ - 0 - ); - - if (c == 0){ - fclose(f); - icalerror_set_errno(ICAL_INTERNAL_ERROR); - return ICAL_INTERNAL_ERROR; - } - - - /* Write the base component to the file */ - r = fputs(icalcomponent_as_ical_string(c),f); - - fclose(f); - - icalcomponent_free(c); - - if (r == EOF){ - icalerror_set_errno(ICAL_FILE_ERROR); - return ICAL_FILE_ERROR; - } - - return ICAL_NO_ERROR; -} - -FILE* parser_file; /*HACK. Not Thread Safe */ -char* read_from_file(char *s, size_t size) +char* read_from_file(char *s, size_t size, void *d) { - char *c = fgets(s,size, parser_file); + char *c = fgets(s,size, (FILE*)d); return c; } -icalerrorenum icalcluster_load(icalcluster* cluster, char* path) -{ - struct icalcluster_impl *impl = (struct icalcluster_impl*)cluster; - icalerrorenum error; - errno = 0; - - icalerror_check_arg_rz((cluster!=0),"cluster"); - icalerror_check_arg_rz((path!=0),"path"); - - if(impl->path != 0 && strcmp(impl->path,path) == 0){ - /* Already have the right cluster, so return */ - return ICAL_NO_ERROR; - } - - error = icalcluster_commit(cluster); - - if (error != ICAL_NO_ERROR){ - icalerror_set_errno(error); - return error; - } - - free(impl->path); - - impl->path= (char*)strdup(path); - - parser_file = fopen(impl->path,"r"); - - /* HACK. Yeah, the following code is horrible....*/ - if (parser_file ==0 || errno != 0){ - - /* Try to create the cluster */ - error = icalcluster_create_cluster(path); - - if (error == ICAL_NO_ERROR){ - /* Try to open the parser again. */ - errno = 0; - parser_file = fopen(impl->path,"r"); - - if (parser_file ==0 || errno != 0){ - impl->cluster = 0; - icalerror_set_errno(ICAL_FILE_ERROR); - return ICAL_FILE_ERROR; - } - } else { - impl->cluster = 0; - icalerror_set_errno(error); /* Redundant, actually */ - return error; - } - } - - impl->cluster = icalparser_parse(read_from_file); - - fclose(parser_file); - - if (impl->cluster == 0){ - icalerror_set_errno(ICAL_PARSE_ERROR); - return ICAL_PARSE_ERROR; - } - - return ICAL_NO_ERROR; -} - - icalcluster* icalcluster_new(char* path) { struct icalcluster_impl *impl = icalcluster_new_impl(); struct stat sbuf; int createclusterfile = 0; - icalerrorenum error; - + icalerrorenum error = ICAL_NO_ERROR; + icalparser *parser; + struct icaltimetype tt; + off_t cluster_file_size; + + memset(&tt,0,sizeof(struct icaltimetype)); + icalerror_clear_errno(); icalerror_check_arg_rz( (path!=0), "path"); @@ -193,15 +91,18 @@ icalcluster* icalcluster_new(char* path) /*impl->path = strdup(path); icalcluster_load does this */ impl->changed = 0; + impl->cluster = 0; + impl->path = 0; + impl->stream = 0; /* Check if the path already exists and if it is a regular file*/ if (stat(path,&sbuf) != 0){ /* A file by the given name does not exist, or there was another error */ - + cluster_file_size = 0; if (errno == ENOENT) { /* It was because the file does not exist */ createclusterfile = 1; @@ -219,7 +120,8 @@ icalcluster* icalcluster_new(char* path) return 0; } else { /* Lets assume that it is a file of the right type */ - createclusterfile = 0; + cluster_file_size = sbuf.st_size; + createclusterfile = 0; } } @@ -233,8 +135,43 @@ icalcluster* icalcluster_new(char* path) return 0; } } + + impl->path = (char*)strdup(path); + + errno = 0; + impl->stream = fopen(impl->path,"r"); - error = icalcluster_load(impl,path); + if (impl->stream ==0 || errno != 0){ + impl->cluster = 0; + icalerror_set_errno(ICAL_FILE_ERROR); /* Redundant, actually */ + return 0; + } + + icalcluster_lock(impl); + + if(cluster_file_size > 0){ + parser = icalparser_new(); + icalparser_set_gen_data(parser,impl->stream); + impl->cluster = icalparser_parse(parser,read_from_file); + icalparser_free(parser); + + if (icalcomponent_isa(impl->cluster) != ICAL_XROOT_COMPONENT){ + /* The parser got a single component, so it did not put it in + an XROOT. */ + icalcomponent *cl = impl->cluster; + impl->cluster = icalcomponent_new(ICAL_XROOT_COMPONENT); + icalcomponent_add_component(impl->cluster,cl); + } + + } else { + + impl->cluster = icalcomponent_new(ICAL_XROOT_COMPONENT); + } + + if (impl->cluster == 0){ + icalerror_set_errno(ICAL_PARSE_ERROR); + return 0; + } if (error != ICAL_NO_ERROR){ return 0; @@ -260,46 +197,134 @@ void icalcluster_free(icalcluster* cluster) impl->path = 0; } + if(impl->stream != 0){ + icalcluster_unlock(impl); + fclose(impl->stream); + impl->stream = 0; + } + free(impl); } -icalerrorenum icalcluster_commit(icalcluster* cluster) +char* icalcluster_path(icalcluster* cluster) { - int ws; /* Size in char of file written to disk */ - FILE *f; + struct icalcluster_impl *impl = (struct icalcluster_impl*)cluster; + icalerror_check_arg_rz((cluster!=0),"cluster"); + + return impl->path; +} + +int icalcluster_lock(icalcluster *cluster) +{ struct icalcluster_impl *impl = (struct icalcluster_impl*)cluster; + struct flock lock; + int fd; - icalerror_check_arg_re((impl!=0),"cluster",ICAL_BADARG_ERROR); + icalerror_check_arg_rz((impl->stream!=0),"impl->stream"); - if (impl->changed != 0 ){ - /* write the cluster to disk */ + fd = fileno(impl->stream); - /* Construct a filename and write out the file */ - - if ( (f = fopen(impl->path,"w")) != 0){ + lock.l_type = F_WRLCK; /* F_RDLCK, F_WRLCK, F_UNLCK */ + lock.l_start = 0; /* byte offset relative to l_whence */ + lock.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */ + lock.l_len = 0; /* #bytes (0 means to EOF) */ + + return (fcntl(fd, F_SETLKW, &lock)); +} + +int icalcluster_unlock(icalcluster *cluster) +{ + struct icalcluster_impl *impl = (struct icalcluster_impl*)cluster; + int fd; + struct flock lock; + icalerror_check_arg_rz((impl->stream!=0),"impl->stream"); + + fd = fileno(impl->stream); + + lock.l_type = F_WRLCK; /* F_RDLCK, F_WRLCK, F_UNLCK */ + lock.l_start = 0; /* byte offset relative to l_whence */ + lock.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */ + lock.l_len = 0; /* #bytes (0 means to EOF) */ + + return (fcntl(fd, F_UNLCK, &lock)); + +} + +icalerrorenum icalcluster_create_cluster(char *path) +{ + + FILE* f; + int r; + icalcomponent *c; + + icalerror_clear_errno(); + + f = fopen(path,"w"); + + if (f == 0){ + icalerror_set_errno(ICAL_FILE_ERROR); + return ICAL_FILE_ERROR; + } + + + /* This used to write data to the file... */ - char* str = icalcomponent_as_ical_string(impl->cluster); - - ws = fwrite(str,sizeof(char),strlen(str),f); - - if ( ws < strlen(str)){ - fclose(f); - return ICAL_FILE_ERROR; - } + fclose(f); + + return ICAL_NO_ERROR; +} + +icalerrorenum icalcluster_commit(icalcluster* cluster) +{ + FILE *f; + char tmp[PATH_MAX]; /* HACK Buffer overflow potential */ + char *str; + icalparser *parser; + icalcomponent *c; + + struct icalcluster_impl *impl = (struct icalcluster_impl*)cluster; + + icalerror_check_arg_re((impl!=0),"cluster",ICAL_BADARG_ERROR); + + if (impl->changed == 0 ){ + return ICAL_NO_ERROR; + } + +#ifdef ICAL_SAFESAVES + snprintf(tmp,PATH_MAX,"%s-tmp",impl->path); +#else + strcpy(tmp,impl->path); +#endif + + if ( (f = fopen(tmp,"w")) < 0 ){ + icalerror_set_errno(ICAL_FILE_ERROR); + return ICAL_FILE_ERROR; + } + + for(c = icalcomponent_get_first_component(impl->cluster,ICAL_ANY_COMPONENT); + c != 0; + c = icalcomponent_get_next_component(impl->cluster,ICAL_ANY_COMPONENT)){ + + str = icalcomponent_as_ical_string(c); + + if ( fwrite(str,sizeof(char),strlen(str),f) < strlen(str)){ fclose(f); - impl->changed = 0; - return ICAL_NO_ERROR; - } else { - icalerror_set_errno(ICAL_FILE_ERROR); return ICAL_FILE_ERROR; } - - } - + } + + fclose(f); + impl->changed = 0; + +#ifdef ICAL_SAFESAVES + rename(tmp,impl->path); /* HACK, should check for error here */ +#endif + return ICAL_NO_ERROR; -} + +} void icalcluster_mark(icalcluster* cluster){ diff --git a/libical/src/libicalss/icalcluster.h b/libical/src/libicalss/icalcluster.h index 05c3a4b144..39fe542027 100644 --- a/libical/src/libicalss/icalcluster.h +++ b/libical/src/libicalss/icalcluster.h @@ -37,9 +37,7 @@ typedef void icalcluster; icalcluster* icalcluster_new(char* path); void icalcluster_free(icalcluster* cluster); - -/* Load a new file into the cluster */ -icalerrorenum icalcluster_load(icalcluster* cluster, char* path); +char* icalcluster_path(icalcluster* cluster); /* Return a reference to the internal component. */ icalcomponent* icalcluster_get_component(icalcluster* cluster); diff --git a/libical/src/libicalss/icalstore.c b/libical/src/libicalss/icalstore.c index 5d1546f3b2..382464e476 100644 --- a/libical/src/libicalss/icalstore.c +++ b/libical/src/libicalss/icalstore.c @@ -1,29 +1,29 @@ /* -*- Mode: C -*- - ====================================================================== - FILE: icalstore.c - CREATOR: eric 28 November 1999 + ====================================================================== + FILE: icalstore.c + CREATOR: eric 28 November 1999 - $Id$ - $Locker$ + $Id$ + $Locker$ - (C) COPYRIGHT 1999 Eric Busboom - http://www.softwarestudio.org + (C) COPYRIGHT 1999 Eric Busboom + http://www.softwarestudio.org - The contents of this file are subject to the Mozilla Public License - Version 1.0 (the "License"); you may not use this file except in - compliance with the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ + The contents of this file are subject to the Mozilla Public License + Version 1.0 (the "License"); you may not use this file except in + compliance with the License. You may obtain a copy of the License at + http://www.mozilla.org/MPL/ - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - the License for the specific language governing rights and - limitations under the License. + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and + limitations under the License. - The Original Code is eric. The Initial Developer of the Original - Code is Eric Busboom + The Original Code is eric. The Initial Developer of the Original + Code is Eric Busboom - ======================================================================*/ + ======================================================================*/ /* @@ -51,6 +51,11 @@ */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + #include "ical.h" #include "icalstore.h" #include "pvl.h" @@ -58,8 +63,6 @@ #include "icalparser.h" #include "icalcluster.h" -#include "filelock.h" - #include <limits.h> #include <dirent.h> /* for opendir() */ #include <errno.h> @@ -95,25 +98,23 @@ struct icalstore_impl* icalstore_new_impl() return comp; } - - -void icalstore_lock_dir(char* dir) +void icalstore_lock(char* dir) { } -void icalstore_unlock_dir(char* dir) +void icalstore_unlock(char* dir) { } /* Load the contents of the store directory into the store's internal directory list*/ icalerrorenum icalstore_read_directory(struct icalstore_impl* impl) { - struct dirent *de; - DIR* dp; - char *str; + struct dirent *de; + DIR* dp; + char *str; - dp = opendir(impl->dir); + dp = opendir(impl->dir); if ( dp == 0) { icalerror_set_errno(ICAL_FILE_ERROR); @@ -166,7 +167,7 @@ icalstore* icalstore_new(char* dir) return 0; } - icalstore_lock_dir(dir); + icalstore_lock(dir); impl = icalstore_new_impl(); @@ -192,7 +193,7 @@ void icalstore_free(icalstore* s) struct icalstore_impl *impl = (struct icalstore_impl*)s; char* str; - icalstore_unlock_dir(impl->dir); + icalstore_unlock(impl->dir); if(impl->dir !=0){ free(impl->dir); @@ -298,10 +299,13 @@ icalerrorenum icalstore_next_cluster(icalstore* store) return ICAL_NO_ERROR; } - sprintf(path,"%s/%s",impl->dir,(char*)pvl_data(impl->directory_iterator)); - return icalcluster_load(impl->cluster,path); + icalcluster_free(impl->cluster); + + impl->cluster = icalcluster_new(path); + + return icalerrno; } void icalstore_add_uid(icalstore* store, icalstore* comp) @@ -310,8 +314,8 @@ void icalstore_add_uid(icalstore* store, icalstore* comp) icalproperty *uid; struct utsname unamebuf; - icalerror_check_arg_rz( (store!=0), "store"); - icalerror_check_arg_rz( (comp!=0), "comp"); + icalerror_check_arg_rv( (store!=0), "store"); + icalerror_check_arg_rv( (comp!=0), "comp"); uid = icalcomponent_get_first_property(comp,ICAL_UID_PROPERTY); @@ -319,7 +323,7 @@ void icalstore_add_uid(icalstore* store, icalstore* comp) uname(&unamebuf); - sprintf(uidstring,"%d-%s",getpid(),unamebuf.nodename); + sprintf(uidstring,"%d-%s",(int)getpid(),unamebuf.nodename); uid = icalproperty_new_uid(uidstring); icalcomponent_add_property(comp,uid); @@ -329,14 +333,20 @@ void icalstore_add_uid(icalstore* store, icalstore* comp) } } + +/* This assumes that the top level component is a VCALENDAR, and there + is an inner component of type VEVENT, VTODO or VJOURNAL. The inner + component must have a DTSTART property */ + icalerrorenum icalstore_add_component(icalstore* store, icalstore* comp) { struct icalstore_impl *impl; char clustername[PATH_MAX]; - icalproperty *dt, *count, *lm; + icalproperty *dt, *count; icalvalue *v; struct icaltimetype tm; icalerrorenum error = ICAL_NO_ERROR; + icalcomponent *inner; impl = (struct icalstore_impl*)store; icalerror_check_arg_rz( (store!=0), "store"); @@ -346,20 +356,21 @@ icalerrorenum icalstore_add_component(icalstore* store, icalstore* comp) icalstore_add_uid(store,comp); - /* Determine which cluster this object belongs in */ - - dt = icalcomponent_get_first_property(comp,ICAL_DTSTART_PROPERTY); + /* Determine which cluster this object belongs in. This is a HACK */ - if (dt == 0){ - dt = icalcomponent_get_first_property(comp,ICAL_DTSTAMP_PROPERTY); + for(inner = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT); + inner != 0; + inner = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT)){ + + dt = icalcomponent_get_first_property(inner,ICAL_DTSTART_PROPERTY); + + if (dt != 0){ + break; + } } if (dt == 0){ - dt = icalcomponent_get_first_property(comp,ICAL_CREATED_PROPERTY); - } - - if (dt == 0){ - icalerror_warn("The component does not have a DTSTART, DTSTAMP or a CREATED property, so it cannot be added to the store"); + icalerror_warn("The component does not have a DTSTART property, so it cannot be added to the store"); icalerror_set_errno(ICAL_BADARG_ERROR); return ICAL_BADARG_ERROR; } @@ -368,41 +379,29 @@ icalerrorenum icalstore_add_component(icalstore* store, icalstore* comp) tm = icalvalue_get_datetime(v); - sprintf(clustername,"%s/%04d%02d",impl->dir,tm.year,tm.month); + snprintf(clustername,PATH_MAX,"%s/%04d%02d",impl->dir,tm.year,tm.month); /* Load the cluster and insert the object */ + if(impl->cluster != 0 && + strcmp(clustername,icalcluster_path(impl->cluster)) != 0 ){ + icalcluster_free(impl->cluster); + impl->cluster = 0; + } + if (impl->cluster == 0){ impl->cluster = icalcluster_new(clustername); if (impl->cluster == 0){ error = icalerrno; } - } else { - error = icalcluster_load(impl->cluster, - clustername); - } - if (error != ICAL_NO_ERROR){ icalerror_set_errno(error); return error; } - /* Update or add the LAST-MODIFIED property */ - - lm = icalcomponent_get_first_property(comp, - ICAL_LASTMODIFIED_PROPERTY); - - if (lm == 0){ - lm = icalproperty_new_lastmodified(icaltimetype_from_timet( time(0),1)); - icalcomponent_add_property(comp,lm); - } else { - icalproperty_set_lastmodified(comp,icaltimetype_from_timet( time(0),1)); - } - - /* Add the component to the cluster */ icalcluster_add_component(impl->cluster,comp); @@ -419,7 +418,7 @@ icalerrorenum icalstore_add_component(icalstore* store, icalstore* comp) } icalproperty_set_xlicclustercount(count, - icalproperty_get_xlicclustercount(count)+1); + icalproperty_get_xlicclustercount(count)+1); icalcluster_mark(impl->cluster); @@ -438,38 +437,38 @@ icalerrorenum icalstore_remove_component(icalstore* store, icalstore* comp) icalerror_check_arg_re((impl->cluster!=0),"Cluster pointer",ICAL_USAGE_ERROR); /* HACK The following code should be used to ensure that the component -the caller is trying to remove is actually in the cluster, but it -resets the internal iterators, which immediately ends any loops over -the cluster the caller may have in progress - - for(c = icalcluster_get_first_component( - impl->cluster, - ICAL_ANY_COMPONENT); - c != 0; - c = icalcluster_get_next_component( - impl->cluster, - ICAL_ANY_COMPONENT)){ - - if (c == comp){ - found = 1; - } - - } - - if (found != 1){ - icalerror_warn("icalstore_remove_component: component is not part of current cluster"); - icalerror_set_errno(ICAL_USAGE_ERROR); - return ICAL_USAGE_ERROR; - } + the caller is trying to remove is actually in the cluster, but it + resets the internal iterators, which immediately ends any loops over + the cluster the caller may have in progress + + for(c = icalcluster_get_first_component( + impl->cluster, + ICAL_ANY_COMPONENT); + c != 0; + c = icalcluster_get_next_component( + impl->cluster, + ICAL_ANY_COMPONENT)){ + + if (c == comp){ + found = 1; + } + + } + + if (found != 1){ + icalerror_warn("icalstore_remove_component: component is not part of current cluster"); + icalerror_set_errno(ICAL_USAGE_ERROR); + return ICAL_USAGE_ERROR; + } */ icalcluster_remove_component(impl->cluster, - comp); + comp); icalcluster_mark(impl->cluster); - /* Decrement the clusters count value */ + /* Decrement the clusters count value */ count = icalcomponent_get_first_property( icalcluster_get_component(impl->cluster), ICAL_XLICCLUSTERCOUNT_PROPERTY); @@ -480,7 +479,7 @@ the cluster the caller may have in progress } icalproperty_set_xlicclustercount(count, - icalproperty_get_xlicclustercount(count)-1); + icalproperty_get_xlicclustercount(count)-1); return ICAL_NO_ERROR; } @@ -507,6 +506,7 @@ icalcomponent* icalstore_make_gauge(icalcomponent* query); Here is an example: + BEGIN:XROOT BEGIN:VCOMPONENT BEGIN:VEVENT DTSTART;X-LIC-COMPARETYPE=LESS:19981025T020000 @@ -516,76 +516,79 @@ icalcomponent* icalstore_make_gauge(icalcomponent* query); LOCATION;X-LIC-COMPARETYPE=EQUAL:McNary's Pub END:VEVENT END:VCALENDAR + END:XROOT This gauge has two sub-components; one which will match a VEVENT based on start time, and organizer, and another that matches based on LOCATION. A target component will pass the test if it matched - either of the gauge. + either of the sub-components. */ -int icalstore_test(icalcomponent* comp, icalcomponent* gauge) + +int icalstore_test_recurse(icalcomponent* comp, icalcomponent* gauge) { - int pass = 0,localpass = 0; - icalcomponent *c; + int pass = 1,localpass = 0; icalproperty *p; - icalcomponent *child; + icalcomponent *child,*subgauge; + icalcomponent_kind gaugekind, compkind; icalerror_check_arg_rz( (comp!=0), "comp"); icalerror_check_arg_rz( (gauge!=0), "gauge"); - for(c = icalcomponent_get_first_component(gauge,ICAL_ANY_COMPONENT); - c != 0; - c = icalcomponent_get_next_component(gauge,ICAL_ANY_COMPONENT)){ + gaugekind = icalcomponent_isa(gauge); + compkind = icalcomponent_isa(comp); + if( ! (gaugekind == compkind || gaugekind == ICAL_ANY_COMPONENT) ){ + return 0; + } - /* Test properties. For each property in the gauge, search through - the component for a similar property. If one is found, compare - the two properties value with the comparison specified in the - gauge with the X-LIC-COMPARETYPE parameter */ - - for(p = icalcomponent_get_first_property(c,ICAL_ANY_PROPERTY); - p != 0; - p = icalcomponent_get_next_property(c,ICAL_ANY_PROPERTY)){ + /* Test properties. For each property in the gauge, search through + the component for a similar property. If one is found, compare + the two properties value with the comparison specified in the + gauge with the X-LIC-COMPARETYPE parameter */ + + for(p = icalcomponent_get_first_property(gauge,ICAL_ANY_PROPERTY); + p != 0; + p = icalcomponent_get_next_property(gauge,ICAL_ANY_PROPERTY)){ + + icalproperty* targetprop; + icalparameter* compareparam; + icalparameter_xliccomparetype compare; + int rel; /* The relationship between the gauge and target values.*/ + + /* Extract the comparison type from the gauge. If there is no + comparison type, assume that it is "EQUAL" */ + + compareparam = icalproperty_get_first_parameter( + p, + ICAL_XLICCOMPARETYPE_PARAMETER); + + if (compareparam!=0){ + compare = icalparameter_get_xliccomparetype(compareparam); + } else { + compare = ICAL_XLICCOMPARETYPE_EQUAL; + } + + /* Find a property in the component that has the same type + as the gauge property. HACK -- multiples of a single + property type in the gauge will match only the first + instance in the component */ + + targetprop = icalcomponent_get_first_property(comp, + icalproperty_isa(p)); + + if(targetprop != 0){ - icalproperty* targetprop; - icalparameter* compareparam; - icalparameter_xliccomparetype compare; - int rel; /* The realtionship between the gauge and target values.*/ - - /* Extract the comparison type from the gauge. If there is no - comparison type, assume that it is "EQUAL" */ - - compareparam = icalproperty_get_first_parameter( - p, - ICAL_XLICCOMPARETYPE_PARAMETER); - - if (compareparam!=0){ - compare = icalparameter_get_xliccomparetype(compareparam); - } else { - compare = ICAL_XLICCOMPARETYPE_EQUAL; - } - - /* Find a property in the component that has the same type as - the gauge property */ - - targetprop = icalcomponent_get_first_property(comp, - icalproperty_isa(p)); - - - if(targetprop == 0){ - continue; - } - /* Compare the values of the gauge property and the target property */ - + rel = icalvalue_compare(icalproperty_get_value(p), icalproperty_get_value(targetprop)); - + /* Now see if the comparison is equavalent to the comparison specified in the gauge */ - + if (rel == compare){ localpass++; } else if (compare == ICAL_XLICCOMPARETYPE_LESSEQUAL && @@ -599,27 +602,59 @@ int icalstore_test(icalcomponent* comp, icalcomponent* gauge) } else if (compare == ICAL_XLICCOMPARETYPE_NOTEQUAL && ( rel == ICAL_XLICCOMPARETYPE_GREATER || rel == ICAL_XLICCOMPARETYPE_LESS)) { - pass++; + localpass++; } else { localpass = 0; } - - pass += localpass; + + pass = pass && (localpass>0); } - - - /* test subcomponents. Look for a child component that has a - counterpart in the gauge. If one is found, recursively call - icalstore_test */ + } + + /* Test subcomponents. Look for a child component that has a + counterpart in the gauge. If one is found, recursively call + icalstore_test */ + + for(subgauge = icalcomponent_get_first_component(gauge,ICAL_ANY_COMPONENT); + subgauge != 0; + subgauge = icalcomponent_get_next_component(gauge,ICAL_ANY_COMPONENT)){ - for(child = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT); - child != 0; - child = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT)){ + gaugekind = icalcomponent_isa(subgauge); + + if (gaugekind == ICAL_ANY_COMPONENT){ + child = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT); + } else { + child = icalcomponent_get_first_component(comp,gaugekind); + } - pass += icalstore_test(child,gauge); - + if(child !=0){ + localpass = icalstore_test_recurse(child,subgauge); + pass = pass && localpass; + } else { + pass = 0; } } + + return pass; +} + +/* guagecontainer is an XROOT component that holds several gauges. The + results of comparing against these gauges are ORed together in this + routine */ +int icalstore_test(icalcomponent* comp, icalcomponent* gaugecontainer) +{ + int pass = 0; + icalcomponent *gauge; + + icalerror_check_arg_rz( (comp!=0), "comp"); + icalerror_check_arg_rz( (gauge!=0), "gauge"); + + for(gauge = icalcomponent_get_first_component(gaugecontainer,ICAL_ANY_COMPONENT); + gauge != 0; + gauge = icalcomponent_get_next_component(gaugecontainer,ICAL_ANY_COMPONENT)){ + + pass += icalstore_test_recurse(comp, gauge); + } return pass>0; @@ -721,16 +756,21 @@ icalcomponent* icalstore_get_first_component(icalstore* store) sprintf(path,"%s/%s",impl->dir,(char*)pvl_data(impl->directory_iterator)); - if (impl->cluster == 0){ + /* If the next cluster we need is different than the current cluster, + delete the current one and get a new one */ + + if(impl->cluster != 0 && strcmp(path,icalcluster_path(impl->cluster)) != 0 ){ + icalcluster_free(impl->cluster); + impl->cluster = 0; + } + + if (impl->cluster == 0){ impl->cluster = icalcluster_new(path); if (impl->cluster == 0){ error = icalerrno; } - } else { - error = icalcluster_load(impl->cluster,path); - - } + } if (error != ICAL_NO_ERROR){ icalerror_set_errno(error); @@ -783,13 +823,13 @@ icalcomponent* icalstore_get_next_component(icalstore* store) ICAL_ANY_COMPONENT)){ /* If there is a gauge defined and the component does not - pass the gauge, skip the rest of the loop */ + pass the gauge, skip the rest of the loop */ if (impl->gauge != 0 && icalstore_test(c,impl->gauge) == 0){ continue; } /* Either there is no gauge, or the component passed the - gauge, so return it*/ + gauge, so return it*/ return c; } @@ -815,3 +855,4 @@ icalcomponent* icalstore_get_next_component(icalstore* store) + diff --git a/libical/src/test/Makefile.am b/libical/src/test/Makefile.am new file mode 100644 index 0000000000..0ebb00ac9a --- /dev/null +++ b/libical/src/test/Makefile.am @@ -0,0 +1,12 @@ + +noinst_PROGRAMS = usecases copycluster regression parser findobj storage + +LDADD = ../libical/libical.a ../libicalss/libicalss.a +INCLUDES = -I . -I../libical -I../libicalss + +findobj_SOURCES = findobj.c +usecases_SOURCES = usecases.c +copycluster_SOURCES = copycluster.c +regression_SOURCES = regression.c +parser_SOURCES = icaltestparser.c +storage_SOURCES = storage.c
\ No newline at end of file diff --git a/libical/src/test/Makefile.in b/libical/src/test/Makefile.in index 5d3d5f709f..a8af11a146 100644 --- a/libical/src/test/Makefile.in +++ b/libical/src/test/Makefile.in @@ -1,36 +1,310 @@ +# Makefile.in generated automatically by automake 1.4a from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = ../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_FLAG = +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +AR = @AR@ +CC = @CC@ +LEX = @LEX@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +VERSION = @VERSION@ +YACC = @YACC@ + +noinst_PROGRAMS = usecases copycluster regression parser findobj storage + +LDADD = ../libical/libical.a ../libicalss/libicalss.a INCLUDES = -I . -I../libical -I../libicalss -CFLAGS = -Wall -g $(INCLUDES) -LIBS = -L../libical -L../libicalss -licalss -lical -CC = gcc -LD = ld -all: usecases copycluster regression parser findobj +findobj_SOURCES = findobj.c +usecases_SOURCES = usecases.c +copycluster_SOURCES = copycluster.c +regression_SOURCES = regression.c +parser_SOURCES = icaltestparser.c +storage_SOURCES = storage.c +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../../config.h +CONFIG_CLEAN_FILES = +PROGRAMS = $(noinst_PROGRAMS) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I../.. +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +usecases_OBJECTS = usecases.o +usecases_LDADD = $(LDADD) +usecases_DEPENDENCIES = ../libical/libical.a ../libicalss/libicalss.a +usecases_LDFLAGS = +copycluster_OBJECTS = copycluster.o +copycluster_LDADD = $(LDADD) +copycluster_DEPENDENCIES = ../libical/libical.a \ +../libicalss/libicalss.a +copycluster_LDFLAGS = +regression_OBJECTS = regression.o +regression_LDADD = $(LDADD) +regression_DEPENDENCIES = ../libical/libical.a ../libicalss/libicalss.a +regression_LDFLAGS = +parser_OBJECTS = icaltestparser.o +parser_LDADD = $(LDADD) +parser_DEPENDENCIES = ../libical/libical.a ../libicalss/libicalss.a +parser_LDFLAGS = +findobj_OBJECTS = findobj.o +findobj_LDADD = $(LDADD) +findobj_DEPENDENCIES = ../libical/libical.a ../libicalss/libicalss.a +findobj_LDFLAGS = +storage_OBJECTS = storage.o +storage_LDADD = $(LDADD) +storage_DEPENDENCIES = ../libical/libical.a ../libicalss/libicalss.a +storage_LDFLAGS = +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(usecases_SOURCES) $(copycluster_SOURCES) $(regression_SOURCES) $(parser_SOURCES) $(findobj_SOURCES) $(storage_SOURCES) +OBJECTS = $(usecases_OBJECTS) $(copycluster_OBJECTS) $(regression_OBJECTS) $(parser_OBJECTS) $(findobj_OBJECTS) $(storage_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps src/test/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-noinstPROGRAMS: + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) + +distclean-noinstPROGRAMS: + +maintainer-clean-noinstPROGRAMS: + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +usecases: $(usecases_OBJECTS) $(usecases_DEPENDENCIES) + @rm -f usecases + $(LINK) $(usecases_LDFLAGS) $(usecases_OBJECTS) $(usecases_LDADD) $(LIBS) + +copycluster: $(copycluster_OBJECTS) $(copycluster_DEPENDENCIES) + @rm -f copycluster + $(LINK) $(copycluster_LDFLAGS) $(copycluster_OBJECTS) $(copycluster_LDADD) $(LIBS) + +regression: $(regression_OBJECTS) $(regression_DEPENDENCIES) + @rm -f regression + $(LINK) $(regression_LDFLAGS) $(regression_OBJECTS) $(regression_LDADD) $(LIBS) + +parser: $(parser_OBJECTS) $(parser_DEPENDENCIES) + @rm -f parser + $(LINK) $(parser_LDFLAGS) $(parser_OBJECTS) $(parser_LDADD) $(LIBS) + +findobj: $(findobj_OBJECTS) $(findobj_DEPENDENCIES) + @rm -f findobj + $(LINK) $(findobj_LDFLAGS) $(findobj_OBJECTS) $(findobj_LDADD) $(LIBS) + +storage: $(storage_OBJECTS) $(storage_DEPENDENCIES) + @rm -f storage + $(LINK) $(storage_LDFLAGS) $(storage_OBJECTS) $(storage_LDADD) $(LIBS) + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = src/test + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile $(PROGRAMS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_STRIP_FLAG=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-noinstPROGRAMS mostlyclean-compile \ + mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-am -parser: icaltestparser.o ../libical/libical.a ../libicalss/libicalss.a - $(CC) -o icalparser icaltestparser.o $(LIBS) +clean-am: clean-noinstPROGRAMS clean-compile clean-tags clean-generic \ + mostlyclean-am -copycluster: copycluster.o ../libical/libical.a ../libicalss/libicalss.a - $(CC) -o copycluster copycluster.o $(INCLUDES) $(LIBS) +clean: clean-am -findobj: findobj.o ../libical/libical.a ../libicalss/libicalss.a - $(CC) -o findobj findobj.o $(INCLUDES) $(LIBS) +distclean-am: distclean-noinstPROGRAMS distclean-compile distclean-tags \ + distclean-generic clean-am -regression: regression.o ../libical/libical.a ../libicalss/libicalss.a - $(CC) -o regression regression.o $(INCLUDES) $(LIBS) +distclean: distclean-am -usecases: usecases.o ../libical/libical.a ../libicalss/libicalss.a - $(CC) -o usecases usecases.o $(INCLUDES) $(LIBS) +maintainer-clean-am: maintainer-clean-noinstPROGRAMS \ + maintainer-clean-compile maintainer-clean-tags \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." -clean: - -/bin/rm -f *.o - -/bin/rm -f \#* - -/bin/rm -f *~ Makefile.bak icalitip.tab.h icalitip.tab.c lex.yy.c - -/bin/rm -rf icalparser core regression usecases copycluster findobj +maintainer-clean: maintainer-clean-am -ci: clean - ci -u *.c *.h +.PHONY: mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \ +clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ +check-am installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean -depend: - @makedepend -Y $(INCLUDES) $(SOURCES) -install:
\ No newline at end of file +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libical/src/test/icaltestparser.c b/libical/src/test/icaltestparser.c index d56af49258..3f07fcd044 100644 --- a/libical/src/test/icaltestparser.c +++ b/libical/src/test/icaltestparser.c @@ -33,78 +33,91 @@ #include <stdlib.h> -char str[] = "BEGIN:VCALENDAR -PRODID:\"-//RDU Software//NONSGML HandCal//EN\" -VERSION:2.0 -BEGIN:VTIMEZONE -TZID:US-Eastern -BEGIN:STANDARD -DTSTART:19990404T020000 -RDATE:19990u404xT020000 -TZOFFSETFROM:-0500 -TZOFFSETTO:-0400 -END:STANDARD -BEGIN:DAYLIGHT -DTSTART:19990404T020000 -RDATE:19990404T020000 -TZOFFSETFROM:-0500 -TZOFFSETTO:-0400 -TZNAME:EDT -Dkjhgri:derhvnv; -BEGIN:dfkjh -END:dfdfkjh -END:DAYLIGHT -END:VTIMEZONE -BEGIN:VEVENT -GEO:Bongo -DTSTAMP:19980309T231000Z -UID:guid-1.host1.com -ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com -ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP - :MAILTO:employee-A@host.com -DESCRIPTION:Project XYZ Review Meeting -CATEGORIES:MEETING -CLASS:PUBLIC -CREATED:19980309T130000Z -SUMMARY:XYZ Project Review -DTSTART;TZID=US-Eastern:19980312T083000 -DTEND;TZID=US-Eastern:19980312T093000 -LOCATION:1CP Conference Room 4350 -END:VEVENT -END:VCALENDAR +char str[] = "BEGIN:VCALENDAR\ +PRODID:\"-//RDU Software//NONSGML HandCal//EN\"\ +VERSION:2.0\ +BEGIN:VTIMEZONE\ +TZID:US-Eastern\ +BEGIN:STANDARD\ +DTSTART:19990404T020000\ +RDATE:19990u404xT020000\ +TZOFFSETFROM:-0500\ +TZOFFSETTO:-0400\ +END:STANDARD\ +BEGIN:DAYLIGHT\ +DTSTART:19990404T020000\ +RDATE:19990404T020000\ +TZOFFSETFROM:-0500\ +TZOFFSETTO:-0400\ +TZNAME:EDT\ +Dkjhgri:derhvnv;\ +BEGIN:dfkjh\ +END:dfdfkjh\ +END:DAYLIGHT\ +END:VTIMEZONE\ +BEGIN:VEVENT\ +GEO:Bongo\ +DTSTAMP:19980309T231000Z\ +UID:guid-1.host1.com\ +ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com\ +ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP\ + :MAILTO:employee-A@host.com\ +DESCRIPTION:Project XYZ Review Meeting\ +CATEGORIES:MEETING\ +CLASS:PUBLIC\ +CREATED:19980309T130000Z\ +SUMMARY:XYZ Project Review\ +DTSTART;TZID=US-Eastern:19980312T083000\ +DTEND;TZID=US-Eastern:19980312T093000\ +LOCATION:1CP Conference Room 4350\ +END:VEVENT\ +END:VCALENDAR\ "; extern int yydebug; /* Have the parser fetch data from stdin */ -char* read_stdin(char *s, size_t size, void *d) +char* read_stream(char *s, size_t size, void *d) { - char *c = fgets(s,size, stdin); + char *c = fgets(s,size, (FILE*)d); return c; } -int main() + + +int main(int argc, char* argv[]) { - /* This is how we would have the parser parse a string */ - /* icalcomponent *c = icalparser_parse_string(str);*/ + int lineno = 0; + char* line; + FILE* stream; + icalcomponent *c; + icalparser *parser = icalparser_new(); - icalcomponent *c = icalparser_parse(read_stdin); + stream = fopen(argv[1],"r"); - printf("%s\n",icalcomponent_as_ical_string(c)); + assert(stream != 0); - /* Strip errors and spit it out again - printf("\n%d Errors in Component\n",icalcomponent_count_errors(c)); - icalcomponent_strip_errors(c); - printf("%s\n",icalcomponent_as_ical_string(c)); - */ + icalparser_set_gen_data(parser,stream); - icalmemory_free_ring(); - icalcomponent_free(c); + do{ + + line = icalparser_get_line(parser,read_stream); - return 1; -} + c = icalparser_add_line(parser,line); + if (c != 0){ + icalcomponent_convert_errors(c); + printf("%s",icalcomponent_as_ical_string(c)); + icalparser_claim(parser); + printf("\n---------------\n"); + icalcomponent_free(c); + } + + } while ( line != 0); + + +} diff --git a/libical/src/test/regression.c b/libical/src/test/regression.c index a969022d98..7b1606d432 100644 --- a/libical/src/test/regression.c +++ b/libical/src/test/regression.c @@ -43,94 +43,48 @@ /* This example creates and minipulates the ical object that appears * in rfc 2445, page 137 */ -/* - BEGIN:VCALENDAR - PRODID:-//RDU Software//NONSGML HandCal//EN - VERSION:2.0 - BEGIN:VTIMEZONE - TZID:US-Eastern - BEGIN:STANDARD - DTSTART:19981025T020000 - RDATE:19981025T020000 - TZOFFSETFROM:-0400 - TZOFFSETTO:-0500 - TZNAME:EST - END:STANDARD - BEGIN:DAYLIGHT - DTSTART:19990404T020000 - RDATE:19990404T020000 - TZOFFSETFROM:-0500 - TZOFFSETTO:-0400 - TZNAME:EDT - END:DAYLIGHT - END:VTIMEZONE - BEGIN:VEVENT - DTSTAMP:19980309T231000Z - UID:guid-1.host1.com - ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com - ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP: - MAILTO:employee-A@host.com - DESCRIPTION:Project XYZ Review Meeting - CATEGORIES:MEETING - CLASS:PUBLIC - CREATED:19980309T130000Z - SUMMARY:XYZ Project Review - DTSTART;TZID=US-Eastern:19980312T083000 - DTEND;TZID=US-Eastern:19980312T093000 - LOCATION:1CP Conference Room 4350 - END:VEVENT - END:VCALENDAR - -*/ -char str[] = "BEGIN:VCALENDAR -PRODID:\"-//RDU Software//NONSGML HandCal//EN\" -VERSION:2.0 -BEGIN:VTIMEZONE -TZID:US-Eastern -BEGIN:STANDARD -DTSTART:19981025T020000 -RDATE:19981025T020000 -TZOFFSETFROM:-0400 -TZOFFSETTO:-0500 -TZNAME:EST -END:STANDARD -BEGIN:DAYLIGHT -DTSTART:19990404T020000 -RDATE:19990404T020000 -TZOFFSETFROM:-0500 -TZOFFSETTO:-0400 -TZNAME:EDT -END:DAYLIGHT -END:VTIMEZONE -BEGIN:VEVENT -DTSTAMP:19980309T231000Z -UID:guid-1.host1.com -ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com -ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:MAILTO:employee-A@host.com -DESCRIPTION:Project XYZ Review Meeting -CATEGORIES:MEETING -CLASS:PUBLIC -CREATED:19980309T130000Z -SUMMARY:XYZ Project Review -DTSTART;TZID=US-Eastern:19980312T083000 -DTEND;TZID=US-Eastern:19980312T093000 -LOCATION:1CP Conference Room 4350 -END:VEVENT -BEGIN:BOOGA -DTSTAMP:19980309T231000Z -X-LIC-FOO:Booga -DTSTOMP:19980309T231000Z -UID:guid-1.host1.com -END:BOOGA +char str[] = "BEGIN:VCALENDAR\ +PRODID:\"-//RDU Software//NONSGML HandCal//EN\"\ +VERSION:2.0\ +BEGIN:VTIMEZONE\ +TZID:US-Eastern\ +BEGIN:STANDARD\ +DTSTART:19981025T020000\ +RDATE:19981025T020000\ +TZOFFSETFROM:-0400\ +TZOFFSETTO:-0500\ +TZNAME:EST\ +END:STANDARD\ +BEGIN:DAYLIGHT\ +DTSTART:19990404T020000\ +RDATE:19990404T020000\ +TZOFFSETFROM:-0500\ +TZOFFSETTO:-0400\ +TZNAME:EDT\ +END:DAYLIGHT\ +END:VTIMEZONE\ +BEGIN:VEVENT\ +DTSTAMP:19980309T231000Z\ +UID:guid-1.host1.com\ +ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com\ +ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:MAILTO:employee-A@host.com\ +DESCRIPTION:Project XYZ Review Meeting\ +CATEGORIES:MEETING\ +CLASS:PUBLIC\ +CREATED:19980309T130000Z\ +SUMMARY:XYZ Project Review\ +DTSTART;TZID=US-Eastern:19980312T083000\ +DTEND;TZID=US-Eastern:19980312T093000\ +LOCATION:1CP Conference Room 4350\ +END:VEVENT\ +BEGIN:BOOGA\ +DTSTAMP:19980309T231000Z\ +X-LIC-FOO:Booga\ +DTSTOMP:19980309T231000Z\ +UID:guid-1.host1.com\ +END:BOOGA\ END:VCALENDAR"; -void _test_string_line_generator(char* str); - -void test_string_line_generator() { - - _test_string_line_generator(str); - -} icalcomponent* create_simple_component() { @@ -611,9 +565,9 @@ void test_properties() icalparameter_new_cn("A Common Name 4"), 0); - for(param = icalproperty_get_first_parameter(prop,ICAL_ANY_PROPERTY); + for(param = icalproperty_get_first_parameter(prop,ICAL_ANY_PARAMETER); param != 0; - param = icalproperty_get_next_parameter(prop,ICAL_ANY_PROPERTY)) { + param = icalproperty_get_next_parameter(prop,ICAL_ANY_PARAMETER)) { printf("Prop parameter: %s\n",icalparameter_get_cn(param)); } @@ -811,17 +765,6 @@ void test_memory() } -int test_parser() -{ - - - icalcomponent *c = icalparser_parse_string(str); - printf("%s\n",icalcomponent_as_ical_string(c)); - icalcomponent_free(c); - icalmemory_free_ring(); - return 1; -} - int test_store() { @@ -1084,7 +1027,7 @@ void test_restriction() ICAL_VCALENDAR_COMPONENT, icalproperty_new_version("2.0"), icalproperty_new_prodid("-//RDU Software//NONSGML HandCal//EN"), - icalproperty_new_method(ICAL_METHOD_CANCEL), + icalproperty_new_method(ICAL_METHOD_REQUEST), icalcomponent_vanew( ICAL_VTIMEZONE_COMPONENT, icalproperty_new_tzid("US_Eastern"), @@ -1129,11 +1072,11 @@ void test_restriction() icalproperty_new_class("PUBLIC"), icalproperty_new_created(atime), icalproperty_new_summary("XYZ Project Review"), - icalproperty_vanew_dtstart( +/* icalproperty_vanew_dtstart( atime, icalparameter_new_tzid("US-Eastern"), 0 - ), + ),*/ icalproperty_vanew_dtend( atime, icalparameter_new_tzid("US-Eastern"), @@ -1273,35 +1216,89 @@ void test_strings(){ } -int main(int argc, char *argv[]) +void test_requeststat() { + icalrequeststatus s; + struct icalreqstattype st, st2; + char temp[1024]; + s = icalenum_num_to_reqstat(2,1); - printf("\n------------Test strings---------------\n"); - test_strings(); + assert(s == ICAL_2_1_FALLBACK_STATUS); -exit(0); + assert(icalenum_reqstat_major(s) == 2); + assert(icalenum_reqstat_minor(s) == 1); - printf("\n------------Test recur---------------\n"); - test_recur(); + printf("2.1: %s\n",icalenum_reqstat_desc(s)); -#if 0 - printf("\n------------Test Calendar---------------\n"); - test_calendar(); + st.code = s; + st.debug = "booga"; + st.desc = 0; - printf("\n------------Test Store---------------\n"); - test_store(); -#endif + printf("%s\n",icalreqstattype_as_string(st)); - printf("\n------------Test duration---------------\n"); - test_duration(); + st.desc = " A non-standard description"; + + printf("%s\n",icalreqstattype_as_string(st)); + st.desc = 0; + + sprintf(temp,"%s\n",icalreqstattype_as_string(st)); + + + st2 = icalreqstattype_from_string("2.1;Success but fallback taken on one or more property values.;booga"); + + printf("%d -- %d -- %s -- %s\n",icalenum_reqstat_major(st2.code), + icalenum_reqstat_minor(st2.code), + icalenum_reqstat_desc(st2.code), + st2.debug); + + st2 = icalreqstattype_from_string("2.1;Success but fallback taken on one or more property values.;booga"); + printf("%s\n",icalreqstattype_as_string(st2)); + + st2 = icalreqstattype_from_string("2.1;Success but fallback taken on one or more property values.;"); + printf("%s\n",icalreqstattype_as_string(st2)); + + st2 = icalreqstattype_from_string("2.1;Success but fallback taken on one or more property values."); + printf("%s\n",icalreqstattype_as_string(st2)); + + st2 = icalreqstattype_from_string("2.1;"); + printf("%s\n",icalreqstattype_as_string(st2)); + + st2 = icalreqstattype_from_string("2.1"); + printf("%s\n",icalreqstattype_as_string(st2)); + + st2 = icalreqstattype_from_string("16.4"); + assert(st2.code == ICAL_UNKNOWN_STATUS); + + st2 = icalreqstattype_from_string("1."); + assert(st2.code == ICAL_UNKNOWN_STATUS); + +} + + +int main(int argc, char *argv[]) +{ + printf("\n------------Test Restriction---------------\n"); test_restriction(); + exit(0); + printf("\n------------Test request status-------\n"); + test_requeststat(); + + + printf("\n------------Test strings---------------\n"); + test_strings(); + + printf("\n------------Test recur---------------\n"); + test_recur(); + + printf("\n------------Test duration---------------\n"); + test_duration(); printf("\n------------Test Compare---------------\n"); test_compare(); @@ -1324,9 +1321,6 @@ exit(0); printf("\n------------Create Components --------\n"); create_new_component(); - printf("\n------------Test Parser---------------\n"); - test_parser(); - printf("\n----- Create Components with vaargs ---\n"); create_new_component_with_va_args(); diff --git a/libical/src/test/storage.c b/libical/src/test/storage.c new file mode 100644 index 0000000000..f6d0dd69e5 --- /dev/null +++ b/libical/src/test/storage.c @@ -0,0 +1,460 @@ +/* -*- Mode: C -*- + ====================================================================== + FILE: usecases.c + CREATOR: eric 03 April 1999 + + DESCRIPTION: + + $Id$ + $Locker$ + + (C) COPYRIGHT 1999 Eric Busboom + http://www.softwarestudio.org + + The contents of this file are subject to the Mozilla Public License + Version 1.0 (the "License"); you may not use this file except in + compliance with the License. You may obtain a copy of the License at + http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and + limitations under the License. + + The original author is Eric Busboom + The original code is usecases.c + + + ======================================================================*/ + +#include "ical.h" +#include <assert.h> +#include <string.h> /* for strdup */ +#include <stdlib.h> /* for malloc */ +#include <stdio.h> /* for printf */ +#include <time.h> /* for time() */ +#include "icalmemory.h" +#include "icalstore.h" +#include "icalcluster.h" +#include "icalerror.h" +#include "icalrestriction.h" +#include "icalcalendar.h" + +/* This example creates and minipulates the ical object that appears + * in rfc 2445, page 137 */ + +char str[] = "BEGIN:VCALENDAR\n\ +PRODID:\"-//RDU Software//NONSGML HandCal//EN\"\n\ +VERSION:2.0\n\ +BEGIN:VTIMEZONE\n\ +TZID:US-Eastern\n\ +BEGIN:STANDARD\n\ +DTSTART:19981025T020000\n\ +RDATE:19981025T020000\n\ +TZOFFSETFROM:-0400\n\ +TZOFFSETTO:-0500\n\ +TZNAME:EST\n\ +END:STANDARD\n\ +BEGIN:DAYLIGHT\n\ +DTSTART:19990404T020000\n\ +RDATE:19990404T020000\n\ +TZOFFSETFROM:-0500\n\ +TZOFFSETTO:-0400\n\ +TZNAME:EDT\n\ +END:DAYLIGHT\n\ +END:VTIMEZONE\n\ +BEGIN:VEVENT\n\ +DTSTAMP:19980309T231000Z\n\ +UID:guid-1.host1.com\n\ +ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com\n\ +ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:MAILTO:employee-A@host.com\n\ +DESCRIPTION:Project XYZ Review Meeting\n\ +CATEGORIES:MEETING\n\ +CLASS:PUBLIC\n\ +CREATED:19980309T130000Z\n\ +SUMMARY:XYZ Project Review\n\ +DTSTART;TZID=US-Eastern:19980312T083000\n\ +DTEND;TZID=US-Eastern:19980312T093000\n\ +LOCATION:1CP Conference Room 4350\n\ +END:VEVENT\n\ +BEGIN:BOOGA\n\ +DTSTAMP:19980309T231000Z\n\ +X-LIC-FOO:Booga\n\ +DTSTOMP:19980309T231000Z\n\ +UID:guid-1.host1.com\n\ +END:BOOGA\n\ +END:VCALENDAR"; + +char str2[] = "BEGIN:VCALENDAR\n\ +PRODID:\"-//RDU Software//NONSGML HandCal//EN\"\n\ +VERSION:2.0\n\ +BEGIN:VEVENT\n\ +DTSTAMP:19980309T231000Z\n\ +UID:guid-1.host1.com\n\ +ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com\n\ +ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:MAILTO:employee-A@host.com\n\ +DESCRIPTION:Project XYZ Review Meeting\n\ +CATEGORIES:MEETING\n\ +CLASS:PUBLIC\n\ +CREATED:19980309T130000Z\n\ +SUMMARY:XYZ Project Review\n\ +DTSTART;TZID=US-Eastern:19980312T083000\n\ +DTEND;TZID=US-Eastern:19980312T093000\n\ +LOCATION:1CP Conference Room 4350\n\ +END:VEVENT\n\ +END:VCALENDAR\n\ +"; + + +void test_cluster() +{ + icalcluster *cin, *cout; + int month = 0; + int count=0; + struct icaltimetype start, end; + icalcomponent *c,*clone, *itr; + + start = icaltimetype_from_timet( time(0),0); + end = start; + end.hour++; + + cout = icalcluster_new("clusterout.ics"); + assert(cout != 0); + + c = icalparser_parse_string(str2); + assert(c != 0); + + for(month = 1; month < 2; month++){ + icalcomponent *event; + icalproperty *dtstart, *dtend; + + cout = icalcluster_new("clusterout.ics"); + assert(cout != 0); + + start.month = month; + end.month = month; + + clone = icalcomponent_new_clone(c); + assert(clone !=0); + event = icalcomponent_get_first_component(clone,ICAL_VEVENT_COMPONENT); + assert(event != 0); + + dtstart = icalcomponent_get_first_property(event,ICAL_DTSTART_PROPERTY); + assert(dtstart!=0); + icalproperty_set_dtstart(dtstart,start); + + dtend = icalcomponent_get_first_property(event,ICAL_DTEND_PROPERTY); + assert(dtend!=0); + icalproperty_set_dtend(dtend,end); + + icalcluster_add_component(cout,clone); + icalcluster_commit(cout); + + icalcluster_free(cout); + + } + + + /* Print them out */ + + + cout = icalcluster_new("clusterout.ics"); + assert(cout != 0); + + for (itr = icalcluster_get_first_component(cout, + ICAL_ANY_COMPONENT); + itr != 0; + itr = icalcluster_get_next_component(cout, + ICAL_ANY_COMPONENT)){ + + icalcomponent *event; + icalproperty *dtstart, *dtend; + + count++; + + event = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT); + + dtstart = icalcomponent_get_first_property(event,ICAL_DTSTART_PROPERTY); + dtend = icalcomponent_get_first_property(event,ICAL_DTEND_PROPERTY); + + printf("%d %s %s\n",count, icalproperty_as_ical_string(dtstart), + icalproperty_as_ical_string(dtend)); + + } + + /* Remove all of them */ + + icalcluster_free(cout); + + cout = icalcluster_new("clusterout.ics"); + assert(cout != 0); + + for (itr = icalcluster_get_first_component(cout, + ICAL_ANY_COMPONENT); + itr != 0; + itr = icalcluster_get_next_component(cout, + ICAL_ANY_COMPONENT)){ + + + icalcluster_remove_component(cout, itr); + } + + icalcluster_free(cout); + + + /* Print them out again */ + + cout = icalcluster_new("clusterout.ics"); + assert(cout != 0); + count =0; + + for (itr = icalcluster_get_first_component(cout, + ICAL_ANY_COMPONENT); + itr != 0; + itr = icalcluster_get_next_component(cout, + ICAL_ANY_COMPONENT)){ + + icalcomponent *event; + icalproperty *dtstart, *dtend; + + count++; + + event = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT); + + dtstart = icalcomponent_get_first_property(event,ICAL_DTSTART_PROPERTY); + dtend = icalcomponent_get_first_property(event,ICAL_DTEND_PROPERTY); + + printf("%d %s %s\n",count, icalproperty_as_ical_string(dtstart), + icalproperty_as_ical_string(dtend)); + + } + + icalcluster_free(cout); + + +} + + + +int test_store() +{ + + icalcomponent *c, *gauge; + icalerrorenum error; + icalcomponent *next, *itr; + icalcluster* cluster; + struct icalperiodtype rtime; + icalstore *s = icalstore_new("store"); + int i; + + assert(s != 0); + + rtime.start = icaltimetype_from_timet( time(0),0); + + cluster = icalcluster_new("clusterout.ics"); + + assert(cluster != 0); + +#define NUMCOMP 4 + + /* Duplicate every component in the cluster NUMCOMP times */ + + icalerror_clear_errno(); + + for (i = 1; i<NUMCOMP+1; i++){ + + /*rtime.start.month = i%12;*/ + rtime.start.month = i; + rtime.end = rtime.start; + rtime.end.hour++; + + for (itr = icalcluster_get_first_component(cluster, + ICAL_ANY_COMPONENT); + itr != 0; + itr = icalcluster_get_next_component(cluster, + ICAL_ANY_COMPONENT)){ + icalcomponent *clone, *inner; + icalproperty *p; + + inner = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT); + if (inner == 0){ + continue; + } + + /* Change the dtstart and dtend times in the component + pointed to by Itr*/ + + clone = icalcomponent_new_clone(itr); + inner = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT); + + assert(icalerrno == ICAL_NO_ERROR); + assert(inner !=0); + + /* DTSTART*/ + p = icalcomponent_get_first_property(inner,ICAL_DTSTART_PROPERTY); + assert(icalerrno == ICAL_NO_ERROR); + + if (p == 0){ + p = icalproperty_new_dtstart(rtime.start); + icalcomponent_add_property(inner,p); + } else { + icalproperty_set_dtstart(p,rtime.start); + } + assert(icalerrno == ICAL_NO_ERROR); + + /* DTEND*/ + p = icalcomponent_get_first_property(inner,ICAL_DTEND_PROPERTY); + assert(icalerrno == ICAL_NO_ERROR); + + if (p == 0){ + p = icalproperty_new_dtstart(rtime.end); + icalcomponent_add_property(inner,p); + } else { + icalproperty_set_dtstart(p,rtime.end); + } + assert(icalerrno == ICAL_NO_ERROR); + + printf("\n----------\n%s\n---------\n",icalcomponent_as_ical_string(inner)); + + error = icalstore_add_component(s,inner); + + assert(icalerrno == ICAL_NO_ERROR); + + } + + } + + gauge = + icalcomponent_vanew( + ICAL_VCALENDAR_COMPONENT, + icalcomponent_vanew( + ICAL_VEVENT_COMPONENT, + icalproperty_vanew_summary( + "Submit Income Taxes", + icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_EQUAL), + 0), + 0), + icalcomponent_vanew( + ICAL_VEVENT_COMPONENT, + icalproperty_vanew_summary( + "Bastille Day Party", + icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_EQUAL), + 0), + 0), + 0); + +#if 0 + + + icalstore_select(s,gauge); + + for(c = icalstore_first(s); c != 0; c = icalstore_next(s)){ + + printf("Got one! (%d)\n", count++); + + if (c != 0){ + printf("%s", icalcomponent_as_ical_string(c));; + if (icalstore_store(s2,c) == 0){ + printf("Failed to write!\n"); + } + icalcomponent_free(c); + } else { + printf("Failed to get component\n"); + } + } + + + icalstore_free(s2); +#endif + + + for(c = icalstore_get_first_component(s); + c != 0; + c = next){ + + next = icalstore_get_next_component(s); + + if (c != 0){ + /*icalstore_remove_component(s,c);*/ + printf("%s", icalcomponent_as_ical_string(c));; + } else { + printf("Failed to get component\n"); + } + + + } + + icalstore_free(s); + return 0; +} + +void test_calendar() +{ + icalcomponent *comp; + icalcluster *c; + icalstore *s; + icalcalendar* calendar = icalcalendar_new("calendar"); + icalerrorenum error; + struct icaltimetype atime = icaltimetype_from_timet( time(0),0); + + comp = icalcomponent_vanew( + ICAL_VEVENT_COMPONENT, + icalproperty_new_version("2.0"), + icalproperty_new_description("This is an event"), + icalproperty_new_dtstart(atime), + icalproperty_vanew_comment( + "Another Comment", + icalparameter_new_cn("A Common Name 1"), + icalparameter_new_cn("A Common Name 2"), + icalparameter_new_cn("A Common Name 3"), + icalparameter_new_cn("A Common Name 4"), + 0), + icalproperty_vanew_xlicerror( + "This is only a test", + icalparameter_new_xlicerrortype(ICAL_XLICERRORTYPE_COMPONENTPARSEERROR), + 0), + + 0); + + + s = icalcalendar_get_booked(calendar); + + error = icalstore_add_component(s,comp); + + assert(error == ICAL_NO_ERROR); + + c = icalcalendar_get_properties(calendar); + + error = icalcluster_add_component(c,icalcomponent_new_clone(comp)); + + assert(error == ICAL_NO_ERROR); + + icalcalendar_free(calendar); + +} + + +int main(int argc, char *argv[]) +{ + + + printf("\n------------Test Cluster---------------\n"); + test_cluster(); + +#if 0 + + printf("\n------------Test Store---------------\n"); + test_store(); + + + + printf("\n------------Test Calendar---------------\n"); + test_calendar(); + +#endif + + return 0; +} + + + diff --git a/libical/src/test/usecases.c b/libical/src/test/usecases.c index d07b5edac5..05c295197f 100644 --- a/libical/src/test/usecases.c +++ b/libical/src/test/usecases.c @@ -59,21 +59,22 @@ END:VCALENDAR */ -char str[] = "BEGIN:VCALENDAR -PRODID:\"-//RDU Software//NONSGML HandCal//EN\" -VERSION:2.0 -BEGIN:VEVENT -DTSTAMP:19980309T231000Z -UID:guid-1.host1.com -ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com -ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:MAILTO:employee-A@host.com -DESCRIPTION:Project XYZ Review Meeting -CATEGORIES:MEETING -CREATED:19980309T130000Z -SUMMARY:XYZ Project Review -DTSTART;TZID=US-Eastern:19980312T083000 -DTEND;TZID=US-Eastern:19980312T093000 -END:VEVENT + +char str[] = "BEGIN:VCALENDAR\ +PRODID:\"-//RDU Software//NONSGML HandCal//EN\"\ +VERSION:2.0\ +BEGIN:VEVENT\ +DTSTAMP:19980309T231000Z\ +UID:guid-1.host1.com\ +ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com\ +ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:MAILTO:employee-A@host.com\ +DESCRIPTION:Project XYZ Review Meeting\ +CATEGORIES:MEETING\ +CREATED:19980309T130000Z\ +SUMMARY:XYZ Project Review\ +DTSTART;TZID=US-Eastern:19980312T083000\ +DTEND;TZID=US-Eastern:19980312T093000\ +END:VEVENT\ END:VCALENDAR"; /* Creating iCal Components @@ -148,6 +149,9 @@ icalcomponent* create_new_component() If the routine returns a string ( "get" and "as_ical_string" ) The library owns the returned memory. + There are more rules, so refer to the documentation for more + details. + */ icalcomponent_add_property( @@ -515,18 +519,6 @@ void test_parameters() } -int test_parser() -{ - - - icalcomponent *c = icalparser_parse_string(str); - printf("%s\n",icalcomponent_as_ical_string(c)); - icalcomponent_free(c); - icalmemory_free_ring(); - return 1; -} - - int main(int argc, char *argv[]) { icalcomponent *c1; |