rem: from the start time into the coresponding BY_* array when the
add: from the start time into the corresponding BY_* array when the
context: icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, 					   struct icaltimetype dtstart){    struct icalrecur_iterator_impl* impl;    icalrecurrencetype_frequency freq;    short days_in_month;    if ( ( impl = (struct icalrecur_iterator_impl *)	   malloc(sizeof(struct icalrecur_iterator_impl))) == 0) {	icalerror_set_errno(ICAL_NEWFAILED_ERROR);	return 0;    }    memset(impl,0,sizeof(struct icalrecur_iterator_impl));    impl->rule = rule;    impl->last = dtstart;    impl->dtstart = dtstart;    impl->days_index =0;    impl->occurrence_no = 0;    freq = impl->rule.freq;    /* Set up convienience pointers to make the code simpler. Allows       us to iterate through all of the BY* arrays in the rule. */    impl->by_ptrs[BY_MONTH]=impl->rule.by_month;    impl->by_ptrs[BY_WEEK_NO]=impl->rule.by_week_no;    impl->by_ptrs[BY_YEAR_DAY]=impl->rule.by_year_day;    impl->by_ptrs[BY_MONTH_DAY]=impl->rule.by_month_day;    impl->by_ptrs[BY_DAY]=impl->rule.by_day;    impl->by_ptrs[BY_HOUR]=impl->rule.by_hour;    impl->by_ptrs[BY_MINUTE]=impl->rule.by_minute;    impl->by_ptrs[BY_SECOND]=impl->rule.by_second;    impl->by_ptrs[BY_SET_POS]=impl->rule.by_set_pos;    memset(impl->orig_data,0,9);    /* Note which by rules had data in them when the iterator was       created. We can't use the actuall by_x arrays, because the       empty ones will be given default values later in this       routine. The orig_data array will be used later in has_by_data */    impl->orig_data[BY_MONTH]	= (impl->rule.by_month[0]!=ICAL_RECURRENCE_ARRAY_MAX);    impl->orig_data[BY_WEEK_NO]      =(impl->rule.by_week_no[0]!=ICAL_RECURRENCE_ARRAY_MAX);    impl->orig_data[BY_YEAR_DAY]    =(impl->rule.by_year_day[0]!=ICAL_RECURRENCE_ARRAY_MAX);    impl->orig_data[BY_MONTH_DAY]    =(impl->rule.by_month_day[0]!=ICAL_RECURRENCE_ARRAY_MAX);    impl->orig_data[BY_DAY]	= (impl->rule.by_day[0]!=ICAL_RECURRENCE_ARRAY_MAX);    impl->orig_data[BY_HOUR]	= (impl->rule.by_hour[0]!=ICAL_RECURRENCE_ARRAY_MAX);    impl->orig_data[BY_MINUTE]     = (impl->rule.by_minute[0]!=ICAL_RECURRENCE_ARRAY_MAX);    impl->orig_data[BY_SECOND]     = (impl->rule.by_second[0]!=ICAL_RECURRENCE_ARRAY_MAX);    impl->orig_data[BY_SET_POS]     = (impl->rule.by_set_pos[0]!=ICAL_RECURRENCE_ARRAY_MAX);    /* Check if the recurrence rule is legal */    /* If the BYYEARDAY appears, no other date rule part may appear.   */    if(icalrecur_two_byrule(impl,BY_YEAR_DAY,BY_MONTH) ||       icalrecur_two_byrule(impl,BY_YEAR_DAY,BY_WEEK_NO) ||       icalrecur_two_byrule(impl,BY_YEAR_DAY,BY_MONTH_DAY) ||       icalrecur_two_byrule(impl,BY_YEAR_DAY,BY_DAY) ){	icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);	return 0;    }    /* BYWEEKNO and BYMONTH rule parts may not both appear.*/    if(icalrecur_two_byrule(impl,BY_WEEK_NO,BY_MONTH)){	icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);	icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);	return 0;    }    /* BYWEEKNO and BYMONTHDAY rule parts may not both appear.*/    if(icalrecur_two_byrule(impl,BY_WEEK_NO,BY_MONTH_DAY)){	icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);	icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);	return 0;    }    /*For MONTHLY recurrences (FREQ=MONTHLY) neither BYYEARDAY nor      BYWEEKNO may appear. */    if(freq == ICAL_MONTHLY_RECURRENCE &&        icalrecur_one_byrule(impl,BY_WEEK_NO)){	icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);	return 0;    }    /*For WEEKLY recurrences (FREQ=WEEKLY) neither BYMONTHDAY nor      BYYEARDAY may appear. */    if(freq == ICAL_WEEKLY_RECURRENCE &&        icalrecur_one_byrule(impl,BY_MONTH_DAY )) {	icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);	return 0;    }    /* BYYEARDAY may only appear in YEARLY rules */    if(freq != ICAL_YEARLY_RECURRENCE &&        icalrecur_one_byrule(impl,BY_YEAR_DAY )) {	icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);	return 0;    }    /* Rewrite some of the rules and set up defaults to make later       processing easier. Primarily, t involves copying an element       from the start time into the coresponding BY_* array when the       BY_* array is empty */    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,		   &(impl->last.minute));    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,		   &(impl->last.day));    setup_defaults(impl,BY_MONTH,ICAL_MONTHLY_RECURRENCE,impl->dtstart.month,		   &(impl->last.month));    if(impl->rule.freq == ICAL_WEEKLY_RECURRENCE ){       if(impl->by_ptrs[BY_DAY][0] == ICAL_RECURRENCE_ARRAY_MAX){	   /* Weekly recurrences with no BY_DAY data should occur on the	      same day of the week as the start time . */	   impl->by_ptrs[BY_DAY][0] = icaltime_day_of_week(impl->dtstart);       } else {	  /* If there is BY_DAY data, then we need to move the initial	     time to the start of the BY_DAY data. That is if the	     start time is on a Wednesday, and the rule has	     BYDAY=MO,WE,FR, move the initial time back to	     monday. Otherwise, jumping to the next week ( jumping 7	     days ahead ) will skip over some occurrences in the	     second week. */	  	  /* This is probably a HACK. There should be some more             general way to solve this problem */	  short dow = impl->by_ptrs[BY_DAY][0]-icaltime_day_of_week(impl->last);	  if(dow < 0) {	      /* initial time is after first day of BY_DAY data */	      impl->last.day += dow;	      impl->last = icaltime_normalize(impl->last);	  }      }          }    /* For YEARLY rule, begin by setting up the year days array */    if(impl->rule.freq == ICAL_YEARLY_RECURRENCE){        expand_year_days(impl,impl->last.year);    }     /* If this is a monthly interval with by day data, then we need to       set the last value to the appropriate day of the month */    if(impl->rule.freq == ICAL_MONTHLY_RECURRENCE &&       has_by_data(impl,BY_DAY)) {	short dow = icalrecurrencetype_day_day_of_week(	    impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]]);  	short pos =  icalrecurrencetype_day_position(	    impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]]);  		short poscount = 0;	days_in_month =             icaltime_days_in_month(impl->last.month, impl->last.year); 	        if(pos >= 0){            /* Count up from the first day pf the month to find the               pos'th weekday of dow ( like the second monday. ) */            for(impl->last.day = 1;                impl->last.day <= days_in_month;                impl->last.day++){                                if(icaltime_day_of_week(impl->last) == dow){                    if(++poscount == pos || pos == 0){                        break;                    }                }            }        } else {            /* Count down from the last day pf the month to find the               pos'th weekday of dow ( like the second to last monday. ) */            pos = -pos;            for(impl->last.day = days_in_month;                impl->last.day != 0;                impl->last.day--){                                if(icaltime_day_of_week(impl->last) == dow){                    if(++poscount == pos ){                        break;                    }                }            }        }	if(impl->last.day > days_in_month || impl->last.day == 0){	    icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);	    return 0;	}	    }    return impl;}