xref: /original-bsd/usr.bin/cal/cal.c (revision 8583c8cb)
1 char	*sccsid = "@(#)cal.c	4.2 82/02/28";
2 char	dayw[] = {
3 	" S  M Tu  W Th  F  S"
4 };
5 char	*smon[]= {
6 	"January", "February", "March", "April",
7 	"May", "June", "July", "August",
8 	"September", "October", "November", "December",
9 };
10 char	string[432];
11 main(argc, argv)
12 char *argv[];
13 {
14 	register y, i, j;
15 	int m;
16 
17 	if(argc < 2) {
18 		printf("usage: cal [month] year\n");
19 		exit(0);
20 	}
21 	if(argc == 2)
22 		goto xlong;
23 
24 /*
25  *	print out just month
26  */
27 
28 	m = number(argv[1]);
29 	if(m<1 || m>12)
30 		goto badarg;
31 	y = number(argv[2]);
32 	if(y<1 || y>9999)
33 		goto badarg;
34 	printf("   %s %u\n", smon[m-1], y);
35 	printf("%s\n", dayw);
36 	cal(m, y, string, 24);
37 	for(i=0; i<6*24; i+=24)
38 		pstr(string+i, 24);
39 	exit(0);
40 
41 /*
42  *	print out complete year
43  */
44 
45 xlong:
46 	y = number(argv[1]);
47 	if(y<1 || y>9999)
48 		goto badarg;
49 	printf("\n\n\n");
50 	printf("				%u\n", y);
51 	printf("\n");
52 	for(i=0; i<12; i+=3) {
53 		for(j=0; j<6*72; j++)
54 			string[j] = '\0';
55 		printf("	 %.3s", smon[i]);
56 		printf("			%.3s", smon[i+1]);
57 		printf("		       %.3s\n", smon[i+2]);
58 		printf("%s   %s   %s\n", dayw, dayw, dayw);
59 		cal(i+1, y, string, 72);
60 		cal(i+2, y, string+23, 72);
61 		cal(i+3, y, string+46, 72);
62 		for(j=0; j<6*72; j+=72)
63 			pstr(string+j, 72);
64 	}
65 	printf("\n\n\n");
66 	exit(0);
67 
68 badarg:
69 	printf("Bad argument\n");
70 }
71 
72 number(str)
73 char *str;
74 {
75 	register n, c;
76 	register char *s;
77 
78 	n = 0;
79 	s = str;
80 	while(c = *s++) {
81 		if(c<'0' || c>'9')
82 			return(0);
83 		n = n*10 + c-'0';
84 	}
85 	return(n);
86 }
87 
88 pstr(str, n)
89 char *str;
90 {
91 	register i;
92 	register char *s;
93 
94 	s = str;
95 	i = n;
96 	while(i--)
97 		if(*s++ == '\0')
98 			s[-1] = ' ';
99 	i = n+1;
100 	while(i--)
101 		if(*--s != ' ')
102 			break;
103 	s[1] = '\0';
104 	printf("%s\n", str);
105 }
106 
107 char	mon[] = {
108 	0,
109 	31, 29, 31, 30,
110 	31, 30, 31, 31,
111 	30, 31, 30, 31,
112 };
113 
114 cal(m, y, p, w)
115 char *p;
116 {
117 	register d, i;
118 	register char *s;
119 
120 	s = p;
121 	d = jan1(y);
122 	mon[2] = 29;
123 	mon[9] = 30;
124 
125 	switch((jan1(y+1)+7-d)%7) {
126 
127 	/*
128 	 *	non-leap year
129 	 */
130 	case 1:
131 		mon[2] = 28;
132 		break;
133 
134 	/*
135 	 *	1752
136 	 */
137 	default:
138 		mon[9] = 19;
139 		break;
140 
141 	/*
142 	 *	leap year
143 	 */
144 	case 2:
145 		;
146 	}
147 	for(i=1; i<m; i++)
148 		d += mon[i];
149 	d %= 7;
150 	s += 3*d;
151 	for(i=1; i<=mon[m]; i++) {
152 		if(i==3 && mon[m]==19) {
153 			i += 11;
154 			mon[m] += 11;
155 		}
156 		if(i > 9)
157 			*s = i/10+'0';
158 		s++;
159 		*s++ = i%10+'0';
160 		s++;
161 		if(++d == 7) {
162 			d = 0;
163 			s = p+w;
164 			p = s;
165 		}
166 	}
167 }
168 
169 /*
170  *	return day of the week
171  *	of jan 1 of given year
172  */
173 
174 jan1(yr)
175 {
176 	register y, d;
177 
178 /*
179  *	normal gregorian calendar
180  *	one extra day per four years
181  */
182 
183 	y = yr;
184 	d = 4+y+(y+3)/4;
185 
186 /*
187  *	julian calendar
188  *	regular gregorian
189  *	less three days per 400
190  */
191 
192 	if(y > 1800) {
193 		d -= (y-1701)/100;
194 		d += (y-1601)/400;
195 	}
196 
197 /*
198  *	great calendar changeover instant
199  */
200 
201 	if(y > 1752)
202 		d += 3;
203 
204 	return(d%7);
205 }
206