Date: Thu, 23 May 2002 20:40:03 -0700 (PDT) From: "Danny J. Zerkel" <dzerkel@columbus.rr.com> To: freebsd-bugs@FreeBSD.org Subject: Re: bin/4629: calendar doesn't print all dates sometimes Message-ID: <200205240340.g4O3e3567202@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/4629; it has been noted by GNATS. From: "Danny J. Zerkel" <dzerkel@columbus.rr.com> To: freebsd-gnats-submit@FreeBSD.org, imp@village.org Cc: Subject: Re: bin/4629: calendar doesn't print all dates sometimes Date: Thu, 23 May 2002 23:33:09 -0400 This patch handles the simplest case: weekly events. Monthly events would be more difficult due to the different lengths of months and different kinds of monthly events. Some of the long lines from the original code may need to be tweaked to get this patch to apply... --- calendar.h.orig Wed May 22 23:56:44 2002 +++ calendar.h Thu May 23 23:29:17 2002 @@ -51,6 +51,7 @@ int getpaskha(char *, int); int easter(int); int isnow(char *, int *, int *, int *); +void repeatweek(int *, int *); FILE *opencal(void); void settime(time_t); time_t Mktime(char *); @@ -64,6 +65,7 @@ #define F_ISDAY 0x02 /* day of week (Sun, Mon, ...) */ #define F_ISDAYVAR 0x04 /* variables day of week, like SundayLast */ #define F_EASTER 0x08 /* Easter or easter depending days */ +#define F_REPEAT 0x10 /* Repeat weekly */ extern int f_dayAfter; /* days after current date */ extern int f_dayBefore; /* days bevore current date */ --- day.c.orig Thu May 23 00:02:34 2002 +++ day.c Thu May 23 23:09:20 2002 @@ -215,7 +215,8 @@ * * Any character may separate them, or they may not be separated. Any line, * following a line that is matched, that starts with "whitespace", is shown - * along with the matched line. + * along with the matched line. Returns the number of matching days in the + * requested date range. */ int isnow(endp, monthp, dayp, varp) @@ -225,6 +226,7 @@ int *varp; { int day, flags, month = 0, v1, v2; + int nummatches; /* * CONVENTION @@ -260,8 +262,12 @@ /* {Day,Weekday} {Month,Monthname} ... */ /* if no recognizable month, assume just a day alone * in other words, find month or use current month */ - if (!(month = getfield(endp, &endp, &flags))) + if (!(month = getfield(endp, &endp, &flags))) { month = tp->tm_mon + 1; + /* Weekdays may match multiple time in a range */ + if (flags & F_ISDAY && day <= 7) + flags |= F_REPEAT; + } } /* 2. {Monthname} XYZ ... */ @@ -378,18 +384,56 @@ #ifdef DEBUG fprintf(stderr, "day2: day %d(%d-%d) yday %d\n", *dayp, day, cumdays[month], tp->tm_yday); #endif + /* Find the earliest matching weekday in the range */ + if (flags & F_REPEAT) { + while (day - 7 >= tp->tm_yday - f_dayBefore) { + day -= 7; + *dayp -= 7; + } + /* Adjust the month and day, to fit the day */ + while (*dayp < 1) { + *monthp -= 1; + if (*monthp < 1) + *monthp = 12; + *dayp += cumdays[*monthp + 1] - cumdays[*monthp]; + } + } + nummatches = 0; + /* if today or today + offset days */ if (day >= tp->tm_yday - f_dayBefore && day <= tp->tm_yday + offset + f_dayAfter) - return (1); + nummatches = 1; /* if number of days left in this year + days to event in next year */ - if (yrdays - tp->tm_yday + day <= offset + f_dayAfter || + else if (yrdays - tp->tm_yday + day <= offset + f_dayAfter || /* a year backward, eg. 6 Jan and 10 days before -> 27. Dec */ - tp->tm_yday + day - f_dayBefore < 0 - ) - return (1); - return (0); + tp->tm_yday + day - f_dayBefore < 0) + nummatches = 1; + + if (nummatches && flags & F_REPEAT) + /* Return number of matching days in range */ + return ((tp->tm_yday - day + offset + f_dayAfter + 7) / 7); + return (nummatches); +} + + +void +repeatweek(monthp, dayp) + int *monthp; + int *dayp; +{ + int days; + + days = *dayp + cumdays[*monthp] + 7; + if (days > cumdays[*monthp + 1]) { + if (*monthp == 12) { + *monthp = 1; + days -= yrdays; + } else + *monthp += 1; + } + *dayp = days - cumdays[*monthp]; } --- io.c.orig Thu May 23 00:26:52 2002 +++ io.c Thu May 23 23:03:10 2002 @@ -134,7 +134,7 @@ continue; } if (buf[0] != '\t') { - printing = isnow(buf, &month, &day, &var) ? 1 : 0; + printing = isnow(buf, &month, &day, &var); if ((p = strchr(buf, '\t')) == NULL) continue; if (p > buf && p[-1] == '*') @@ -144,19 +144,28 @@ char dbuf[80]; if (d_first < 0) - d_first = (*nl_langinfo(D_MD_ORDER) == 'd'); + d_first = + (*nl_langinfo(D_MD_ORDER) == 'd'); tm.tm_sec = 0; /* unused */ tm.tm_min = 0; /* unused */ tm.tm_hour = 0; /* unused */ tm.tm_wday = 0; /* unused */ - tm.tm_mon = month - 1; - tm.tm_mday = day; tm.tm_year = tp->tm_year; /* unused */ - (void)strftime(dbuf, sizeof(dbuf), - d_first ? "%e %b" : "%b %e", - &tm); - (void)fprintf(fp, "%s%c%s\n", dbuf, - var ? '*' : ' ', p); + for (;;) { + tm.tm_mon = month - 1; + tm.tm_mday = day; + /* Print additional date */ + (void)strftime(dbuf, sizeof(dbuf), + d_first ? "%e %b" : "%b %e", + &tm); + (void)fprintf(fp, "%s%c%s\n", dbuf, + var ? '*' : ' ', p); + printing--; + if (!printing) + break; + /* Increment by 1 week */ + repeatweek(&month, &day); + } } } else if (printing) -- Danny J. Zerkel dzerkel@columbus.rr.com To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200205240340.g4O3e3567202>