=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/calendar/day.c,v retrieving revision 1.4 retrieving revision 1.6 diff -u -r1.4 -r1.6 --- src/usr.bin/calendar/day.c 1998/03/30 06:59:26 1.4 +++ src/usr.bin/calendar/day.c 1998/11/08 04:31:13 1.6 @@ -1,4 +1,4 @@ -/* $OpenBSD: day.c,v 1.4 1998/03/30 06:59:26 deraadt Exp $ */ +/* $OpenBSD: day.c,v 1.6 1998/11/08 04:31:13 pjanzen Exp $ */ /* * Copyright (c) 1989, 1993, 1994 @@ -43,7 +43,7 @@ #if 0 static const char sccsid[] = "@(#)calendar.c 8.3 (Berkeley) 3/25/94"; #else -static char rcsid[] = "$OpenBSD: day.c,v 1.4 1998/03/30 06:59:26 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: day.c,v 1.6 1998/11/08 04:31:13 pjanzen Exp $"; #endif #endif /* not lint */ @@ -183,7 +183,9 @@ return((time_t)-1); tm.tm_sec = 0; tm.tm_min = 0; - tm.tm_hour = 0; + /* Avoid getting caught by a timezone shift; set time to noon */ + tm.tm_isdst = 0; + tm.tm_hour = 12; tm.tm_wday = 0; tm.tm_mday = tp->tm_mday; tm.tm_mon = tp->tm_mon; @@ -199,12 +201,12 @@ } /* Year */ - if (len >= 7) { + if (len >= 6) { *(date + len - 4) = '\0'; tm.tm_year = atoi(date); /* tm_year up TM_YEAR_BASE ... */ - if (tm.tm_year < 70) + if (tm.tm_year < 69) /* Y2K */ tm.tm_year += 2000 - TM_YEAR_BASE; else if (tm.tm_year < 100) tm.tm_year += 1900 - TM_YEAR_BASE; @@ -229,14 +231,13 @@ * following a line that is matched, that starts with "whitespace", is shown * along with the matched line. */ -int -isnow(endp, monthp, dayp, varp) +struct match * +isnow(endp) char *endp; - int *monthp; - int *dayp; - int *varp; { int day, flags = 0, month = 0, v1, v2; + int monthp, dayp, varp; + struct match *matches; /* * CONVENTION @@ -251,7 +252,7 @@ /* read first field */ /* didn't recognize anything, skip it */ if (!(v1 = getfield(endp, &endp, &flags))) - return (0); + return (NULL); /* Easter or Easter depending days */ if (flags & F_EASTER) @@ -295,7 +296,7 @@ if (flags & F_ISMONTH) { day = v1; month = v2; - *varp = 0; + varp = 0; } /* {Month} {Weekday,Day} ... */ @@ -304,95 +305,95 @@ month = v1; /* if no recognizable day, assume the first */ day = v2 ? v2 : 1; - *varp = 0; + varp = 0; } } /* convert Weekday into *next* Day, * e.g.: 'Sunday' -> 22 - * 'SunayLast' -> ?? + * 'SundayLast' -> ?? */ if (flags & F_ISDAY) { #if DEBUG fprintf(stderr, "\nday: %d %s month %d\n", day, endp, month); #endif - *varp = 1; + varp = 1; /* variable weekday, SundayLast, MondayFirst ... */ if (day < 0 || day >= 10) { /* negative offset; last, -4 .. -1 */ if (day < 0) { v1 = day/10 - 1; /* offset -4 ... -1 */ - day = 10 + (day % 10); /* day 1 ... 7 */ + day = 10 + (day % 10); /* day 1 ... 7 */ - /* day, eg '22th' */ - v2 = tp->tm_mday + (((day - 1) - tp->tm_wday + 7) % 7); + /* which weekday the end of the month is (1-7) */ + v2 = (cumdays[month + 1] - tp->tm_yday + + tp->tm_wday + 371) % 7 + 1; - /* (month length - day) / 7 + 1 */ - if (((int)((cumdays[month+1] - - cumdays[month] - v2) / 7) + 1) == -v1) - /* bingo ! */ - day = v2; - - /* set to yesterday */ - else - day = tp->tm_mday - 1; + /* and subtract enough days */ + day = cumdays[month + 1] - cumdays[month] + + (v1 + 1) * 7 - (v2 - day + 7) % 7; +#if DEBUG + fprintf(stderr, "\nMonth %d ends on weekday %d\n", month, v2); +#endif } /* first, second ... +1 ... +5 */ else { - v1 = day/10; /* offset: +1 (first Sunday) ... */ + v1 = day/10; /* offset */ day = day % 10; - /* day, eg '22th' */ - v2 = tp->tm_mday + (((day - 1) - tp->tm_wday + 7) % 7); - - /* Hurrah! matched */ - if ( ((v2 - 1 + 7) / 7) == v1 ) - day = v2; - - /* set to yesterday */ - else - day = tp->tm_mday - 1; - } + /* which weekday the first of the month is */ + v2 = (cumdays[month] - tp->tm_yday + + tp->tm_wday + 372) % 7 + 1; + + /* and add enough days */ + day = 1 + (v1 - 1) * 7 + (day - v2 + 7) % 7; +#if DEBUG + fprintf(stderr, "\nMonth %d starts on weekday %d\n", month, v2); +#endif } - - /* wired */ - else { - day = tp->tm_mday + (((day - 1) - tp->tm_wday + 7) % 7); - *varp = 1; } + else + day = tp->tm_mday + (((day - 1) - tp->tm_wday + 7) % 7); } if (!(flags & F_EASTER)) { - *monthp = month; - *dayp = day; + monthp = month; + dayp = day; day = cumdays[month] + day; } else { for (v1 = 0; day > cumdays[v1]; v1++) ; - *monthp = v1 - 1; - *dayp = day - cumdays[v1 - 1]; - *varp = 1; + monthp = v1 - 1; + dayp = day - cumdays[v1 - 1]; + varp = 1; } #if DEBUG - fprintf(stderr, "day2: day %d(%d) yday %d\n", *dayp, day, tp->tm_yday); + fprintf(stderr, "day2: day %d(%d) yday %d\n", dayp, day, tp->tm_yday); #endif /* if today or today + offset days */ - if (day >= tp->tm_yday - f_dayBefore && - day <= tp->tm_yday + offset + f_dayAfter) - return (1); + if ((day >= tp->tm_yday - f_dayBefore && + day <= tp->tm_yday + offset + f_dayAfter) || /* if number of days left in this year + days to event in next year */ - if (yrdays - tp->tm_yday + day <= offset + f_dayAfter || + (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); + )) { + if ((matches = malloc(sizeof(struct match))) == NULL) + errx(1,"cannot allocate memory"); + matches->month = monthp; + matches->day = dayp; + matches->var = varp; + matches->year = tp->tm_year; /* XXX */ + matches->next = NULL; + return (matches); + } + return (NULL); }