cdesktopenv/cde/lib/csa/reparser.y

1080 lines
21 KiB
Plaintext

/* $XConsortium: reparser.y /main/2 1996/11/11 11:52:15 drk $ */
%{
/*
* (c) Copyright 1993, 1994 Hewlett-Packard Company
* (c) Copyright 1993, 1994 International Business Machines Corp.
* (c) Copyright 1993, 1994 Novell, Inc.
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
*/
#include <EUSCompat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include "rerule.h"
#include "iso8601.h"
/* The parsed rule is stored in this structure */
RepeatEvent *_DtCm_repeat_info;
extern int yylex(void);
extern void yyerror(char*);
static int CompareNums(const void *, const void *);
static int CompareDayTime(const void *, const void *);
static int CompareWeekDayTime(const void *, const void *);
static unsigned int *ConvertNumList(NumberList *, unsigned int * /* Return */);
static WeekDayTime *ConvertWeekDayTime(WeekDayTimeList *, unsigned int *);
static NumberList *AllocNumber(unsigned int);
static WeekDayTimeList *AllocWeekDayTimeList(NumberList*, NumberList *,
NumberList *);
static RepeatEvent *HandleEndDate(RepeatEvent *, time_t);
static RepeatEvent *DeriveMinuteEvent(unsigned int, unsigned int);
static RepeatEvent *DeriveDailyEvent(unsigned int, NumberList *,
unsigned int, RepeatEvent *);
static RepeatEvent *DeriveWeeklyEvent(unsigned int, DayTimeList *,
unsigned int, RepeatEvent *);
static RepeatEvent *DeriveMonthlyEvent(RepeatType, unsigned int, void *,
unsigned int, RepeatEvent *);
static RepeatEvent *DeriveYearlyEvent(RepeatType, unsigned int, NumberList *,
unsigned int, RepeatEvent *);
%}
%token ERROR ENDMARKER DURATION NUMBER FIRSTWEEK SECONDWEEK THIRDWEEK
%token FOURTHWEEK FIFTHWEEK LASTWEEK SECONDLAST THIRDLAST FOURTHLAST
%token FIFTHLAST MINUTECOMMAND DAILYCOMMAND WEEKLYCOMMAND MONTHPOSCOMMAND
%token MONTHDAYCOMMAND YEARDAYCOMMAND YEARMONTHCOMMAND LASTDAY SUNDAY
%token MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY DATE
%union {
int number;
RepeatEvent *re;
NumberList *nl;
WeekDay weekday;
WeekNumber weeknum;
DayTime *dt;
DayTimeList *dtl;
WeekDayTimeList *wdtl;
time_t enddate;
char date[64];
}
%type <re> start begin minuteEvent dailyEvent weeklyEvent monthlyPosEvent
monthlyDayEvent yearlyByMonth yearlyByDay
%type <nl> time0List timeList dayOfMonthList monthOfYearList
dayOfYearList occurrenceList genericNumberList
generic0NumberList weekdayList
%type <weekday> SUNDAY MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY
weekday
%type <number> duration NUMBER occurrence endMarker time
%type <dtl> weekdayTimeList
%type <wdtl> weekDayTime
%type <dt> weekdayTimePair
%type <date> DATE
%type <enddate> endDate
%% /* Beginning of rules section */
start : begin
{
_DtCm_repeat_info = $$;
}
| error
{
/*
* XXX: Memory leak: We need to free up any portion
* of the re struct that has be allocated before the
* error was encountered.
*/
_DtCm_repeat_info = NULL;
}
;
begin : minuteEvent endDate
{
$$ = HandleEndDate($1, $2);
}
| dailyEvent endDate
{
$$ = HandleEndDate($1, $2);
}
| weeklyEvent endDate
{
$$ = HandleEndDate($1, $2);
}
| monthlyPosEvent endDate
{
$$ = HandleEndDate($1, $2);
}
| monthlyDayEvent endDate
{
$$ = HandleEndDate($1, $2);
}
| yearlyByMonth endDate
{
$$ = HandleEndDate($1, $2);
}
| yearlyByDay endDate
{
$$ = HandleEndDate($1, $2);
}
;
minuteEvent : /* empty */
{
$$ = NULL;
}
| MINUTECOMMAND NUMBER duration
{
#ifdef MINUTE
$$ = DeriveMinuteEvent($2, $3);
#else
$$ = NULL;
#endif /* MINUTE */
}
;
dailyEvent
: DAILYCOMMAND NUMBER time0List duration minuteEvent
{
$$ = DeriveDailyEvent($2, $3, $4, $5);
if ($5) $$ = NULL;
}
;
weeklyEvent
: WEEKLYCOMMAND NUMBER weekdayTimeList duration minuteEvent
{
$$ = DeriveWeeklyEvent($2, $3, $4, $5);
if ($5) $$ = NULL;
}
| WEEKLYCOMMAND NUMBER duration minuteEvent
{
$$ = DeriveWeeklyEvent($2, NULL, $3, $4);
if ($4) $$ = NULL;
}
;
monthlyPosEvent
: MONTHPOSCOMMAND NUMBER weekDayTime duration minuteEvent
{
$$ = DeriveMonthlyEvent(RT_MONTHLY_POSITION,
$2, $3, $4, $5);
if ($5) $$ = NULL;
}
| MONTHPOSCOMMAND NUMBER weekDayTime duration dailyEvent
{
$$ = DeriveMonthlyEvent(RT_MONTHLY_POSITION,
$2, $3, $4, $5);
if ($5) $$ = NULL;
}
| MONTHPOSCOMMAND NUMBER weekDayTime duration weeklyEvent
{
$$ = DeriveMonthlyEvent(RT_MONTHLY_POSITION,
$2, $3, $4, $5);
if ($5) $$ = NULL;
}
;
monthlyDayEvent : MONTHDAYCOMMAND NUMBER dayOfMonthList duration minuteEvent
{
$$ = DeriveMonthlyEvent(RT_MONTHLY_DAY, $2, $3, $4, $5);
if ($5) $$ = NULL;
}
| MONTHDAYCOMMAND NUMBER dayOfMonthList duration dailyEvent
{
$$ = DeriveMonthlyEvent(RT_MONTHLY_DAY, $2, $3, $4, $5);
if ($5) $$ = NULL;
}
| MONTHDAYCOMMAND NUMBER dayOfMonthList duration weeklyEvent
{
$$ = DeriveMonthlyEvent(RT_MONTHLY_DAY, $2, $3, $4, $5);
if ($5) $$ = NULL;
}
;
yearlyByMonth : YEARMONTHCOMMAND NUMBER monthOfYearList duration minuteEvent
{
$$ = DeriveYearlyEvent(RT_YEARLY_MONTH, $2, $3, $4, $5);
if ($5) $$ = NULL;
}
| YEARMONTHCOMMAND NUMBER monthOfYearList duration dailyEvent
{
$$ = DeriveYearlyEvent(RT_YEARLY_MONTH, $2, $3, $4, $5);
if ($5) $$ = NULL;
}
| YEARMONTHCOMMAND NUMBER monthOfYearList duration weeklyEvent
{
$$ = DeriveYearlyEvent(RT_YEARLY_MONTH, $2, $3, $4, $5);
if ($5) $$ = NULL;
}
| YEARMONTHCOMMAND NUMBER monthOfYearList duration
monthlyPosEvent
{
$$ = DeriveYearlyEvent(RT_YEARLY_MONTH, $2, $3, $4, $5);
if ($5) $$ = NULL;
}
| YEARMONTHCOMMAND NUMBER monthOfYearList duration
monthlyDayEvent
{
$$ = DeriveYearlyEvent(RT_YEARLY_MONTH, $2, $3, $4, $5);
if ($5) $$ = NULL;
}
;
yearlyByDay : YEARDAYCOMMAND NUMBER dayOfYearList duration minuteEvent
{
$$ = DeriveYearlyEvent(RT_YEARLY_DAY, $2, $3, $4, $5);
if ($5) $$ = NULL;
}
| YEARDAYCOMMAND NUMBER dayOfYearList duration dailyEvent
{
$$ = DeriveYearlyEvent(RT_YEARLY_DAY, $2, $3, $4, $5);
if ($5) $$ = NULL;
}
| YEARDAYCOMMAND NUMBER dayOfYearList duration weeklyEvent
{
$$ = DeriveYearlyEvent(RT_YEARLY_DAY, $2, $3, $4, $5);
if ($5) $$ = NULL;
}
| YEARDAYCOMMAND NUMBER dayOfYearList duration monthlyPosEvent
{
$$ = DeriveYearlyEvent(RT_YEARLY_DAY, $2, $3, $4, $5);
if ($5) $$ = NULL;
}
| YEARDAYCOMMAND NUMBER dayOfYearList duration monthlyDayEvent
{
$$ = DeriveYearlyEvent(RT_YEARLY_DAY, $2, $3, $4, $5);
if ($5) $$ = NULL;
}
;
/* e.g. 1W MO TU 1300 1400 */
weekDayTime : /* empty */
{
$$ = NULL;
}
| weekDayTime occurrenceList weekdayList
{
WeekDayTimeList *wdtl;
wdtl = AllocWeekDayTimeList($2, $3, NULL);
if ($1 == NULL) {
$$ = wdtl;
} else {
wdtl->wdtl_next = $$->wdtl_next;
$$->wdtl_next = wdtl;
}
}
| weekDayTime occurrenceList weekdayList timeList
{
WeekDayTimeList *wdtl;
wdtl = AllocWeekDayTimeList($2, $3, $4);
if ($1 == NULL) {
$$ = wdtl;
} else {
wdtl->wdtl_next = $$->wdtl_next;
$$->wdtl_next = wdtl;
}
}
;
/* e.g. MO TU WE TH */
weekdayList : weekday
{
$$ = AllocNumber($1);
}
| weekdayList weekday
{
NumberList *nl;
nl = AllocNumber($2);
if ($1 == NULL) {
$$ = nl;
} else {
nl->nl_next = $$->nl_next;
$$->nl_next = nl;
}
}
;
/* e.g. 1W 3W 2L LW */
occurrenceList : occurrence
{
$$ = AllocNumber($1);
}
| occurrenceList occurrence
{
NumberList *nl;
nl = AllocNumber($2);
if ($1 == NULL) {
$$ = nl;
} else {
nl->nl_next = $$->nl_next;
$$->nl_next = nl;
}
}
;
/* e.g. MO 1300 1500 2000 */
weekdayTimePair : weekday time0List
{
DayTime *dt;
dt = (DayTime *)calloc(1, sizeof(DayTime));
dt->dt_day = $1;
/* Convert from list to array, sort */
dt->dt_time =
(Time *)ConvertNumList($2, &(dt->dt_ntime));
$$ = dt;
}
;
/* e.g. MO 1300 1500 2000 TU 1200 1400 */
weekdayTimeList : weekdayTimePair
{
DayTimeList *dtl;
dtl = (DayTimeList *)calloc(1, sizeof(DayTimeList));
dtl->dtl_daytime = $1;
dtl->dtl_next = NULL;
$$ = dtl;
}
| weekdayTimeList weekdayTimePair
{
DayTimeList *dtl,
*dtl_end;
dtl = (DayTimeList *)calloc(1, sizeof(DayTimeList));
dtl->dtl_daytime = $2;
dtl->dtl_next = NULL;
if ($1 == NULL) {
$$ = dtl;
} else {
/* Insert the new entry at the end. This is
* so that MO TU 200 300 TH will maintain the
* same order in the list since MO uses the
* times next to TU and TH is dependent on the
* appt time.
*/
dtl_end = $$;
while (dtl_end->dtl_next)
dtl_end = dtl_end->dtl_next;
dtl_end->dtl_next = dtl;
}
}
;
/* e.g. 1+ 2+ 3- 1- */
occurrence : FIRSTWEEK endMarker
{
$$ = WK_F1;
if ($2) RE_SET_FLAG($$);
}
| SECONDWEEK endMarker
{
$$ = WK_F2;
if ($2) RE_SET_FLAG($$);
}
| THIRDWEEK endMarker
{
$$ = WK_F3;
if ($2) RE_SET_FLAG($$);
}
| FOURTHWEEK endMarker
{
$$ = WK_F4;
if ($2) RE_SET_FLAG($$);
}
| FIFTHWEEK endMarker
{
$$ = WK_F5;
if ($2) RE_SET_FLAG($$);
}
| LASTWEEK endMarker
{
$$ = WK_L1;
if ($2) RE_SET_FLAG($$);
}
| SECONDLAST endMarker
{
$$ = WK_L2;
if ($2) RE_SET_FLAG($$);
}
| THIRDLAST endMarker
{
$$ = WK_L3;
if ($2) RE_SET_FLAG($$);
}
| FOURTHLAST endMarker
{
$$ = WK_L4;
if ($2) RE_SET_FLAG($$);
}
| FIFTHLAST endMarker
{
$$ = WK_L5;
if ($2) RE_SET_FLAG($$);
}
;
endDate : /* empty */
{
$$ = '\0';
}
| DATE
{
if (_csa_iso8601_to_tick($1, &$$) == -1)
$$ = '\0';
}
;
/* e.g. MO TU WE */
weekday : SUNDAY endMarker
{
$$ = WD_SUN;
if ($2) RE_SET_FLAG($$);
}
| MONDAY endMarker
{
$$ = WD_MON;
if ($2) RE_SET_FLAG($$);
}
| TUESDAY endMarker
{
$$ = WD_TUE;
if ($2) RE_SET_FLAG($$);
}
| WEDNESDAY endMarker
{
$$ = WD_WED;
if ($2) RE_SET_FLAG($$);
}
| THURSDAY endMarker
{
$$ = WD_THU;
if ($2) RE_SET_FLAG($$);
}
| FRIDAY endMarker
{
$$ = WD_FRI;
if ($2) RE_SET_FLAG($$);
}
| SATURDAY endMarker
{
$$ = WD_SAT;
if ($2) RE_SET_FLAG($$);
}
;
/* e.g. 0100 1200 1300 or NULL */
time0List : /* empty */
{
$$ = NULL;
}
| time0List time
{
NumberList *nl;
nl = AllocNumber($2);
if ($1 == NULL) {
$$ = nl;
} else {
nl->nl_next = $$->nl_next;
$$->nl_next = nl;
}
}
;
/* e.g. 1000 */
time : NUMBER endMarker
{
if ($2)
RE_SET_FLAG($1);
$$ = $1;
}
;
/* e.g. $ */
endMarker : /* empty */
{
$$ = FALSE;
}
| ENDMARKER
{
$$ = TRUE;
}
;
/* e.g. #10 */
duration : /* empty */
{
/* If no duration then default to 2 - set later if
* end date not used.
*/
$$ = RE_NOTSET;
}
| DURATION NUMBER
{
/* If duration == 0 then repeat forever */
if ($2 == 0)
$$ = RE_INFINITY;
else
$$ = $2;
}
;
timeList : genericNumberList
dayOfMonthList : generic0NumberList
monthOfYearList : generic0NumberList
dayOfYearList : generic0NumberList
generic0NumberList: /* empty */
{
$$ = NULL;
}
| genericNumberList
{
$$ = $1;
}
genericNumberList
: NUMBER endMarker
{
if ($2)
RE_SET_FLAG($1);
$$ = AllocNumber($1);
}
| LASTDAY endMarker
{
int number = RE_LASTDAY;
if ($2)
RE_SET_FLAG(number);
$$ = AllocNumber(number);
}
| genericNumberList NUMBER endMarker
{
NumberList *nl;
if ($3)
RE_SET_FLAG($2);
nl = AllocNumber($2);
if ($1 == NULL) {
$$ = nl;
} else {
nl->nl_next = $$->nl_next;
$$->nl_next = nl;
}
}
| genericNumberList LASTDAY endMarker
{
NumberList *nl;
int number = RE_LASTDAY;
if ($3)
RE_SET_FLAG(number);
nl = AllocNumber(number);
if ($1 == NULL) {
$$ = nl;
} else {
nl->nl_next = $$->nl_next;
$$->nl_next = nl;
}
}
;
%%
/*
* Convert the NumberList (linked list) to an array, sort the array.
*/
static unsigned int *
ConvertNumList(
NumberList *nl,
unsigned int *count)
{
NumberList *nl_head = nl;
unsigned int *array;
int i = 0;
if (!nl) return (unsigned int *)NULL;
while (nl) {
i++;
nl = nl->nl_next;
}
array = (unsigned int *) calloc(i, sizeof(unsigned int));
i = 0;
/* Convert the list into an array */
nl = nl_head;
while (nl) {
NumberList *nl_prev;
array[i] = nl->nl_number;
i++;
nl_prev = nl;
nl = nl->nl_next;
free(nl_prev);
}
*count = i;
/* Sort the array */
qsort((void *)array, i, sizeof(unsigned int), CompareNums);
return array;
}
/*
* Convert the DayTimeList to an array, sort the array.
*/
static DayTime *
ConvertDayTime(
DayTimeList *dtl,
unsigned int *count)
{
DayTimeList *dtl_head = dtl;
DayTime *daytime_array;
int i = 0,
no_time = -1;
if (!dtl) return (DayTime *)NULL;
while (dtl) {
i++;
dtl = dtl->dtl_next;
}
daytime_array = (DayTime *) calloc(i, sizeof(DayTime));
i = 0;
/* Convert the list into an array */
dtl = dtl_head;
while (dtl) {
DayTimeList *dtl_prev;
daytime_array[i].dt_day = dtl->dtl_daytime->dt_day;
daytime_array[i].dt_ntime = dtl->dtl_daytime->dt_ntime;
daytime_array[i].dt_time = dtl->dtl_daytime->dt_time;
i++;
dtl_prev = dtl;
dtl = dtl->dtl_next;
/* alloc'ed in <weekdayTimeList> */
free(dtl_prev);
}
*count = i;
for (i = 0; i < *count; i++) {
if (daytime_array[i].dt_time == NULL) {
if (no_time == -1)
no_time = i;
} else {
if (no_time != -1) {
int j;
for (j = no_time; j < i; j++) {
daytime_array[j].dt_ntime =
daytime_array[i].dt_ntime;
daytime_array[j].dt_time =
(Time *)calloc(
daytime_array[j].dt_ntime,
sizeof(Time));
memcpy(daytime_array[j].dt_time,
daytime_array[i].dt_time,
daytime_array[j].dt_ntime *
sizeof(Time));
}
no_time = -1;
}
}
}
/* Sort the array */
qsort((void *)daytime_array, *count, sizeof(DayTime), CompareDayTime);
return daytime_array;
}
/*
* Used by qsort()
*/
static int
CompareNums(
const void *data1,
const void *data2)
{
const unsigned int *i = (const unsigned int *)data1;
const unsigned int *j = (const unsigned int *)data2;
if ((unsigned )RE_MASK_STOP(*i) > (unsigned )RE_MASK_STOP(*j))
return(1);
if ((unsigned )RE_MASK_STOP(*i) < (unsigned )RE_MASK_STOP(*j))
return(-1);
return (0);
}
/*
* Used by qsort()
*/
static int
CompareDayTime(
const void *data1,
const void *data2)
{
const DayTime *i = (const DayTime *)data1;
const DayTime *j = (const DayTime *)data2;
if ((unsigned )RE_MASK_STOP(i->dt_day) >
(unsigned )RE_MASK_STOP(j->dt_day))
return(1);
if ((unsigned )RE_MASK_STOP(i->dt_day) <
(unsigned )RE_MASK_STOP(j->dt_day))
return(-1);
return (0);
}
/*
* Used by qsort()
*/
static int
CompareWeekDayTime(
const void *data1,
const void *data2)
{
const WeekDayTime *i = (const WeekDayTime *)data1;
const WeekDayTime *j = (const WeekDayTime *)data2;
if ((unsigned )RE_MASK_STOP(i->wdt_week[0]) >
(unsigned )RE_MASK_STOP(j->wdt_week[0]))
return(1);
if ((unsigned )RE_MASK_STOP(i->wdt_week[0]) <
(unsigned )RE_MASK_STOP(j->wdt_week[0]))
return(-1);
return (0);
}
static NumberList *
AllocNumber(
unsigned int num)
{
NumberList *nl;
nl = (NumberList *)calloc(1, sizeof(NumberList));
nl->nl_number = num;
nl->nl_next = NULL;
return nl;
}
/*
* Given three NumberLists convert them into arrays and return a WeekDayTime.
*/
static WeekDayTimeList *
AllocWeekDayTimeList(
NumberList *week_list,
NumberList *day_list,
NumberList *time_list)
{
WeekDayTime *wdt;
WeekDayTimeList *wdtl;
wdt = (WeekDayTime *)calloc(1, sizeof(WeekDayTime));
wdtl = (WeekDayTimeList *)calloc(1, sizeof(WeekDayTimeList));
wdt->wdt_week =
(WeekNumber *)ConvertNumList(week_list, &(wdt->wdt_nweek));
wdt->wdt_day =
(WeekDay *)ConvertNumList(day_list, &(wdt->wdt_nday));
wdt->wdt_time =
(Time *)ConvertNumList(time_list, &(wdt->wdt_ntime));
wdtl->wdtl_weektime = wdt;
return wdtl;
}
/*
* Convert the DayTimeList to an array, sort the array.
*/
static WeekDayTime *
ConvertWeekDayTime(
WeekDayTimeList *wdtl,
unsigned int *count)
{
WeekDayTimeList *wdtl_head = wdtl;
WeekDayTime *array;
int i = 0;
if (!wdtl) return (WeekDayTime *)NULL;
while (wdtl) {
i++;
wdtl = wdtl->wdtl_next;
}
array = (WeekDayTime *) calloc(i, sizeof(WeekDayTime));
i = 0;
/* Convert the list into an array */
wdtl = wdtl_head;
while (wdtl) {
WeekDayTimeList *wdtl_prev;
array[i].wdt_day = wdtl->wdtl_weektime->wdt_day;
array[i].wdt_nday = wdtl->wdtl_weektime->wdt_nday;
array[i].wdt_time = wdtl->wdtl_weektime->wdt_time;
array[i].wdt_ntime = wdtl->wdtl_weektime->wdt_ntime;
array[i].wdt_week = wdtl->wdtl_weektime->wdt_week;
array[i].wdt_nweek = wdtl->wdtl_weektime->wdt_nweek;
i++;
wdtl_prev = wdtl;
wdtl = wdtl->wdtl_next;
free(wdtl_prev);
}
*count = i;
/* Sort the array */
qsort((void *)array, i, sizeof(WeekDayTime), CompareWeekDayTime);
return array;
}
static RepeatEvent *
HandleEndDate(
RepeatEvent *re,
time_t enddate)
{
if (re) {
if (enddate) {
re->re_end_date = enddate;
} else if (re->re_duration == RE_NOTSET) {
re->re_duration = 2;
}
}
return re;
}
/*
* Create a RepeatEvent for the minute portion of a rule.
*/
static RepeatEvent *
DeriveMinuteEvent(
unsigned int interval,
unsigned int duration)
{
RepeatEvent *re;
if (interval < 1)
return NULL;
re = (RepeatEvent *)calloc(1, sizeof(RepeatEvent));
re->re_interval = interval;
re->re_duration = duration;
re->re_type = RT_MINUTE;
return re;
}
/*
* Create a RepeatEvent for the daily portion of a rule.
*/
static RepeatEvent *
DeriveDailyEvent(
unsigned int interval,
NumberList *time_list,
unsigned int duration,
RepeatEvent *other_event)
{
RepeatEvent *re;
DailyData *dd;
dd = (DailyData *)calloc(1, sizeof(DailyData));
/* Convert from list to array, sort */
dd->dd_time = (Time *)ConvertNumList(time_list, &(dd->dd_ntime));
if (interval < 1) {
free(dd);
return NULL;
}
re = (RepeatEvent *)calloc(1, sizeof(RepeatEvent));
re->re_interval = interval;
re->re_duration = duration;
re->re_type = RT_DAILY;
re->re_data.re_daily = dd;
/* If there is a minuteEvent, tack it on */
if (other_event) {
re->re_next = other_event;
other_event->re_prev = re;
}
return re;
}
/*
* Create a RepeatEvent for the weekly portion of a rule.
*/
static RepeatEvent *
DeriveWeeklyEvent(
unsigned int interval,
DayTimeList *dtl,
unsigned int duration,
RepeatEvent *other_event)
{
RepeatEvent *re;
WeeklyData *wd;
wd = (WeeklyData *)calloc(1, sizeof(WeeklyData));
/* Convert from list to array, sort */
wd->wd_daytime = ConvertDayTime(dtl, &(wd->wd_ndaytime));
if (interval < 1) {
free(wd);
return NULL;
}
re = (RepeatEvent *)calloc(1, sizeof(RepeatEvent));
re->re_interval = interval;
re->re_duration = duration;
re->re_type = RT_WEEKLY;
re->re_data.re_weekly = wd;
if (other_event) {
re->re_next = other_event;
other_event->re_prev = re;
}
return re;
}
/*
* Create a RepeatEvent for the monthly portion of a rule.
*/
static RepeatEvent *
DeriveMonthlyEvent(
RepeatType type,
unsigned int interval,
void *data_list,
unsigned int duration,
RepeatEvent *other_event)
{
RepeatEvent *re;
MonthlyData *md;
md = (MonthlyData *)calloc(1, sizeof(MonthlyData));
/* Convert from list to array, sort */
if (type == RT_MONTHLY_POSITION) {
md->md_weektime = ConvertWeekDayTime(
(WeekDayTimeList *)data_list, &(md->md_nitems));
} else {
md->md_days = ConvertNumList(
(NumberList *)data_list, &(md->md_nitems));
}
if (interval < 1) {
free(md);
return NULL;
}
re = (RepeatEvent *)calloc(1, sizeof(RepeatEvent));
re->re_interval = interval;
re->re_duration = duration;
re->re_type = type;
re->re_data.re_monthly = md;
/* If there is an another event, tack it on */
if (other_event) {
re->re_next = other_event;
other_event->re_prev = re;
}
return re;
}
/*
* Create a RepeatEvent for the yearly portion of a rule.
*/
static RepeatEvent *
DeriveYearlyEvent(
RepeatType type,
unsigned int interval,
NumberList *nl,
unsigned int duration,
RepeatEvent *other_event)
{
RepeatEvent *re;
YearlyData *yd;
yd = (YearlyData *)calloc(1, sizeof(YearlyData));
/* Convert from list to array, sort */
yd->yd_items = ConvertNumList(nl, &(yd->yd_nitems));
if (interval < 1) {
free(yd);
return NULL;
}
re = (RepeatEvent *)calloc(1, sizeof(RepeatEvent));
re->re_interval = interval;
re->re_duration = duration;
re->re_type = type;
re->re_data.re_yearly = yd;
/* If there is an another event, tack it on */
if (other_event) {
re->re_next = other_event;
other_event->re_prev = re;
}
return re;
}
void
yyerror(
char *str)
{
/* Don't do anything */
}