Blame


1 bc7cb1a1 2003-11-23 devnull #include <u.h>
2 bc7cb1a1 2003-11-23 devnull #include <libc.h>
3 bc7cb1a1 2003-11-23 devnull #include <bio.h>
4 bc7cb1a1 2003-11-23 devnull
5 bc7cb1a1 2003-11-23 devnull char dayw[] =
6 bc7cb1a1 2003-11-23 devnull {
7 bc7cb1a1 2003-11-23 devnull " S M Tu W Th F S"
8 bc7cb1a1 2003-11-23 devnull };
9 bc7cb1a1 2003-11-23 devnull char *smon[] =
10 bc7cb1a1 2003-11-23 devnull {
11 bc7cb1a1 2003-11-23 devnull "January", "February", "March", "April",
12 bc7cb1a1 2003-11-23 devnull "May", "June", "July", "August",
13 bc7cb1a1 2003-11-23 devnull "September", "October", "November", "December",
14 bc7cb1a1 2003-11-23 devnull };
15 bc7cb1a1 2003-11-23 devnull char mon[] =
16 bc7cb1a1 2003-11-23 devnull {
17 bc7cb1a1 2003-11-23 devnull 0,
18 bc7cb1a1 2003-11-23 devnull 31, 29, 31, 30,
19 bc7cb1a1 2003-11-23 devnull 31, 30, 31, 31,
20 bc7cb1a1 2003-11-23 devnull 30, 31, 30, 31,
21 bc7cb1a1 2003-11-23 devnull };
22 bc7cb1a1 2003-11-23 devnull char string[432];
23 bc7cb1a1 2003-11-23 devnull Biobuf bout;
24 bc7cb1a1 2003-11-23 devnull
25 bc7cb1a1 2003-11-23 devnull void main(int argc, char *argv[]);
26 bc7cb1a1 2003-11-23 devnull int number(char *str);
27 bc7cb1a1 2003-11-23 devnull void pstr(char *str, int n);
28 bc7cb1a1 2003-11-23 devnull void cal(int m, int y, char *p, int w);
29 bc7cb1a1 2003-11-23 devnull int jan1(int yr);
30 bc7cb1a1 2003-11-23 devnull int curmo(void);
31 bc7cb1a1 2003-11-23 devnull int curyr(void);
32 bc7cb1a1 2003-11-23 devnull
33 bc7cb1a1 2003-11-23 devnull void
34 bc7cb1a1 2003-11-23 devnull main(int argc, char *argv[])
35 bc7cb1a1 2003-11-23 devnull {
36 bc7cb1a1 2003-11-23 devnull int y, i, j, m;
37 bc7cb1a1 2003-11-23 devnull
38 bc7cb1a1 2003-11-23 devnull if(argc > 3) {
39 bc7cb1a1 2003-11-23 devnull fprint(2, "usage: cal [month] [year]\n");
40 bc7cb1a1 2003-11-23 devnull exits("usage");
41 bc7cb1a1 2003-11-23 devnull }
42 bc7cb1a1 2003-11-23 devnull Binit(&bout, 1, OWRITE);
43 bc7cb1a1 2003-11-23 devnull
44 bc7cb1a1 2003-11-23 devnull /*
45 bc7cb1a1 2003-11-23 devnull * no arg, print current month
46 bc7cb1a1 2003-11-23 devnull */
47 bc7cb1a1 2003-11-23 devnull if(argc == 1) {
48 bc7cb1a1 2003-11-23 devnull m = curmo();
49 bc7cb1a1 2003-11-23 devnull y = curyr();
50 bc7cb1a1 2003-11-23 devnull goto xshort;
51 bc7cb1a1 2003-11-23 devnull }
52 bc7cb1a1 2003-11-23 devnull
53 bc7cb1a1 2003-11-23 devnull /*
54 bc7cb1a1 2003-11-23 devnull * one arg
55 bc7cb1a1 2003-11-23 devnull * if looks like a month, print month
56 bc7cb1a1 2003-11-23 devnull * else print year
57 bc7cb1a1 2003-11-23 devnull */
58 bc7cb1a1 2003-11-23 devnull if(argc == 2) {
59 bc7cb1a1 2003-11-23 devnull y = number(argv[1]);
60 bc7cb1a1 2003-11-23 devnull if(y < 0)
61 bc7cb1a1 2003-11-23 devnull y = -y;
62 bc7cb1a1 2003-11-23 devnull if(y >= 1 && y <= 12) {
63 bc7cb1a1 2003-11-23 devnull m = y;
64 bc7cb1a1 2003-11-23 devnull y = curyr();
65 bc7cb1a1 2003-11-23 devnull goto xshort;
66 bc7cb1a1 2003-11-23 devnull }
67 bc7cb1a1 2003-11-23 devnull goto xlong;
68 bc7cb1a1 2003-11-23 devnull }
69 bc7cb1a1 2003-11-23 devnull
70 bc7cb1a1 2003-11-23 devnull /*
71 bc7cb1a1 2003-11-23 devnull * two arg, month and year
72 bc7cb1a1 2003-11-23 devnull */
73 bc7cb1a1 2003-11-23 devnull m = number(argv[1]);
74 bc7cb1a1 2003-11-23 devnull if(m < 0)
75 bc7cb1a1 2003-11-23 devnull m = -m;
76 bc7cb1a1 2003-11-23 devnull y = number(argv[2]);
77 bc7cb1a1 2003-11-23 devnull goto xshort;
78 bc7cb1a1 2003-11-23 devnull
79 bc7cb1a1 2003-11-23 devnull /*
80 bc7cb1a1 2003-11-23 devnull * print out just month
81 bc7cb1a1 2003-11-23 devnull */
82 bc7cb1a1 2003-11-23 devnull xshort:
83 bc7cb1a1 2003-11-23 devnull if(m < 1 || m > 12)
84 bc7cb1a1 2003-11-23 devnull goto badarg;
85 bc7cb1a1 2003-11-23 devnull if(y < 1 || y > 9999)
86 bc7cb1a1 2003-11-23 devnull goto badarg;
87 bc7cb1a1 2003-11-23 devnull Bprint(&bout, " %s %ud\n", smon[m-1], y);
88 bc7cb1a1 2003-11-23 devnull Bprint(&bout, "%s\n", dayw);
89 bc7cb1a1 2003-11-23 devnull cal(m, y, string, 24);
90 bc7cb1a1 2003-11-23 devnull for(i=0; i<6*24; i+=24)
91 bc7cb1a1 2003-11-23 devnull pstr(string+i, 24);
92 bc7cb1a1 2003-11-23 devnull exits(0);
93 bc7cb1a1 2003-11-23 devnull
94 bc7cb1a1 2003-11-23 devnull /*
95 bc7cb1a1 2003-11-23 devnull * print out complete year
96 bc7cb1a1 2003-11-23 devnull */
97 bc7cb1a1 2003-11-23 devnull xlong:
98 bc7cb1a1 2003-11-23 devnull y = number(argv[1]);
99 bc7cb1a1 2003-11-23 devnull if(y<1 || y>9999)
100 bc7cb1a1 2003-11-23 devnull goto badarg;
101 bc7cb1a1 2003-11-23 devnull Bprint(&bout, "\n\n\n");
102 bc7cb1a1 2003-11-23 devnull Bprint(&bout, " %ud\n", y);
103 bc7cb1a1 2003-11-23 devnull Bprint(&bout, "\n");
104 bc7cb1a1 2003-11-23 devnull for(i=0; i<12; i+=3) {
105 bc7cb1a1 2003-11-23 devnull for(j=0; j<6*72; j++)
106 bc7cb1a1 2003-11-23 devnull string[j] = '\0';
107 bc7cb1a1 2003-11-23 devnull Bprint(&bout, " %.3s", smon[i]);
108 bc7cb1a1 2003-11-23 devnull Bprint(&bout, " %.3s", smon[i+1]);
109 bc7cb1a1 2003-11-23 devnull Bprint(&bout, " %.3s\n", smon[i+2]);
110 bc7cb1a1 2003-11-23 devnull Bprint(&bout, "%s %s %s\n", dayw, dayw, dayw);
111 bc7cb1a1 2003-11-23 devnull cal(i+1, y, string, 72);
112 bc7cb1a1 2003-11-23 devnull cal(i+2, y, string+23, 72);
113 bc7cb1a1 2003-11-23 devnull cal(i+3, y, string+46, 72);
114 bc7cb1a1 2003-11-23 devnull for(j=0; j<6*72; j+=72)
115 bc7cb1a1 2003-11-23 devnull pstr(string+j, 72);
116 bc7cb1a1 2003-11-23 devnull }
117 bc7cb1a1 2003-11-23 devnull Bprint(&bout, "\n\n\n");
118 bc7cb1a1 2003-11-23 devnull exits(0);
119 bc7cb1a1 2003-11-23 devnull
120 bc7cb1a1 2003-11-23 devnull badarg:
121 bc7cb1a1 2003-11-23 devnull Bprint(&bout, "cal: bad argument\n");
122 bc7cb1a1 2003-11-23 devnull }
123 bc7cb1a1 2003-11-23 devnull
124 bc7cb1a1 2003-11-23 devnull struct
125 bc7cb1a1 2003-11-23 devnull {
126 bc7cb1a1 2003-11-23 devnull char* word;
127 bc7cb1a1 2003-11-23 devnull int val;
128 bc7cb1a1 2003-11-23 devnull } dict[] =
129 bc7cb1a1 2003-11-23 devnull {
130 bc7cb1a1 2003-11-23 devnull "jan", 1,
131 bc7cb1a1 2003-11-23 devnull "january", 1,
132 bc7cb1a1 2003-11-23 devnull "feb", 2,
133 bc7cb1a1 2003-11-23 devnull "february", 2,
134 bc7cb1a1 2003-11-23 devnull "mar", 3,
135 bc7cb1a1 2003-11-23 devnull "march", 3,
136 bc7cb1a1 2003-11-23 devnull "apr", 4,
137 bc7cb1a1 2003-11-23 devnull "april", 4,
138 bc7cb1a1 2003-11-23 devnull "may", 5,
139 bc7cb1a1 2003-11-23 devnull "jun", 6,
140 bc7cb1a1 2003-11-23 devnull "june", 6,
141 bc7cb1a1 2003-11-23 devnull "jul", 7,
142 bc7cb1a1 2003-11-23 devnull "july", 7,
143 bc7cb1a1 2003-11-23 devnull "aug", 8,
144 bc7cb1a1 2003-11-23 devnull "august", 8,
145 bc7cb1a1 2003-11-23 devnull "sep", 9,
146 bc7cb1a1 2003-11-23 devnull "sept", 9,
147 bc7cb1a1 2003-11-23 devnull "september", 9,
148 bc7cb1a1 2003-11-23 devnull "oct", 10,
149 bc7cb1a1 2003-11-23 devnull "october", 10,
150 bc7cb1a1 2003-11-23 devnull "nov", 11,
151 bc7cb1a1 2003-11-23 devnull "november", 11,
152 bc7cb1a1 2003-11-23 devnull "dec", 12,
153 bc7cb1a1 2003-11-23 devnull "december", 12,
154 bc7cb1a1 2003-11-23 devnull 0
155 bc7cb1a1 2003-11-23 devnull };
156 bc7cb1a1 2003-11-23 devnull
157 bc7cb1a1 2003-11-23 devnull /*
158 bc7cb1a1 2003-11-23 devnull * convert to a number.
159 bc7cb1a1 2003-11-23 devnull * if its a dictionary word,
160 bc7cb1a1 2003-11-23 devnull * return negative number
161 bc7cb1a1 2003-11-23 devnull */
162 bc7cb1a1 2003-11-23 devnull int
163 bc7cb1a1 2003-11-23 devnull number(char *str)
164 bc7cb1a1 2003-11-23 devnull {
165 bc7cb1a1 2003-11-23 devnull int n, c;
166 bc7cb1a1 2003-11-23 devnull char *s;
167 bc7cb1a1 2003-11-23 devnull
168 bc7cb1a1 2003-11-23 devnull for(n=0; s=dict[n].word; n++)
169 bc7cb1a1 2003-11-23 devnull if(strcmp(s, str) == 0)
170 bc7cb1a1 2003-11-23 devnull return -dict[n].val;
171 bc7cb1a1 2003-11-23 devnull n = 0;
172 bc7cb1a1 2003-11-23 devnull s = str;
173 bc7cb1a1 2003-11-23 devnull while(c = *s++) {
174 bc7cb1a1 2003-11-23 devnull if(c<'0' || c>'9')
175 bc7cb1a1 2003-11-23 devnull return 0;
176 bc7cb1a1 2003-11-23 devnull n = n*10 + c-'0';
177 bc7cb1a1 2003-11-23 devnull }
178 bc7cb1a1 2003-11-23 devnull return n;
179 bc7cb1a1 2003-11-23 devnull }
180 bc7cb1a1 2003-11-23 devnull
181 bc7cb1a1 2003-11-23 devnull void
182 bc7cb1a1 2003-11-23 devnull pstr(char *str, int n)
183 bc7cb1a1 2003-11-23 devnull {
184 bc7cb1a1 2003-11-23 devnull int i;
185 bc7cb1a1 2003-11-23 devnull char *s;
186 bc7cb1a1 2003-11-23 devnull
187 bc7cb1a1 2003-11-23 devnull s = str;
188 bc7cb1a1 2003-11-23 devnull i = n;
189 bc7cb1a1 2003-11-23 devnull while(i--)
190 bc7cb1a1 2003-11-23 devnull if(*s++ == '\0')
191 bc7cb1a1 2003-11-23 devnull s[-1] = ' ';
192 bc7cb1a1 2003-11-23 devnull i = n+1;
193 bc7cb1a1 2003-11-23 devnull while(i--)
194 bc7cb1a1 2003-11-23 devnull if(*--s != ' ')
195 bc7cb1a1 2003-11-23 devnull break;
196 bc7cb1a1 2003-11-23 devnull s[1] = '\0';
197 bc7cb1a1 2003-11-23 devnull Bprint(&bout, "%s\n", str);
198 bc7cb1a1 2003-11-23 devnull }
199 bc7cb1a1 2003-11-23 devnull
200 bc7cb1a1 2003-11-23 devnull void
201 bc7cb1a1 2003-11-23 devnull cal(int m, int y, char *p, int w)
202 bc7cb1a1 2003-11-23 devnull {
203 bc7cb1a1 2003-11-23 devnull int d, i;
204 bc7cb1a1 2003-11-23 devnull char *s;
205 bc7cb1a1 2003-11-23 devnull
206 bc7cb1a1 2003-11-23 devnull s = p;
207 bc7cb1a1 2003-11-23 devnull d = jan1(y);
208 bc7cb1a1 2003-11-23 devnull mon[2] = 29;
209 bc7cb1a1 2003-11-23 devnull mon[9] = 30;
210 bc7cb1a1 2003-11-23 devnull
211 bc7cb1a1 2003-11-23 devnull switch((jan1(y+1)+7-d)%7) {
212 bc7cb1a1 2003-11-23 devnull
213 bc7cb1a1 2003-11-23 devnull /*
214 bc7cb1a1 2003-11-23 devnull * non-leap year
215 bc7cb1a1 2003-11-23 devnull */
216 bc7cb1a1 2003-11-23 devnull case 1:
217 bc7cb1a1 2003-11-23 devnull mon[2] = 28;
218 bc7cb1a1 2003-11-23 devnull break;
219 bc7cb1a1 2003-11-23 devnull
220 bc7cb1a1 2003-11-23 devnull /*
221 bc7cb1a1 2003-11-23 devnull * 1752
222 bc7cb1a1 2003-11-23 devnull */
223 bc7cb1a1 2003-11-23 devnull default:
224 bc7cb1a1 2003-11-23 devnull mon[9] = 19;
225 bc7cb1a1 2003-11-23 devnull break;
226 bc7cb1a1 2003-11-23 devnull
227 bc7cb1a1 2003-11-23 devnull /*
228 bc7cb1a1 2003-11-23 devnull * leap year
229 bc7cb1a1 2003-11-23 devnull */
230 bc7cb1a1 2003-11-23 devnull case 2:
231 bc7cb1a1 2003-11-23 devnull ;
232 bc7cb1a1 2003-11-23 devnull }
233 bc7cb1a1 2003-11-23 devnull for(i=1; i<m; i++)
234 bc7cb1a1 2003-11-23 devnull d += mon[i];
235 bc7cb1a1 2003-11-23 devnull d %= 7;
236 bc7cb1a1 2003-11-23 devnull s += 3*d;
237 bc7cb1a1 2003-11-23 devnull for(i=1; i<=mon[m]; i++) {
238 bc7cb1a1 2003-11-23 devnull if(i==3 && mon[m]==19) {
239 bc7cb1a1 2003-11-23 devnull i += 11;
240 bc7cb1a1 2003-11-23 devnull mon[m] += 11;
241 bc7cb1a1 2003-11-23 devnull }
242 bc7cb1a1 2003-11-23 devnull if(i > 9)
243 bc7cb1a1 2003-11-23 devnull *s = i/10+'0';
244 bc7cb1a1 2003-11-23 devnull s++;
245 bc7cb1a1 2003-11-23 devnull *s++ = i%10+'0';
246 bc7cb1a1 2003-11-23 devnull s++;
247 bc7cb1a1 2003-11-23 devnull if(++d == 7) {
248 bc7cb1a1 2003-11-23 devnull d = 0;
249 bc7cb1a1 2003-11-23 devnull s = p+w;
250 bc7cb1a1 2003-11-23 devnull p = s;
251 bc7cb1a1 2003-11-23 devnull }
252 bc7cb1a1 2003-11-23 devnull }
253 bc7cb1a1 2003-11-23 devnull }
254 bc7cb1a1 2003-11-23 devnull
255 bc7cb1a1 2003-11-23 devnull /*
256 bc7cb1a1 2003-11-23 devnull * return day of the week
257 bc7cb1a1 2003-11-23 devnull * of jan 1 of given year
258 bc7cb1a1 2003-11-23 devnull */
259 bc7cb1a1 2003-11-23 devnull int
260 bc7cb1a1 2003-11-23 devnull jan1(int yr)
261 bc7cb1a1 2003-11-23 devnull {
262 bc7cb1a1 2003-11-23 devnull int y, d;
263 bc7cb1a1 2003-11-23 devnull
264 bc7cb1a1 2003-11-23 devnull /*
265 bc7cb1a1 2003-11-23 devnull * normal gregorian calendar
266 bc7cb1a1 2003-11-23 devnull * one extra day per four years
267 bc7cb1a1 2003-11-23 devnull */
268 bc7cb1a1 2003-11-23 devnull
269 bc7cb1a1 2003-11-23 devnull y = yr;
270 bc7cb1a1 2003-11-23 devnull d = 4+y+(y+3)/4;
271 bc7cb1a1 2003-11-23 devnull
272 bc7cb1a1 2003-11-23 devnull /*
273 bc7cb1a1 2003-11-23 devnull * julian calendar
274 bc7cb1a1 2003-11-23 devnull * regular gregorian
275 bc7cb1a1 2003-11-23 devnull * less three days per 400
276 bc7cb1a1 2003-11-23 devnull */
277 bc7cb1a1 2003-11-23 devnull
278 bc7cb1a1 2003-11-23 devnull if(y > 1800) {
279 bc7cb1a1 2003-11-23 devnull d -= (y-1701)/100;
280 bc7cb1a1 2003-11-23 devnull d += (y-1601)/400;
281 bc7cb1a1 2003-11-23 devnull }
282 bc7cb1a1 2003-11-23 devnull
283 bc7cb1a1 2003-11-23 devnull /*
284 bc7cb1a1 2003-11-23 devnull * great calendar changeover instant
285 bc7cb1a1 2003-11-23 devnull */
286 bc7cb1a1 2003-11-23 devnull
287 bc7cb1a1 2003-11-23 devnull if(y > 1752)
288 bc7cb1a1 2003-11-23 devnull d += 3;
289 bc7cb1a1 2003-11-23 devnull
290 bc7cb1a1 2003-11-23 devnull return d%7;
291 bc7cb1a1 2003-11-23 devnull }
292 bc7cb1a1 2003-11-23 devnull
293 bc7cb1a1 2003-11-23 devnull /*
294 bc7cb1a1 2003-11-23 devnull * system dependent
295 bc7cb1a1 2003-11-23 devnull * get current month and year
296 bc7cb1a1 2003-11-23 devnull */
297 bc7cb1a1 2003-11-23 devnull int
298 bc7cb1a1 2003-11-23 devnull curmo(void)
299 bc7cb1a1 2003-11-23 devnull {
300 bc7cb1a1 2003-11-23 devnull Tm *tm;
301 bc7cb1a1 2003-11-23 devnull
302 bc7cb1a1 2003-11-23 devnull tm = localtime(time(0));
303 bc7cb1a1 2003-11-23 devnull return tm->mon+1;
304 bc7cb1a1 2003-11-23 devnull }
305 bc7cb1a1 2003-11-23 devnull
306 bc7cb1a1 2003-11-23 devnull int
307 bc7cb1a1 2003-11-23 devnull curyr(void)
308 bc7cb1a1 2003-11-23 devnull {
309 bc7cb1a1 2003-11-23 devnull Tm *tm;
310 bc7cb1a1 2003-11-23 devnull
311 bc7cb1a1 2003-11-23 devnull tm = localtime(time(0));
312 bc7cb1a1 2003-11-23 devnull return tm->year+1900;
313 bc7cb1a1 2003-11-23 devnull }