Skip site navigation (1)Skip section navigation (2)
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>