Feature creap I guess, support for "every friday" and "the first wednesday" in calender for regular jargon-bingo sessions. Notes: Mon Dec 20 13:07:37 EST 2004 rsc maybe we can find a more general way to do this Reference: /n/sources/patch/applied/calendar Date: Tue Jan 4 17:09:10 CET 2005 Reviewed-by: rsc --- /sys/src/cmd/calendar.c Tue Jan 4 17:09:10 2005 +++ /sys/src/cmd/calendar.c Tue Jan 4 17:09:10 2005 @@ -14,12 +14,13 @@ Secondsperday = 24*60*60 }; +Date *Base = nil; Biobuf in; int debug, matchyear; -Date *dates(Date**, Tm*); +void dates(Tm*); void upper2lower(char*, char*, int); -void *alloc(unsigned int); +void *emalloc(unsigned int); void main(int argc, char *argv[]) @@ -28,7 +29,7 @@ long now; char *line; Tm *tm; - Date *first, *last, *d; + Date *d; char buf[1024]; ahead = 0; @@ -50,26 +51,25 @@ /* make a list of dates */ now = time(0); tm = localtime(now); - last = nil; - first = dates(&last, tm); + dates(tm); now += Secondsperday; tm = localtime(now); - dates(&last, tm); + dates(tm); if(tm->wday == 6){ now += Secondsperday; tm = localtime(now); - dates(&last, tm); + dates(tm); } if(tm->wday == 0){ now += Secondsperday; tm = localtime(now); - dates(&last, tm); + dates(tm); } if(ahead){ now = time(0); now += ahead * Secondsperday; tm = localtime(now); - dates(&last, tm); + dates(tm); } for(i=0; inext) + for(d=Base; d; d=d->next) if(regexec(d->p, buf, 0, 0)){ print("%s\n", line); break; @@ -114,18 +114,39 @@ "november", "december" }; +char *nth[] = { + "first", + "seccond", + "third", + "fourth", + "fifth" +}; +char *days[] = { + "sunday", + "monday", + "tuesday", + "wednesday", + "thursday", + "friday", + "saturday" +}; /* * Generate two Date structures. First has month followed by day; * second has day followed by month. Link them into list after * last, and return the first. */ -Date* -dates(Date **last, Tm *tm) +void +dates(Tm *tm) { - Date *first; Date *nd; - char mo[128], buf[128]; + char mo[128], day[128], buf[128]; + + if(utflen(days[tm->wday]) > 3) + snprint(day, sizeof day, "%3.3s(%s)?", + days[tm->wday], days[tm->wday]+3); + else + snprint(day, sizeof day, "%3.3s", days[tm->wday]); if(utflen(months[tm->mon]) > 3) snprint(mo, sizeof mo, "%3.3s(%s)?", @@ -134,37 +155,50 @@ snprint(mo, sizeof mo, "%3.3s", months[tm->mon]); if (matchyear) snprint(buf, sizeof buf, - "(^| |\t)((%s( |\t)+)|(%d/))%d( |\t|$)(((%d|%d)( |\t|$))|[^0-9]|([0-9]+[^0-9 \t]))", - mo, tm->mon+1, tm->mday, tm->year+1900, tm->year%100); + "^[\t ]*((%s( |\t)+)|(%d/))%d( |\t|$)(((%d|%d|%02d)( |\t|$))|[^0-9]|([0-9]+[^0-9 \t]))", + mo, tm->mon+1, tm->mday, tm->year+1900, tm->year%100, tm->year%100); else snprint(buf, sizeof buf, - "(^| |\t)((%s( |\t)+)|(%d/))%d( |\t|$)", + "^[\t ]*((%s( |\t)+)|(%d/))%d( |\t|$)", mo, tm->mon+1, tm->mday); if(debug) print("%s\n", buf); - first = alloc(sizeof(Date)); - if(*last) - (*last)->next = first; - first->p = regcomp(buf); + nd = emalloc(sizeof(Date)); + nd->p = regcomp(buf); + nd->next = Base; + Base = nd; if (matchyear) snprint(buf, sizeof buf, - "(^| |\t)%d( |\t)+(%s)( |\t|$)(((%d|%d)( |\t|$))|[^0-9]|([0-9]+[^0-9 \t]))", - tm->mday, mo, tm->year+1900, tm->year%100); + "^[\t ]*%d( |\t)+(%s)( |\t|$)(((%d|%d|%02d)( |\t|$))|[^0-9]|([0-9]+[^0-9 \t]))", + tm->mday, mo, tm->year+1900, tm->year%100, tm->year%100); else snprint(buf, sizeof buf, - "(^| |\t)%d( |\t)+(%s)( |\t|$)", + "^[\t ]*%d( |\t)+(%s)( |\t|$)", tm->mday, mo); if(debug) print("%s\n", buf); - nd = alloc(sizeof(Date)); + nd = emalloc(sizeof(Date)); + nd->p = regcomp(buf); + nd->next = Base; + Base = nd; + + snprint(buf, sizeof buf, "^[\t ]*every[ \t]+%s", day); + if(debug) + print("%s\n", buf); + nd = emalloc(sizeof(Date)); nd->p = regcomp(buf); - nd->next = 0; - first->next = nd; - *last = nd; + nd->next = Base; + Base = nd; - return first; + snprint(buf, sizeof buf, "[\t ]*the[\t ]+%s[\t ]+%s", nth[tm->mday/7], day); + if(debug) + print("%s\n", buf); + nd = emalloc(sizeof(Date)); + nd->p = regcomp(buf); + nd->next = Base; + Base = nd; } /* @@ -182,7 +216,7 @@ * Call malloc and check for errors */ void* -alloc(unsigned int n) +emalloc(unsigned int n) { void *p; --- /sys/man/1/calendar Tue Jan 4 17:09:10 2005 +++ /sys/man/1/calendar Tue Jan 4 17:09:10 2005 @@ -25,6 +25,10 @@ "11 April", and "11 Apr". +A special form may be used to represent weekly and +monthly events: +"Every Tuesday" +"The third Wednesday" All comparisons are case insensitive. .PP If the