xref: /plan9-contrib/sys/src/cmd/calendar.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <regexp.h>
5 #include <ctype.h>
6 
7 typedef struct Date	Date;
8 struct Date {
9 	Reprog *p;
10 	Date *next;
11 };
12 
13 Biobuf in;
14 int debug;
15 
16 Date *dates(Date**, Tm*);
17 void upper2lower(char*, char*, int);
18 
19 void
20 main(int argc, char *argv[])
21 {
22 	int fd;
23 	long now;
24 	char *line;
25 	Tm *tm;
26 	Date *first, *last, *d;
27 	char buf[1024];
28 
29 	ARGBEGIN{
30 	case 'd':
31 		debug = 1;
32 		break;
33 	}ARGEND;
34 
35 	if(argv[0])
36 		strcpy(buf, argv[0]);
37 	else
38 		snprint(buf, sizeof(buf), "/usr/%s/lib/calendar", getuser());
39 	fd = open(buf, OREAD);
40 	if(fd < 0){
41 		fprint(2, "calendar: can't open %s: %r\n", buf);
42 		exits("open");
43 	}
44 	Binit(&in, fd, OREAD);
45 
46 	/* make a list of dates */
47 	now = time(0);
48 	tm = localtime(now);
49 	first = dates(&last, tm);
50 	tm = localtime(now+24*60*60);
51 	dates(&last, tm);
52 	if(tm->wday == 6){
53 		tm = localtime(now+2*24*60*60);
54 		dates(&last, tm);
55 	}
56 	if(tm->wday == 0){
57 		tm = localtime(now+3*24*60*60);
58 		dates(&last, tm);
59 	}
60 
61 	/* go through the file */
62 	while(line = Brdline(&in, '\n')){
63 		line[Blinelen(&in) - 1] = 0;
64 		upper2lower(line, buf, sizeof buf);
65 		for(d = first; d; d = d->next)
66 			if(regexec(d->p, buf, 0, 0)){
67 				print("%s\n", line);
68 				break;
69 			}
70 	}
71 	exits(0);
72 }
73 
74 char *months[] =
75 {
76 	"january",
77 	"february",
78 	"march",
79 	"april",
80 	"may",
81 	"june",
82 	"july",
83 	"august",
84 	"september",
85 	"october",
86 	"november",
87 	"december"
88 };
89 
90 Date*
91 dates(Date **last, Tm *tm)
92 {
93 	Date *first;
94 	Date *nd;
95 	char mo[128], buf[128];
96 
97 	if(strlen(months[tm->mon]) > 3)
98 		sprint(mo, "%3.3s(%s)?",
99 			months[tm->mon], months[tm->mon]+3);
100 	else
101 		sprint(mo, "%3.3s", months[tm->mon]);
102 	snprint(buf, sizeof buf, "(^| |\t)((%s( |\t)+)|(%d/))%d( |\t|$)", mo, tm->mon+1, tm->mday);
103 	if(debug)
104 		print("%s\n", buf);
105 	first = malloc(sizeof(Date));
106 	if(first == 0){
107 		fprint(2, "calendar: out of memory\n");
108 		exits("memory");
109 	}
110 	if(*last)
111 		(*last)->next = first;
112 	first->p = regcomp(buf);
113 
114 	snprint(buf, sizeof buf, "(^| |\t)%d( |\t)+(%s)( |\t|$)",
115 		tm->mday, mo);
116 	if(debug)
117 		print("%s\n", buf);
118 	nd = malloc(sizeof(Date));
119 	if(nd == 0){
120 		fprint(2, "calendar: out of memory\n");
121 		exits("memory");
122 	}
123 	nd->p = regcomp(buf);
124 	nd->next = 0;
125 	first->next = nd;
126 	*last = nd;
127 
128 	return first;
129 }
130 
131 void
132 upper2lower(char *from, char *to, int len)
133 {
134 	int c;
135 
136 	while(--len > 0){
137 		c = *to++ = tolower(*from++);
138 		if(c == 0)
139 			return;
140 	}
141 	*to = 0;
142 }
143