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>
