author | zautrix <zautrix> | 2004-06-29 11:59:46 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2004-06-29 11:59:46 (UTC) |
commit | da43dbdc6c82453228f34766fc74585615cba938 (patch) (side-by-side diff) | |
tree | 16576932cea08bf117b2d0320b0d5f66ee8ad093 /libical/src/libical/icalrecur.c | |
parent | 627489ea2669d3997676bc3cee0f5d0d0c16c4d4 (diff) | |
download | kdepimpi-da43dbdc6c82453228f34766fc74585615cba938.zip kdepimpi-da43dbdc6c82453228f34766fc74585615cba938.tar.gz kdepimpi-da43dbdc6c82453228f34766fc74585615cba938.tar.bz2 |
New lib ical.Some minor changes as well.
Diffstat (limited to 'libical/src/libical/icalrecur.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | libical/src/libical/icalrecur.c | 789 |
1 files changed, 433 insertions, 356 deletions
diff --git a/libical/src/libical/icalrecur.c b/libical/src/libical/icalrecur.c index 203ce70..d5a59c6 100644 --- a/libical/src/libical/icalrecur.c +++ b/libical/src/libical/icalrecur.c @@ -20,5 +20,9 @@ The Mozilla Public License Version 1.0. You may obtain a copy of the License at http://www.mozilla.org/MPL/ +*/ +/** + @file icalrecur.c + @brief Implementation of routines for dealing with recurring time How this code works: @@ -131,13 +135,12 @@ #endif +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif + #include "icalrecur.h" -#ifdef ICAL_NO_LIBICAL -#define icalerror_set_errno(x) -#define icalerror_check_arg_rv(x,y) -#else #include "icalerror.h" #include "icalmemory.h" -#endif #include <stdlib.h> /* for malloc */ @@ -149,4 +152,8 @@ #include "pvl.h" +/** This is the last year we will go up to, since 32-bit time_t values + only go up to the start of 2038. */ +#define MAX_TIME_T_YEAR 2037 + #define TEMP_MAX 1024 @@ -171,5 +178,4 @@ icalrecurrencetype_weekday icalrecur_string_to_weekday(const char* str); - /*********************** Rule parsing routines ************************/ @@ -254,5 +260,5 @@ void icalrecur_add_byrules(struct icalrecur_parser *parser, short *array, int i=0; int sign = 1; - short v; + int v; n = vals; @@ -281,4 +287,6 @@ void icalrecur_add_byrules(struct icalrecur_parser *parser, short *array, sign = 1; t++; + } else { + sign = 1; } @@ -286,5 +294,5 @@ void icalrecur_add_byrules(struct icalrecur_parser *parser, short *array, - array[i++] = v; + array[i++] = (short)v; array[i] = ICAL_RECURRENCE_ARRAY_MAX; @@ -333,19 +341,16 @@ void icalrecur_add_bydayrules(struct icalrecur_parser *parser, const char* vals) } - weekno = 0; /* Get Optional weekno */ - if( sscanf(t,"%d",&weekno) != 0){ - if (n != 0){ - int weeknolen = (n-t)-3; /* 3 -> one for \0, 2 for day name */ - /* could use abs(log10(weekno))+1, but that needs libm */ - t += weeknolen; - } else { - t = end -2; - } - } + weekno = strtol(t,&t,10); + + /* Outlook/Exchange generate "BYDAY=MO, FR" and "BYDAY=2 TH". + * Cope with that. + */ + if (*t == ' ') + t++; wd = icalrecur_string_to_weekday(t); - array[i++] = sign* ((int)wd + 8*weekno); + array[i++] = (short)(sign* (wd + 8*weekno)); array[i] = ICAL_RECURRENCE_ARRAY_MAX; @@ -388,4 +393,5 @@ struct icalrecurrencetype icalrecurrencetype_from_string(const char* str) icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); icalrecurrencetype_clear(&parser.rt); + free(parser.copy); return parser.rt; } @@ -398,5 +404,5 @@ struct icalrecurrencetype icalrecurrencetype_from_string(const char* str) parser.rt.until = icaltime_from_string(value); } else if (strcmp(name,"INTERVAL") == 0){ - parser.rt.interval = atoi(value); + parser.rt.interval = (short)atoi(value); } else if (strcmp(name,"WKST") == 0){ parser.rt.week_start = icalrecur_string_to_weekday(value); @@ -430,4 +436,5 @@ struct icalrecurrencetype icalrecurrencetype_from_string(const char* str) icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); icalrecurrencetype_clear(&parser.rt); + free(parser.copy); return parser.rt; } @@ -441,7 +448,5 @@ struct icalrecurrencetype icalrecurrencetype_from_string(const char* str) } -#ifndef ICAL_NO_LIBICAL - -struct { char* str;size_t offset; short limit; } recurmap[] = +static struct { char* str;size_t offset; int limit; } recurmap[] = { {";BYSECOND=",offsetof(struct icalrecurrencetype,by_second),60}, @@ -458,4 +463,5 @@ struct { char* str;size_t offset; short limit; } recurmap[] = /* A private routine in icalvalue.c */ +void print_date_to_string(char* str, struct icaltimetype *data); void print_datetime_to_string(char* str, struct icaltimetype *data); @@ -482,5 +488,8 @@ char* icalrecurrencetype_as_string(struct icalrecurrencetype *recur) temp[0] = 0; - print_datetime_to_string(temp,&(recur->until)); + if (recur->until.is_date) + print_date_to_string(temp,&(recur->until)); + else + print_datetime_to_string(temp,&(recur->until)); icalmemory_append_string(&str,&str_p,&buf_sz,";UNTIL="); @@ -502,5 +511,5 @@ char* icalrecurrencetype_as_string(struct icalrecurrencetype *recur) for(j =0; recurmap[j].str != 0; j++){ short* array = (short*)(recurmap[j].offset+ (size_t)recur); - short limit = recurmap[j].limit; + int limit = recurmap[j].limit; /* Skip unused arrays */ @@ -513,7 +522,7 @@ char* icalrecurrencetype_as_string(struct icalrecurrencetype *recur) i++){ if (j == 3) { /* BYDAY */ - short dow = icalrecurrencetype_day_day_of_week(array[i]); - const char *daystr = icalrecur_weekday_to_string(dow); - short pos; + const char *daystr = icalrecur_weekday_to_string( + icalrecurrencetype_day_day_of_week(array[i])); + int pos; pos = icalrecurrencetype_day_position(array[i]); @@ -541,6 +550,4 @@ char* icalrecurrencetype_as_string(struct icalrecurrencetype *recur) return str; } -#endif - @@ -574,11 +581,13 @@ struct icalrecur_iterator_impl { enum byrule byrule; short by_indices[9]; - short orig_data[9]; /* 1 if there was data in the byrule */ + short orig_data[9]; /**< 1 if there was data in the byrule */ - short *by_ptrs[9]; /* Pointers into the by_* array elements of the rule */ + short *by_ptrs[9]; /**< Pointers into the by_* array elements of the rule */ }; +static void increment_year(icalrecur_iterator* impl, int inc); + int icalrecur_iterator_sizeof_byarray(short* byarray) { @@ -600,8 +609,11 @@ enum expand_table { }; -/* The split map indicates, for a particular interval, wether a BY_* - rule part expands the number of instances in the occcurrence set or - contracts it. 1=> contract, 2=>expand, and 3 means the pairing is - not allowed. */ +/** + * The split map indicates, for a particular interval, wether a BY_* + * rule part expands the number of instances in the occcurrence set or + * contracts it. 1=> contract, 2=>expand, and 3 means the pairing is + * not allowed. + */ + struct expand_split_map_struct { @@ -614,5 +626,5 @@ struct expand_split_map_struct }; -struct expand_split_map_struct expand_map[] = +static struct expand_split_map_struct expand_map[] = { {ICAL_SECONDLY_RECURRENCE,{1,1,1,1,1,1,1,1}}, @@ -629,6 +641,7 @@ struct expand_split_map_struct expand_map[] = -/* Check that the rule has only the two given interday byrule parts. */ -int icalrecur_two_byrule(struct icalrecur_iterator_impl* impl, +/** Check that the rule has only the two given interday byrule parts. */ +static +int icalrecur_two_byrule(icalrecur_iterator* impl, enum byrule one,enum byrule two) { @@ -637,5 +650,5 @@ int icalrecur_two_byrule(struct icalrecur_iterator_impl* impl, int passes = 0; - memset(test_array,0,9); + memset(test_array,0,sizeof(test_array)); test_array[one] = 1; @@ -660,6 +673,6 @@ int icalrecur_two_byrule(struct icalrecur_iterator_impl* impl, } -/* Check that the rule has only the one given interdat byrule parts. */ -int icalrecur_one_byrule(struct icalrecur_iterator_impl* impl,enum byrule one) +/** Check that the rule has only the one given interdat byrule parts. */ +static int icalrecur_one_byrule(icalrecur_iterator* impl,enum byrule one) { int passes = 1; @@ -677,5 +690,5 @@ int icalrecur_one_byrule(struct icalrecur_iterator_impl* impl,enum byrule one) } -int count_byrules(struct icalrecur_iterator_impl* impl) +static int count_byrules(icalrecur_iterator* impl) { int count = 0; @@ -692,7 +705,7 @@ int count_byrules(struct icalrecur_iterator_impl* impl) -void setup_defaults(struct icalrecur_iterator_impl* impl, +static void setup_defaults(icalrecur_iterator* impl, enum byrule byrule, icalrecurrencetype_frequency req, - short deftime, int *timepart) + int deftime, int *timepart) { @@ -705,5 +718,5 @@ void setup_defaults(struct icalrecur_iterator_impl* impl, if(impl->by_ptrs[byrule][0] == ICAL_RECURRENCE_ARRAY_MAX && expand_map[freq].map[byrule] != CONTRACT){ - impl->by_ptrs[byrule][0] = deftime; + impl->by_ptrs[byrule][0] = (short)deftime; } @@ -716,5 +729,5 @@ void setup_defaults(struct icalrecur_iterator_impl* impl, } -int has_by_data(struct icalrecur_iterator_impl* impl, enum byrule byrule){ +static int has_by_data(icalrecur_iterator* impl, enum byrule byrule){ return (impl->orig_data[byrule] == 1); @@ -722,5 +735,5 @@ int has_by_data(struct icalrecur_iterator_impl* impl, enum byrule byrule){ -int expand_year_days(struct icalrecur_iterator_impl* impl,short year); +static int expand_year_days(icalrecur_iterator* impl, int year); @@ -728,16 +741,14 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, struct icaltimetype dtstart) { - struct icalrecur_iterator_impl* impl; + icalrecur_iterator* impl; icalrecurrencetype_frequency freq; - short days_in_month; - - if ( ( impl = (struct icalrecur_iterator_impl *) - malloc(sizeof(struct icalrecur_iterator_impl))) == 0) { + if ( ( impl = (icalrecur_iterator*) + malloc(sizeof(icalrecur_iterator))) == 0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } - memset(impl,0,sizeof(struct icalrecur_iterator_impl)); + memset(impl,0,sizeof(icalrecur_iterator)); impl->rule = rule; @@ -761,5 +772,5 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, impl->by_ptrs[BY_SET_POS]=impl->rule.by_set_pos; - memset(impl->orig_data,0,9); + memset(impl->orig_data,0,9*sizeof(short)); /* Note which by rules had data in them when the iterator was @@ -769,21 +780,21 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, impl->orig_data[BY_MONTH] - = (impl->rule.by_month[0]!=ICAL_RECURRENCE_ARRAY_MAX); + = (short)(impl->rule.by_month[0]!=ICAL_RECURRENCE_ARRAY_MAX); impl->orig_data[BY_WEEK_NO] - =(impl->rule.by_week_no[0]!=ICAL_RECURRENCE_ARRAY_MAX); + =(short)(impl->rule.by_week_no[0]!=ICAL_RECURRENCE_ARRAY_MAX); impl->orig_data[BY_YEAR_DAY] - =(impl->rule.by_year_day[0]!=ICAL_RECURRENCE_ARRAY_MAX); + =(short)(impl->rule.by_year_day[0]!=ICAL_RECURRENCE_ARRAY_MAX); impl->orig_data[BY_MONTH_DAY] - =(impl->rule.by_month_day[0]!=ICAL_RECURRENCE_ARRAY_MAX); + =(short)(impl->rule.by_month_day[0]!=ICAL_RECURRENCE_ARRAY_MAX); impl->orig_data[BY_DAY] - = (impl->rule.by_day[0]!=ICAL_RECURRENCE_ARRAY_MAX); + = (short)(impl->rule.by_day[0]!=ICAL_RECURRENCE_ARRAY_MAX); impl->orig_data[BY_HOUR] - = (impl->rule.by_hour[0]!=ICAL_RECURRENCE_ARRAY_MAX); + = (short)(impl->rule.by_hour[0]!=ICAL_RECURRENCE_ARRAY_MAX); impl->orig_data[BY_MINUTE] - = (impl->rule.by_minute[0]!=ICAL_RECURRENCE_ARRAY_MAX); + = (short)(impl->rule.by_minute[0]!=ICAL_RECURRENCE_ARRAY_MAX); impl->orig_data[BY_SECOND] - = (impl->rule.by_second[0]!=ICAL_RECURRENCE_ARRAY_MAX); + = (short)(impl->rule.by_second[0]!=ICAL_RECURRENCE_ARRAY_MAX); impl->orig_data[BY_SET_POS] - = (impl->rule.by_set_pos[0]!=ICAL_RECURRENCE_ARRAY_MAX); + = (short)(impl->rule.by_set_pos[0]!=ICAL_RECURRENCE_ARRAY_MAX); @@ -853,17 +864,22 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, - setup_defaults(impl,BY_SECOND,ICAL_SECONDLY_RECURRENCE,impl->dtstart.second, + setup_defaults(impl,BY_SECOND,ICAL_SECONDLY_RECURRENCE, + impl->dtstart.second, &(impl->last.second)); - setup_defaults(impl,BY_MINUTE,ICAL_MINUTELY_RECURRENCE,impl->dtstart.minute, + setup_defaults(impl,BY_MINUTE,ICAL_MINUTELY_RECURRENCE, + impl->dtstart.minute, &(impl->last.minute)); - setup_defaults(impl,BY_HOUR,ICAL_HOURLY_RECURRENCE,impl->dtstart.hour, + setup_defaults(impl,BY_HOUR,ICAL_HOURLY_RECURRENCE, + impl->dtstart.hour, &(impl->last.hour)); - setup_defaults(impl,BY_MONTH_DAY,ICAL_DAILY_RECURRENCE,impl->dtstart.day, + setup_defaults(impl,BY_MONTH_DAY,ICAL_DAILY_RECURRENCE, + impl->dtstart.day, &(impl->last.day)); - setup_defaults(impl,BY_MONTH,ICAL_MONTHLY_RECURRENCE,impl->dtstart.month, + setup_defaults(impl,BY_MONTH,ICAL_MONTHLY_RECURRENCE, + impl->dtstart.month, &(impl->last.month)); @@ -875,5 +891,5 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, /* Weekly recurrences with no BY_DAY data should occur on the same day of the week as the start time . */ - impl->by_ptrs[BY_DAY][0] = icaltime_day_of_week(impl->dtstart); + impl->by_ptrs[BY_DAY][0] = (short)icaltime_day_of_week(impl->dtstart); } else { @@ -889,5 +905,5 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, general way to solve this problem */ - short dow = impl->by_ptrs[BY_DAY][0]-icaltime_day_of_week(impl->last); + short dow = (short)(impl->by_ptrs[BY_DAY][0]-icaltime_day_of_week(impl->last)); if(dow < 0) { @@ -902,8 +918,22 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, } - /* For YEARLY rule, begin by setting up the year days array */ + /* For YEARLY rule, begin by setting up the year days array . The + YEARLY rules work by expanding one year at a time. */ if(impl->rule.freq == ICAL_YEARLY_RECURRENCE){ - expand_year_days(impl,impl->last.year); + struct icaltimetype next; + + for (;;) { + expand_year_days(impl, impl->last.year); + if (impl->days[0] != ICAL_RECURRENCE_ARRAY_MAX) + break; /* break when no days are expanded */ + increment_year(impl,impl->rule.interval); + } + + /* Copy the first day into last. */ + next = icaltime_from_day_of_year(impl->days[0], impl->last.year); + + impl->last.day = next.day; + impl->last.month = next.month; } @@ -915,11 +945,11 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, has_by_data(impl,BY_DAY)) { - short dow = icalrecurrencetype_day_day_of_week( + int dow = icalrecurrencetype_day_day_of_week( impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]]); - short pos = icalrecurrencetype_day_position( + int pos = icalrecurrencetype_day_position( impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]]); - short poscount = 0; - days_in_month = + int poscount = 0; + int days_in_month = icaltime_days_in_month(impl->last.month, impl->last.year); @@ -970,24 +1000,19 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, void icalrecur_iterator_free(icalrecur_iterator* i) { + icalerror_check_arg_rv((i!=0),"impl"); - struct icalrecur_iterator_impl* impl = - (struct icalrecur_iterator_impl*)i; - - icalerror_check_arg_rv((impl!=0),"impl"); - - free(impl); + free(i); } - -void increment_year(struct icalrecur_iterator_impl* impl, int inc) +static void increment_year(icalrecur_iterator* impl, int inc) { impl->last.year+=inc; } -/* Increment month is different that the other incement_* routines -- +/** Increment month is different that the other incement_* routines -- it figures out the interval for itself, and uses BYMONTH data if available. */ -void increment_month(struct icalrecur_iterator_impl* impl) +static void increment_month(icalrecur_iterator* impl) { int years; @@ -1036,5 +1061,5 @@ void increment_month(struct icalrecur_iterator_impl* impl) } -void increment_monthday(struct icalrecur_iterator_impl* impl, int inc) +static void increment_monthday(icalrecur_iterator* impl, int inc) { int i; @@ -1042,6 +1067,6 @@ void increment_monthday(struct icalrecur_iterator_impl* impl, int inc) for(i=0; i<inc; i++){ - short days_in_month = - icaltime_days_in_month(impl->last.month,impl->last.year); + int days_in_month = + icaltime_days_in_month(impl->last.month, impl->last.year); impl->last.day++; @@ -1055,7 +1080,7 @@ void increment_monthday(struct icalrecur_iterator_impl* impl, int inc) -void increment_hour(struct icalrecur_iterator_impl* impl, int inc) +static void increment_hour(icalrecur_iterator* impl, int inc) { - short days; + int days; impl->last.hour+=inc; @@ -1069,7 +1094,7 @@ void increment_hour(struct icalrecur_iterator_impl* impl, int inc) } -void increment_minute(struct icalrecur_iterator_impl* impl, int inc) +static void increment_minute(icalrecur_iterator* impl, int inc) { - short hours; + int hours; impl->last.minute+=inc; @@ -1084,7 +1109,7 @@ void increment_minute(struct icalrecur_iterator_impl* impl, int inc) } -void increment_second(struct icalrecur_iterator_impl* impl, int inc) +static void increment_second(icalrecur_iterator* impl, int inc) { - short minutes; + int minutes; impl->last.second+=inc; @@ -1103,5 +1128,5 @@ void increment_second(struct icalrecur_iterator_impl* impl, int inc) void test_increment() { - struct icalrecur_iterator_impl impl; + icalrecur_iterator impl; impl.last = icaltime_from_string("20000101T000000Z"); @@ -1133,15 +1158,15 @@ void test_increment() #endif -short next_second(struct icalrecur_iterator_impl* impl) +static int next_second(icalrecur_iterator* impl) { - short has_by_data = (impl->by_ptrs[BY_SECOND][0]!=ICAL_RECURRENCE_ARRAY_MAX); - short this_frequency = (impl->rule.freq == ICAL_SECONDLY_RECURRENCE); + int has_by_second = (impl->by_ptrs[BY_SECOND][0]!=ICAL_RECURRENCE_ARRAY_MAX); + int this_frequency = (impl->rule.freq == ICAL_SECONDLY_RECURRENCE); - short end_of_data = 0; + int end_of_data = 0; - assert(has_by_data || this_frequency); + assert(has_by_second || this_frequency); - if( has_by_data ){ + if( has_by_second ){ /* Ignore the frequency and use the byrule data */ @@ -1160,5 +1185,5 @@ short next_second(struct icalrecur_iterator_impl* impl) - } else if( !has_by_data && this_frequency ){ + } else if( !has_by_second && this_frequency ){ /* Compute the next value from the last time and the frequency interval*/ increment_second(impl, impl->rule.interval); @@ -1169,5 +1194,5 @@ short next_second(struct icalrecur_iterator_impl* impl) need to move to the next minute */ - if(has_by_data && end_of_data && this_frequency ){ + if(has_by_second && end_of_data && this_frequency ){ increment_minute(impl,1); } @@ -1177,13 +1202,13 @@ short next_second(struct icalrecur_iterator_impl* impl) } -int next_minute(struct icalrecur_iterator_impl* impl) +static int next_minute(icalrecur_iterator* impl) { - short has_by_data = (impl->by_ptrs[BY_MINUTE][0]!=ICAL_RECURRENCE_ARRAY_MAX); - short this_frequency = (impl->rule.freq == ICAL_MINUTELY_RECURRENCE); + int has_by_minute = (impl->by_ptrs[BY_MINUTE][0]!=ICAL_RECURRENCE_ARRAY_MAX); + int this_frequency = (impl->rule.freq == ICAL_MINUTELY_RECURRENCE); - short end_of_data = 0; + int end_of_data = 0; - assert(has_by_data || this_frequency); + assert(has_by_minute || this_frequency); @@ -1192,5 +1217,5 @@ int next_minute(struct icalrecur_iterator_impl* impl) } - if( has_by_data ){ + if( has_by_minute ){ /* Ignore the frequency and use the byrule data */ @@ -1208,5 +1233,5 @@ int next_minute(struct icalrecur_iterator_impl* impl) impl->by_ptrs[BY_MINUTE][impl->by_indices[BY_MINUTE]]; - } else if( !has_by_data && this_frequency ){ + } else if( !has_by_minute && this_frequency ){ /* Compute the next value from the last time and the frequency interval*/ increment_minute(impl,impl->rule.interval); @@ -1216,5 +1241,5 @@ int next_minute(struct icalrecur_iterator_impl* impl) need to move to the next hour */ - if(has_by_data && end_of_data && this_frequency ){ + if(has_by_minute && end_of_data && this_frequency ){ increment_hour(impl,1); } @@ -1223,13 +1248,13 @@ int next_minute(struct icalrecur_iterator_impl* impl) } -int next_hour(struct icalrecur_iterator_impl* impl) +static int next_hour(icalrecur_iterator* impl) { - short has_by_data = (impl->by_ptrs[BY_HOUR][0]!=ICAL_RECURRENCE_ARRAY_MAX); - short this_frequency = (impl->rule.freq == ICAL_HOURLY_RECURRENCE); + int has_by_hour = (impl->by_ptrs[BY_HOUR][0]!=ICAL_RECURRENCE_ARRAY_MAX); + int this_frequency = (impl->rule.freq == ICAL_HOURLY_RECURRENCE); - short end_of_data = 0; + int end_of_data = 0; - assert(has_by_data || this_frequency); + assert(has_by_hour || this_frequency); if (next_minute(impl) == 0){ @@ -1237,5 +1262,5 @@ int next_hour(struct icalrecur_iterator_impl* impl) } - if( has_by_data ){ + if( has_by_hour ){ /* Ignore the frequency and use the byrule data */ @@ -1252,5 +1277,5 @@ int next_hour(struct icalrecur_iterator_impl* impl) impl->by_ptrs[BY_HOUR][impl->by_indices[BY_HOUR]]; - } else if( !has_by_data && this_frequency ){ + } else if( !has_by_hour && this_frequency ){ /* Compute the next value from the last time and the frequency interval*/ increment_hour(impl,impl->rule.interval); @@ -1261,5 +1286,5 @@ int next_hour(struct icalrecur_iterator_impl* impl) need to move to the next day */ - if(has_by_data && end_of_data && this_frequency ){ + if(has_by_hour && end_of_data && this_frequency ){ increment_monthday(impl,1); } @@ -1269,11 +1294,11 @@ int next_hour(struct icalrecur_iterator_impl* impl) } -int next_day(struct icalrecur_iterator_impl* impl) +static int next_day(icalrecur_iterator* impl) { - short has_by_data = (impl->by_ptrs[BY_DAY][0]!=ICAL_RECURRENCE_ARRAY_MAX); - short this_frequency = (impl->rule.freq == ICAL_DAILY_RECURRENCE); + int has_by_day = (impl->by_ptrs[BY_DAY][0]!=ICAL_RECURRENCE_ARRAY_MAX); + int this_frequency = (impl->rule.freq == ICAL_DAILY_RECURRENCE); - assert(has_by_data || this_frequency); + assert(has_by_day || this_frequency); if (next_hour(impl) == 0){ @@ -1297,12 +1322,12 @@ int next_day(struct icalrecur_iterator_impl* impl) -int next_yearday(struct icalrecur_iterator_impl* impl) +static int next_yearday(icalrecur_iterator* impl) { - short has_by_data = (impl->by_ptrs[BY_YEAR_DAY][0]!=ICAL_RECURRENCE_ARRAY_MAX); + int has_by_yearday = (impl->by_ptrs[BY_YEAR_DAY][0]!=ICAL_RECURRENCE_ARRAY_MAX); - short end_of_data = 0; + int end_of_data = 0; - assert(has_by_data ); + assert(has_by_yearday ); if (next_hour(impl) == 0){ @@ -1322,5 +1347,5 @@ int next_yearday(struct icalrecur_iterator_impl* impl) impl->by_ptrs[BY_YEAR_DAY][impl->by_indices[BY_YEAR_DAY]]; - if(has_by_data && end_of_data){ + if(has_by_yearday && end_of_data){ increment_year(impl,1); } @@ -1330,60 +1355,13 @@ int next_yearday(struct icalrecur_iterator_impl* impl) } -/* This routine is only called by next_week. It is certain that BY_DAY -has data */ - -int next_weekday_by_week(struct icalrecur_iterator_impl* impl) -{ - - short end_of_data = 0; - short start_of_week, dow; - struct icaltimetype next; - - if (next_hour(impl) == 0){ - return 0; - } - - assert( impl->by_ptrs[BY_DAY][0]!=ICAL_RECURRENCE_ARRAY_MAX); - - while(1) { - - impl->by_indices[BY_DAY]++; /* Look at next elem in BYDAY array */ - - /* Are we at the end of the BYDAY array? */ - if (impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]] - ==ICAL_RECURRENCE_ARRAY_MAX){ - - impl->by_indices[BY_DAY] = 0; /* Reset to 0 */ - end_of_data = 1; /* Signal that we're at the end */ - } - - /* Add the day of week offset to to the start of this week, and use - that to get the next day */ - dow = impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]]; - start_of_week = icaltime_start_doy_of_week(impl->last); - - dow--; /*Sun is 1, not 0 */ - - if(dow+start_of_week <1 && !end_of_data){ - /* The selected date is in the previous year. */ - continue; - } - - next = icaltime_from_day_of_year(start_of_week + dow,impl->last.year); - - impl->last.day = next.day; - impl->last.month = next.month; - impl->last.year = next.year; - - return end_of_data; - } -} +/* Returns the day of the month for the current month of t that is the + pos'th instance of the day-of-week dow */ -int nth_weekday(short dow, short pos, struct icaltimetype t){ +static int nth_weekday(int dow, int pos, struct icaltimetype t){ - short days_in_month = icaltime_days_in_month(t.month,t.year); - short end_dow, start_dow; - short wd; + int days_in_month = icaltime_days_in_month(t.month, t.year); + int end_dow, start_dow; + int wd; if(pos >= 0){ @@ -1429,10 +1407,27 @@ int nth_weekday(short dow, short pos, struct icaltimetype t){ } +static int is_day_in_byday(icalrecur_iterator* impl,struct icaltimetype tt){ + + int idx; -int next_month(struct icalrecur_iterator_impl* impl) + for(idx = 0; BYDAYPTR[idx] != ICAL_RECURRENCE_ARRAY_MAX; idx++){ + int dow = icalrecurrencetype_day_day_of_week(BYDAYPTR[idx]); + int pos = icalrecurrencetype_day_position(BYDAYPTR[idx]); + int this_dow = icaltime_day_of_week(tt); + + if( (pos == 0 && dow == this_dow ) || /* Just a dow, like "TU" or "FR" */ + (nth_weekday(dow,pos,tt) == tt.day)){ /*pos+wod: "3FR" or -1TU" */ + return 1; + } + } + + return 0; +} + +static int next_month(icalrecur_iterator* impl) { int data_valid = 1; - short this_frequency = (impl->rule.freq == ICAL_MONTHLY_RECURRENCE); + int this_frequency = (impl->rule.freq == ICAL_MONTHLY_RECURRENCE); assert( has_by_data(impl,BY_MONTH) || this_frequency); @@ -1446,12 +1441,15 @@ int next_month(struct icalrecur_iterator_impl* impl) } - /* Now iterate through the occurrences within a month -- by days, weeks or weekdays. */ + + /* + * Case 1: + * Rules Like: FREQ=MONTHLY;INTERVAL=1;BYDAY=FR;BYMONTHDAY=13 + */ if(has_by_data(impl,BY_DAY) && has_by_data(impl,BY_MONTH_DAY)){ - /* Cases like: FREQ=MONTHLY;INTERVAL=1;BYDAY=FR;BYMONTHDAY=13 */ - short day, idx,j; - short days_in_month = icaltime_days_in_month(impl->last.month, + int day, idx,j; + int days_in_month = icaltime_days_in_month(impl->last.month, impl->last.year); /* Iterate through the remaining days in the month and check if @@ -1464,9 +1462,9 @@ int next_month(struct icalrecur_iterator_impl* impl) for(idx = 0; BYDAYPTR[idx] != ICAL_RECURRENCE_ARRAY_MAX; idx++){ for(j = 0; BYMDPTR[j]!=ICAL_RECURRENCE_ARRAY_MAX; j++){ - short dow = + int dow = icalrecurrencetype_day_day_of_week(BYDAYPTR[idx]); - short pos = icalrecurrencetype_day_position(BYDAYPTR[idx]); - short mday = BYMDPTR[j]; - short this_dow; + int pos = icalrecurrencetype_day_position(BYDAYPTR[idx]); + int mday = BYMDPTR[j]; + int this_dow; impl->last.day = day; @@ -1489,49 +1487,55 @@ int next_month(struct icalrecur_iterator_impl* impl) } - + + /* + * Case 2: + * Rules Like: FREQ=MONTHLY;INTERVAL=1;BYDAY=FR + */ + } else if(has_by_data(impl,BY_DAY)){ - /* Cases like: FREQ=MONTHLY;INTERVAL=1;BYDAY=FR */ /* For this case, the weekdays are relative to the month. BYDAY=FR -> First Friday in month, etc. */ - short day, idx; - short days_in_month = icaltime_days_in_month(impl->last.month, - impl->last.year); + /* This code iterates through the remaining days in the month + and checks if each day is listed in the BY_DAY array. This + seems very inneficient, but I think it is the simplest way to + account for both BYDAY=1FR (First friday in month) and + BYDAY=FR ( every friday in month ) */ + int day; + int days_in_month = icaltime_days_in_month(impl->last.month, + impl->last.year); assert( BYDAYPTR[0]!=ICAL_RECURRENCE_ARRAY_MAX); - /* Iterate through the remaining days in the month and check if - each day is listed in the BY_DAY array. This seems very - inneficient, but I think it is the simplest way to account - for both BYDAY=1FR (First friday in month) and BYDAY=FR ( - every friday in month ) */ - for(day = impl->last.day+1; day <= days_in_month; day++){ - for(idx = 0; BYDAYPTR[idx] != ICAL_RECURRENCE_ARRAY_MAX; idx++){ - short dow = icalrecurrencetype_day_day_of_week(BYDAYPTR[idx]); - short pos = icalrecurrencetype_day_position(BYDAYPTR[idx]); - short this_dow; - - impl->last.day = day; - this_dow = icaltime_day_of_week(impl->last); - - if( (pos == 0 && dow == this_dow ) || - (nth_weekday(dow,pos,impl->last) == day)){ - goto DEND; - } + impl->last.day = day; + if(is_day_in_byday(impl,impl->last)){ + data_valid = 1; + break; } } - DEND: - if ( day > days_in_month){ impl->last.day = 1; increment_month(impl); - data_valid = 0; /* signal that impl->last is invalid */ + + /* Did moving to the next month put us on a valid date? if + so, note that the new data is valid, if, not, mark it + invalid */ + + if(is_day_in_byday(impl,impl->last)){ + data_valid = 1; + } else { + data_valid = 0; /* signal that impl->last is invalid */ + } } + /* + * Case 3 + * Rules Like: FREQ=MONTHLY;COUNT=10;BYMONTHDAY=-3 + */ + } else if (has_by_data(impl,BY_MONTH_DAY)) { - /* Cases like: FREQ=MONTHLY;COUNT=10;BYMONTHDAY=-3 */ - short day; + int day; assert( BYMDPTR[0]!=ICAL_RECURRENCE_ARRAY_MAX); @@ -1549,6 +1553,5 @@ int next_month(struct icalrecur_iterator_impl* impl) if (day < 0) { - day = icaltime_days_in_month(impl->last.month,impl->last.year)+ - day + 1; + day = icaltime_days_in_month(impl->last.month, impl->last.year) + day + 1; } @@ -1559,16 +1562,70 @@ int next_month(struct icalrecur_iterator_impl* impl) } - return data_valid; /* Signal that the data is valid */ + return data_valid; } +static int next_weekday_by_week(icalrecur_iterator* impl) +{ + + int end_of_data = 0; + int start_of_week, dow; + struct icaltimetype next; + + if (next_hour(impl) == 0){ + return 0; + } + + if(!has_by_data(impl,BY_DAY)){ + return 1; + } + + /* If we get here, we need to step to tne next day */ + + for (;;) { + struct icaltimetype tt = icaltime_null_time(); + BYDAYIDX++; /* Look at next elem in BYDAY array */ + + /* Are we at the end of the BYDAY array? */ + if (BYDAYPTR[BYDAYIDX]==ICAL_RECURRENCE_ARRAY_MAX){ + BYDAYIDX = 0; /* Reset to 0 */ + end_of_data = 1; /* Signal that we're at the end */ + } + + /* Add the day of week offset to to the start of this week, and use + that to get the next day */ + /* ignore position of dow ("4FR"), only use dow ("FR")*/ + dow = icalrecurrencetype_day_day_of_week(BYDAYPTR[BYDAYIDX]); + tt.year = impl->last.year; + tt.day = impl->last.day; + tt.month = impl->last.month; + + start_of_week = icaltime_start_doy_of_week(tt); + + dow--; /* Set Sunday to be 0 */ + + if(dow+start_of_week <1){ + /* The selected date is in the previous year. */ + if(!end_of_data){ + continue; + } + } + + next = icaltime_from_day_of_year(start_of_week + dow,impl->last.year); + + impl->last.day = next.day; + impl->last.month = next.month; + impl->last.year = next.year; + + return end_of_data; + } + +} -int next_week(struct icalrecur_iterator_impl* impl) +static int next_week(icalrecur_iterator* impl) { - short has_by_data = (impl->by_ptrs[BY_WEEK_NO][0]!=ICAL_RECURRENCE_ARRAY_MAX); - short this_frequency = (impl->rule.freq == ICAL_WEEKLY_RECURRENCE); - short end_of_data = 0; + int end_of_data = 0; - /* Increment to the next week day */ + /* Increment to the next week day, if there is data at a level less than a week */ if (next_weekday_by_week(impl) == 0){ return 0; /* Have not reached end of week yet */ @@ -1578,6 +1635,6 @@ int next_week(struct icalrecur_iterator_impl* impl) can increment to the next week */ - - if( has_by_data){ + if( has_by_data(impl,BY_WEEK_NO)){ + /*FREQ=WEEKLY;BYWEEK=20*/ /* Use the Week Number byrule data */ int week_no; @@ -1603,11 +1660,10 @@ int next_week(struct icalrecur_iterator_impl* impl) impl->last = icaltime_normalize(impl->last); - } else if( !has_by_data && this_frequency ){ - /* If there is no BY_WEEK_NO data, just jump forward 7 days. */ + } else { + /* Jump to the next week */ increment_monthday(impl,7*impl->rule.interval); } - - if(has_by_data && end_of_data && this_frequency ){ + if( has_by_data(impl,BY_WEEK_NO) && end_of_data){ increment_year(impl,1); } @@ -1617,6 +1673,6 @@ int next_week(struct icalrecur_iterator_impl* impl) } -/* Expand the BYDAY rule part and return a pointer to a newly allocated list of days. */ -pvl_list expand_by_day(struct icalrecur_iterator_impl* impl,short year) +/** Expand the BYDAY rule part and return a pointer to a newly allocated list of days. */ +static pvl_list expand_by_day(icalrecur_iterator* impl, int year) { /* Try to calculate each of the occurrences. */ @@ -1624,5 +1680,5 @@ pvl_list expand_by_day(struct icalrecur_iterator_impl* impl,short year) pvl_list days_list = pvl_newlist(); - short start_dow, end_dow, end_year_day, start_doy; + int start_dow, end_dow, end_year_day; struct icaltimetype tmp = impl->last; @@ -1632,12 +1688,12 @@ pvl_list expand_by_day(struct icalrecur_iterator_impl* impl,short year) tmp.is_date = 1; + /* Find the day that 1st Jan falls on, 1 (Sun) to 7 (Sat). */ start_dow = icaltime_day_of_week(tmp); - start_doy = icaltime_start_doy_of_week(tmp); /* Get the last day of the year*/ - tmp.year++; - tmp = icaltime_normalize(tmp); - tmp.day--; - tmp = icaltime_normalize(tmp); + tmp.year= year; + tmp.month = 12; + tmp.day = 31; + tmp.is_date = 1; end_dow = icaltime_day_of_week(tmp); @@ -1645,7 +1701,8 @@ pvl_list expand_by_day(struct icalrecur_iterator_impl* impl,short year) for(i = 0; BYDAYPTR[i] != ICAL_RECURRENCE_ARRAY_MAX; i++){ - short dow = + /* This is 1 (Sun) to 7 (Sat). */ + int dow = icalrecurrencetype_day_day_of_week(BYDAYPTR[i]); - short pos = icalrecurrencetype_day_position(BYDAYPTR[i]); + int pos = icalrecurrencetype_day_position(BYDAYPTR[i]); if(pos == 0){ @@ -1653,14 +1710,11 @@ pvl_list expand_by_day(struct icalrecur_iterator_impl* impl,short year) a bare day of the week ( BYDAY=SU) so add all of the days of the year with this day-of-week*/ - int week; - for(week = 0; week < 52 ; week ++){ - short doy = start_doy + (week * 7) + dow-1; + int doy, tmp_start_doy; - if(doy > end_year_day){ - break; - } else { + tmp_start_doy = ((dow + 7 - start_dow) % 7) + 1; + + for (doy = tmp_start_doy; doy <= end_year_day; doy += 7) pvl_push(days_list,(void*)(int)doy); - } - } + } else if ( pos > 0) { int first; @@ -1672,5 +1726,5 @@ pvl_list expand_by_day(struct icalrecur_iterator_impl* impl,short year) } - /* THen just multiple the position times 7 to get the pos'th day in the year */ + /* Then just multiple the position times 7 to get the pos'th day in the year */ pvl_push(days_list,(void*)(first+ (pos-1) * 7)); @@ -1697,5 +1751,5 @@ pvl_list expand_by_day(struct icalrecur_iterator_impl* impl,short year) rule. */ -int expand_year_days(struct icalrecur_iterator_impl* impl,short year) +static int expand_year_days(icalrecur_iterator* impl, int year) { int j,k; @@ -1704,13 +1758,14 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year) int flags; - t = icaltime_null_time(); + t = icaltime_null_date(); #define HBD(x) has_by_data(impl,x) - t.is_date = 1; /* Needed to make day_of_year routines work property */ - - memset(&t,0,sizeof(t)); memset(impl->days,ICAL_RECURRENCE_ARRAY_MAX_BYTE,sizeof(impl->days)); + /* The flags and the following switch statement select which code + to use to expand the yers days, based on which BY-rules are + present. */ + flags = (HBD(BY_DAY) ? 1<<BY_DAY : 0) + (HBD(BY_WEEK_NO) ? 1<<BY_WEEK_NO : 0) + @@ -1724,5 +1779,9 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year) case 0: { /* FREQ=YEARLY; */ + t = impl->dtstart; + t.year = impl->last.year; + impl->days[days_index++] = (short)icaltime_day_of_year(t); + break; } @@ -1731,7 +1790,6 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year) for(j=0;impl->by_ptrs[BY_MONTH][j]!=ICAL_RECURRENCE_ARRAY_MAX;j++){ - struct icaltimetype t; - short month = impl->by_ptrs[BY_MONTH][j]; - short doy; + int month = impl->by_ptrs[BY_MONTH][j]; + int doy; t = impl->dtstart; @@ -1742,5 +1800,5 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year) doy = icaltime_day_of_year(t); - impl->days[days_index++] = doy; + impl->days[days_index++] = (short)doy; } @@ -1752,6 +1810,6 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year) for(k=0;impl->by_ptrs[BY_MONTH_DAY][k]!=ICAL_RECURRENCE_ARRAY_MAX;k++) { - short month_day = impl->by_ptrs[BY_MONTH_DAY][k]; - short doy; + int month_day = impl->by_ptrs[BY_MONTH_DAY][k]; + int doy; t = impl->dtstart; @@ -1762,5 +1820,5 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year) doy = icaltime_day_of_year(t); - impl->days[days_index++] = doy; + impl->days[days_index++] = (short)doy; } @@ -1774,7 +1832,7 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year) for(k=0;impl->by_ptrs[BY_MONTH_DAY][k]!=ICAL_RECURRENCE_ARRAY_MAX;k++) { - short month = impl->by_ptrs[BY_MONTH][j]; - short month_day = impl->by_ptrs[BY_MONTH_DAY][k]; - short doy; + int month = impl->by_ptrs[BY_MONTH][j]; + int month_day = impl->by_ptrs[BY_MONTH_DAY][k]; + int doy; t.day = month_day; @@ -1785,5 +1843,5 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year) doy = icaltime_day_of_year(t); - impl->days[days_index++] = doy; + impl->days[days_index++] = (short)doy; } @@ -1796,6 +1854,5 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year) /* FREQ=YEARLY; BYWEEKNO=20,50 */ - struct icaltimetype t; - short dow; + int dow; t.day = impl->dtstart.day; @@ -1820,5 +1877,4 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year) case 1<<BY_DAY: { /*FREQ=YEARLY; BYDAY=TH,20MO,-10FR*/ - int days_index = 0; pvl_elem i; pvl_list days = expand_by_day(impl,year); @@ -1826,5 +1882,5 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year) for(i=pvl_head(days);i!=0;i=pvl_next(i)){ - short day = (short)(int)pvl_data(i); + short day = (short)(*((int*)pvl_data(i))); impl->days[days_index++] = day; } @@ -1838,29 +1894,57 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year) /*FREQ=YEARLY; BYDAY=TH,20MO,-10FR; BYMONTH = 12*/ - int days_index = 0; - pvl_elem itr; - pvl_list days = expand_by_day(impl,year); - for(itr=pvl_head(days);itr!=0;itr=pvl_next(itr)){ - short doy = (short)(int)pvl_data(itr); - struct icaltimetype tt; - short j; + for(j=0;impl->by_ptrs[BY_MONTH][j]!=ICAL_RECURRENCE_ARRAY_MAX;j++){ + int month = impl->by_ptrs[BY_MONTH][j]; + int days_in_month = icaltime_days_in_month(month,year); + int first_dow, last_dow, doy_offset; - tt = icaltime_from_day_of_year(doy,year); + t.year = year; + t.month = month; + t.day = 1; + t.is_date = 1; - for(j=0; - impl->by_ptrs[BY_MONTH][j]!=ICAL_RECURRENCE_ARRAY_MAX; - j++){ - short month = impl->by_ptrs[BY_MONTH][j]; + first_dow = icaltime_day_of_week(t); - if(tt.month == month){ - impl->days[days_index++] = doy; - } - } + /* This holds the day offset used to calculate the day of the year + from the month day. Just add the month day to this. */ + doy_offset = icaltime_day_of_year(t) - 1; - } + t.day = days_in_month; + last_dow = icaltime_day_of_week(t); - pvl_free(days); + for(k=0;impl->by_ptrs[BY_DAY][k]!=ICAL_RECURRENCE_ARRAY_MAX;k++){ + short day_coded = impl->by_ptrs[BY_DAY][k]; + enum icalrecurrencetype_weekday dow = + icalrecurrencetype_day_day_of_week(day_coded); + int pos = icalrecurrencetype_day_position(day_coded); + int first_matching_day, last_matching_day, day, month_day; + + /* Calculate the first day in the month with the given weekday, + and the last day. */ + first_matching_day = ((dow + 7 - first_dow) % 7) + 1; + last_matching_day = days_in_month - ((last_dow + 7 - dow) % 7); + + if (pos == 0) { + /* Add all of instances of the weekday within the month. */ + for (day = first_matching_day; day <= days_in_month; day += 7) + impl->days[days_index++] = (short)(doy_offset + day); + + } else if (pos > 0) { + /* Add the nth instance of the weekday within the month. */ + month_day = first_matching_day + (pos - 1) * 7; + + if (month_day <= days_in_month) + impl->days[days_index++] = (short)(doy_offset + month_day); + } else { + /* Add the -nth instance of the weekday within the month.*/ + month_day = last_matching_day + (pos + 1) * 7; + + if (month_day > 0) + impl->days[days_index++] = (short)(doy_offset + month_day); + } + } + } break; } @@ -1869,17 +1953,15 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year) /*FREQ=YEARLY; BYDAY=TH,20MO,-10FR; BYMONTHDAY=1,15*/ - int days_index = 0; pvl_elem itr; pvl_list days = expand_by_day(impl,year); for(itr=pvl_head(days);itr!=0;itr=pvl_next(itr)){ - short day = (short)(int)pvl_data(itr); + short day = (short)(*((int*)pvl_data(itr))); struct icaltimetype tt; - short j; tt = icaltime_from_day_of_year(day,year); for(j = 0; BYMDPTR[j]!=ICAL_RECURRENCE_ARRAY_MAX; j++){ - short mday = BYMDPTR[j]; + int mday = BYMDPTR[j]; if(tt.day == mday){ @@ -1898,12 +1980,11 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year) /*FREQ=YEARLY; BYDAY=TH,20MO,-10FR; BYMONTHDAY=10; MYMONTH=6,11*/ - int days_index = 0; pvl_elem itr; pvl_list days = expand_by_day(impl,year); for(itr=pvl_head(days);itr!=0;itr=pvl_next(itr)){ - short day = (short)(int)pvl_data(itr); + short day = (short)(*((int*)pvl_data(itr))); struct icaltimetype tt; - short i,j; + int i; tt = icaltime_from_day_of_year(day,year); @@ -1911,6 +1992,6 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year) for(i = 0; BYMONPTR[i] != ICAL_RECURRENCE_ARRAY_MAX; i++){ for(j = 0; BYMDPTR[j]!=ICAL_RECURRENCE_ARRAY_MAX; j++){ - short mday = BYMDPTR[j]; - short month = BYMONPTR[i]; + int mday = BYMDPTR[j]; + int month = BYMONPTR[i]; if(tt.month == month && tt.day == mday){ @@ -1931,19 +2012,18 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year) /*FREQ=YEARLY; BYDAY=TH,20MO,-10FR; WEEKNO=20,50*/ - int days_index = 0; pvl_elem itr; pvl_list days = expand_by_day(impl,year); for(itr=pvl_head(days);itr!=0;itr=pvl_next(itr)){ - short day = (short)(int)pvl_data(itr); + short day = (short)(*((int*)pvl_data(itr))); struct icaltimetype tt; - short i; + int i; tt = icaltime_from_day_of_year(day,year); for(i = 0; BYWEEKPTR[i] != ICAL_RECURRENCE_ARRAY_MAX; i++){ - short weekno = BYWEEKPTR[i]; - - if(weekno== icaltime_week_number(tt)){ + int weekno = BYWEEKPTR[i]; + int this_weekno = icaltime_week_number(tt); + if(weekno== this_weekno){ impl->days[days_index++] = day; } @@ -1964,6 +2044,5 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year) case 1<<BY_YEAR_DAY: { for(j=0;impl->by_ptrs[BY_YEAR_DAY][j]!=ICAL_RECURRENCE_ARRAY_MAX;j++){ - short doy = impl->by_ptrs[BY_YEAR_DAY][j]; - impl->days[days_index++] = doy; + impl->days[days_index++] = impl->by_ptrs[BY_YEAR_DAY][j]; } break; @@ -1981,24 +2060,24 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year) -int next_year(struct icalrecur_iterator_impl* impl) +static int next_year(icalrecur_iterator* impl) { struct icaltimetype next; - /* Next_year does it's own interatio in days, so the next level down is hours */ if (next_hour(impl) == 0){ - return 1; + return 0; } if (impl->days[++impl->days_index] == ICAL_RECURRENCE_ARRAY_MAX){ impl->days_index = 0; + + for (;;) { increment_year(impl,impl->rule.interval); expand_year_days(impl,impl->last.year); + if (impl->days[0] != ICAL_RECURRENCE_ARRAY_MAX) + break; } - - if(impl->days[0] == ICAL_RECURRENCE_ARRAY_MAX) { - return 0; } - next = icaltime_from_day_of_year(impl->days[impl->days_index],impl->last.year); + next = icaltime_from_day_of_year(impl->days[impl->days_index], impl->last.year); impl->last.day = next.day; @@ -2008,6 +2087,6 @@ int next_year(struct icalrecur_iterator_impl* impl) } -int icalrecur_check_rulepart(struct icalrecur_iterator_impl* impl, - short v, enum byrule byrule) +int icalrecur_check_rulepart(icalrecur_iterator* impl, + int v, enum byrule byrule) { int itr; @@ -2024,6 +2103,6 @@ int icalrecur_check_rulepart(struct icalrecur_iterator_impl* impl, } -int check_contract_restriction(struct icalrecur_iterator_impl* impl, - enum byrule byrule, short v) +static int check_contract_restriction(icalrecur_iterator* impl, + enum byrule byrule, int v) { int pass = 0; @@ -2049,20 +2128,20 @@ int check_contract_restriction(struct icalrecur_iterator_impl* impl, -int check_contracting_rules(struct icalrecur_iterator_impl* impl) +static int check_contracting_rules(icalrecur_iterator* impl) { - int day_of_week=0; - int week_no=0; - int year_day=0; + int day_of_week = icaltime_day_of_week(impl->last); + int week_no = icaltime_week_number(impl->last); + int year_day = icaltime_day_of_year(impl->last); if ( - check_contract_restriction(impl,BY_SECOND,impl->last.second) && - check_contract_restriction(impl,BY_MINUTE,impl->last.minute) && - check_contract_restriction(impl,BY_HOUR,impl->last.hour) && - check_contract_restriction(impl,BY_DAY,day_of_week) && - check_contract_restriction(impl,BY_WEEK_NO,week_no) && - check_contract_restriction(impl,BY_MONTH_DAY,impl->last.day) && - check_contract_restriction(impl,BY_MONTH,impl->last.month) && - check_contract_restriction(impl,BY_YEAR_DAY,year_day) ) + check_contract_restriction(impl,BY_SECOND, impl->last.second) && + check_contract_restriction(impl,BY_MINUTE, impl->last.minute) && + check_contract_restriction(impl,BY_HOUR, impl->last.hour) && + check_contract_restriction(impl,BY_DAY, day_of_week) && + check_contract_restriction(impl,BY_WEEK_NO, week_no) && + check_contract_restriction(impl,BY_MONTH_DAY, impl->last.day) && + check_contract_restriction(impl,BY_MONTH, impl->last.month) && + check_contract_restriction(impl,BY_YEAR_DAY, year_day) ) { @@ -2073,9 +2152,7 @@ int check_contracting_rules(struct icalrecur_iterator_impl* impl) } -struct icaltimetype icalrecur_iterator_next(icalrecur_iterator *itr) +struct icaltimetype icalrecur_iterator_next(icalrecur_iterator *impl) { int valid = 1; - struct icalrecur_iterator_impl* impl = - (struct icalrecur_iterator_impl*)itr; if( (impl->rule.count!=0 &&impl->occurrence_no >= impl->rule.count) || @@ -2121,5 +2198,5 @@ struct icaltimetype icalrecur_iterator_next(icalrecur_iterator *itr) } case ICAL_YEARLY_RECURRENCE:{ - valid = next_year(impl); + next_year(impl); break; } @@ -2136,5 +2213,5 @@ struct icaltimetype icalrecur_iterator_next(icalrecur_iterator *itr) } while(!check_contracting_rules(impl) - || icaltime_compare(impl->last,impl->dtstart) <= 0 + || icaltime_compare(impl->last,impl->dtstart) < 0 || valid == 0); @@ -2167,14 +2244,13 @@ void icalrecurrencetype_clear(struct icalrecurrencetype *recur) } -/* The 'day' element of icalrecurrencetype_weekday is encoded to allow -reporesentation of both the day of the week ( Monday, Tueday), but -also the Nth day of the week ( First tuesday of the month, last -thursday of the year) These routines decode the day values. - -The day's position in the period ( Nth-ness) and the numerical value -of the day are encoded together as: pos*7 + dow - -A position of 0 means 'any' or 'every' - +/** The 'day' element of icalrecurrencetype_weekday is encoded to + * allow representation of both the day of the week ( Monday, Tueday), + * but also the Nth day of the week ( First tuesday of the month, last + * thursday of the year) These routines decode the day values. + * + * The day's position in the period ( Nth-ness) and the numerical + * value of the day are encoded together as: pos*7 + dow + * + * A position of 0 means 'any' or 'every' */ @@ -2184,7 +2260,7 @@ enum icalrecurrencetype_weekday icalrecurrencetype_day_day_of_week(short day) } -short icalrecurrencetype_day_position(short day) +int icalrecurrencetype_day_position(short day) { - short wd, pos; + int wd, pos; wd = icalrecurrencetype_day_day_of_week(day); @@ -2199,5 +2275,5 @@ short icalrecurrencetype_day_position(short day) /****************** Enumeration Routines ******************/ -struct {icalrecurrencetype_weekday wd; const char * str; } +static struct {icalrecurrencetype_weekday wd; const char * str; } wd_map[] = { {ICAL_SUNDAY_WEEKDAY,"SU"}, @@ -2239,5 +2315,5 @@ icalrecurrencetype_weekday icalrecur_string_to_weekday(const char* str) -struct { +static struct { icalrecurrencetype_frequency kind; const char* str; @@ -2277,8 +2353,9 @@ icalrecurrencetype_frequency icalrecur_string_to_freq(const char* str) } -/* Fill an array with the 'count' number of occurrences generated by - the rrule. Note that the times are returned in UTC, but the times - are calculated in local time. YOu will have to convert the results - back into local time before using them. */ +/** Fill an array with the 'count' number of occurrences generated by + * the rrule. Note that the times are returned in UTC, but the times + * are calculated in local time. YOu will have to convert the results + * back into local time before using them. + */ int icalrecur_expand_recurrence(char* rule, time_t start, @@ -2293,5 +2370,5 @@ int icalrecur_expand_recurrence(char* rule, time_t start, memset(array, 0, count*sizeof(time_t)); - icstart = icaltime_from_timet(start,0); + icstart = icaltime_from_timet_with_zone(start,0,0); recur = icalrecurrencetype_from_string(rule); |