123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- #include <u.h>
- #include <libc.h>
- #include <bio.h>
- #include <regexp.h>
- #include <ctype.h>
- typedef struct Date Date;
- struct Date {
- Reprog *p; /* an RE to match this date */
- Date *next; /* pointer to next in list */
- };
- enum{
- Secondsperday = 24*60*60
- };
- Biobuf in;
- int debug, matchyear;
- Date *dates(Date**, Tm*);
- void upper2lower(char*, char*, int);
- void *alloc(unsigned int);
- void
- main(int argc, char *argv[])
- {
- int i, fd, ahead;
- long now;
- char *line;
- Tm *tm;
- Date *first, *last, *d;
- char buf[1024];
- ahead = 0;
- ARGBEGIN{
- case 'y':
- matchyear = 1;
- break;
- case 'd':
- debug = 1;
- break;
- case 'p':
- ahead = atoi(ARGF());
- break;
- default:
- fprint(2, "usage: calendar [-y] [-d] [files ...]\n");
- exits("usage");
- }ARGEND;
- /* make a list of dates */
- now = time(0);
- tm = localtime(now);
- last = nil;
- first = dates(&last, tm);
- now += Secondsperday;
- tm = localtime(now);
- dates(&last, tm);
- if(tm->wday == 6){
- now += Secondsperday;
- tm = localtime(now);
- dates(&last, tm);
- }
- if(tm->wday == 0){
- now += Secondsperday;
- tm = localtime(now);
- dates(&last, tm);
- }
- if(ahead){
- now = time(0);
- now += ahead * Secondsperday;
- tm = localtime(now);
- dates(&last, tm);
- }
- for(i=0; i<argc || (i==0 && argc==0); i++){
- if(i==0 && argc==0)
- snprint(buf, sizeof(buf),
- "/usr/%s/lib/calendar", getuser());
- else
- strcpy(buf, argv[i]);
- fd = open(buf, OREAD);
- if(fd<0 || Binit(&in, fd, OREAD)<0){
- fprint(2, "calendar: can't open %s: %r\n", buf);
- exits("open");
- }
- /* go through the file */
- while(line = Brdline(&in, '\n')){
- line[Blinelen(&in) - 1] = 0;
- upper2lower(buf, line, sizeof buf);
- for(d=first; d; d=d->next)
- if(regexec(d->p, buf, 0, 0)){
- print("%s\n", line);
- break;
- }
- }
- close(fd);
- }
- exits("");
- }
- char *months[] =
- {
- "january",
- "february",
- "march",
- "april",
- "may",
- "june",
- "july",
- "august",
- "september",
- "october",
- "november",
- "december"
- };
- /*
- * 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)
- {
- Date *first;
- Date *nd;
- char mo[128], buf[128];
- if(utflen(months[tm->mon]) > 3)
- snprint(mo, sizeof mo, "%3.3s(%s)?",
- months[tm->mon], months[tm->mon]+3);
- else
- 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);
- else
- snprint(buf, sizeof buf,
- "(^| |\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);
- 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);
- else
- snprint(buf, sizeof buf,
- "(^| |\t)%d( |\t)+(%s)( |\t|$)",
- tm->mday, mo);
- if(debug)
- print("%s\n", buf);
- nd = alloc(sizeof(Date));
- nd->p = regcomp(buf);
- nd->next = 0;
- first->next = nd;
- *last = nd;
- return first;
- }
- /*
- * Copy 'from' to 'to', converting to lower case
- */
- void
- upper2lower(char *to, char *from, int len)
- {
- while(--len>0 && *from!='\0')
- *to++ = tolower(*from++);
- *to = 0;
- }
- /*
- * Call malloc and check for errors
- */
- void*
- alloc(unsigned int n)
- {
- void *p;
- p = malloc(n);
- if(p == 0){
- fprint(2, "calendar: malloc failed: %r\n");
- exits("malloc");
- }
- return p;
- }
|