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