blob: 778c76082846beb54c16afe0d2b2249ac09a525d [file] [log] [blame]
rscbc7cb1a2003-11-23 18:04:47 +00001#include <u.h>
2#include <libc.h>
3#include <bio.h>
4#include <regexp.h>
5#include <ctype.h>
6
7typedef struct Date Date;
8struct Date {
9 Reprog *p; /* an RE to match this date */
10 Date *next; /* pointer to next in list */
11};
12
13enum{
14 Secondsperday = 24*60*60
15};
16
17Biobuf in;
18int debug, matchyear;
19
20Date *dates(Date**, Tm*);
21void upper2lower(char*, char*, int);
22void *alloc(unsigned int);
23
24void
25main(int argc, char *argv[])
26{
27 int i, fd, ahead;
28 long now;
29 char *line;
30 Tm *tm;
31 Date *first, *last, *d;
32 char buf[1024];
33
34 ahead = 0;
35 ARGBEGIN{
36 case 'y':
37 matchyear = 1;
38 break;
39 case 'd':
40 debug = 1;
41 break;
42 case 'p':
43 ahead = atoi(ARGF());
44 break;
45 default:
46 fprint(2, "usage: calendar [-y] [-d] [files ...]\n");
47 exits("usage");
48 }ARGEND;
49
50 /* make a list of dates */
51 now = time(0);
52 tm = localtime(now);
53 last = nil;
54 first = dates(&last, tm);
55 now += Secondsperday;
56 tm = localtime(now);
57 dates(&last, tm);
58 if(tm->wday == 6){
59 now += Secondsperday;
60 tm = localtime(now);
61 dates(&last, tm);
62 }
63 if(tm->wday == 0){
64 now += Secondsperday;
65 tm = localtime(now);
66 dates(&last, tm);
67 }
68 if(ahead){
69 now = time(0);
70 now += ahead * Secondsperday;
71 tm = localtime(now);
72 dates(&last, tm);
73 }
74
75 for(i=0; i<argc || (i==0 && argc==0); i++){
76 if(i==0 && argc==0)
77 snprint(buf, sizeof(buf),
rscc8b63422005-01-13 04:49:19 +000078 "%s/lib/calendar", getenv("HOME"));
rscbc7cb1a2003-11-23 18:04:47 +000079 else
80 strcpy(buf, argv[i]);
81 fd = open(buf, OREAD);
82 if(fd<0 || Binit(&in, fd, OREAD)<0){
83 fprint(2, "calendar: can't open %s: %r\n", buf);
84 exits("open");
85 }
86
87 /* go through the file */
88 while(line = Brdline(&in, '\n')){
89 line[Blinelen(&in) - 1] = 0;
90 upper2lower(buf, line, sizeof buf);
91 for(d=first; d; d=d->next)
92 if(regexec(d->p, buf, 0, 0)){
93 print("%s\n", line);
94 break;
95 }
96 }
97 close(fd);
98 }
99 exits("");
100}
101
102char *months[] =
103{
104 "january",
105 "february",
106 "march",
107 "april",
108 "may",
109 "june",
110 "july",
111 "august",
112 "september",
113 "october",
114 "november",
115 "december"
116};
117
118/*
119 * Generate two Date structures. First has month followed by day;
120 * second has day followed by month. Link them into list after
121 * last, and return the first.
122 */
123Date*
124dates(Date **last, Tm *tm)
125{
126 Date *first;
127 Date *nd;
128 char mo[128], buf[128];
129
130 if(utflen(months[tm->mon]) > 3)
131 snprint(mo, sizeof mo, "%3.3s(%s)?",
132 months[tm->mon], months[tm->mon]+3);
133 else
134 snprint(mo, sizeof mo, "%3.3s", months[tm->mon]);
135 if (matchyear)
136 snprint(buf, sizeof buf,
137 "(^| |\t)((%s( |\t)+)|(%d/))%d( |\t|$)(((%d|%d)( |\t|$))|[^0-9]|([0-9]+[^0-9 \t]))",
138 mo, tm->mon+1, tm->mday, tm->year+1900, tm->year%100);
139 else
140 snprint(buf, sizeof buf,
141 "(^| |\t)((%s( |\t)+)|(%d/))%d( |\t|$)",
142 mo, tm->mon+1, tm->mday);
143 if(debug)
144 print("%s\n", buf);
145
146 first = alloc(sizeof(Date));
147 if(*last)
148 (*last)->next = first;
149 first->p = regcomp(buf);
150
151 if (matchyear)
152 snprint(buf, sizeof buf,
153 "(^| |\t)%d( |\t)+(%s)( |\t|$)(((%d|%d)( |\t|$))|[^0-9]|([0-9]+[^0-9 \t]))",
154 tm->mday, mo, tm->year+1900, tm->year%100);
155 else
156 snprint(buf, sizeof buf,
157 "(^| |\t)%d( |\t)+(%s)( |\t|$)",
158 tm->mday, mo);
159 if(debug)
160 print("%s\n", buf);
161 nd = alloc(sizeof(Date));
162 nd->p = regcomp(buf);
163 nd->next = 0;
164 first->next = nd;
165 *last = nd;
166
167 return first;
168}
169
170/*
171 * Copy 'from' to 'to', converting to lower case
172 */
173void
174upper2lower(char *to, char *from, int len)
175{
176 while(--len>0 && *from!='\0')
rsc1c171e32005-07-19 18:00:07 +0000177 *to++ = tolower((uchar)*from++);
rscbc7cb1a2003-11-23 18:04:47 +0000178 *to = 0;
179}
180
181/*
182 * Call malloc and check for errors
183 */
184void*
185alloc(unsigned int n)
186{
187 void *p;
188
189 p = malloc(n);
190 if(p == 0){
191 fprint(2, "calendar: malloc failed: %r\n");
192 exits("malloc");
193 }
194 return p;
195}