| #include <u.h> |
| #include <libc.h> |
| #include <bio.h> |
| |
| char dayw[] = |
| { |
| " S M Tu W Th F S" |
| }; |
| char *smon[] = |
| { |
| "January", "February", "March", "April", |
| "May", "June", "July", "August", |
| "September", "October", "November", "December", |
| }; |
| char mon[] = |
| { |
| 0, |
| 31, 29, 31, 30, |
| 31, 30, 31, 31, |
| 30, 31, 30, 31, |
| }; |
| char string[432]; |
| Biobuf bout; |
| |
| void main(int argc, char *argv[]); |
| int number(char *str); |
| void pstr(char *str, int n); |
| void cal(int m, int y, char *p, int w); |
| int jan1(int yr); |
| int curmo(void); |
| int curyr(void); |
| |
| void |
| main(int argc, char *argv[]) |
| { |
| int y, i, j, m; |
| |
| if(argc > 3) { |
| fprint(2, "usage: cal [month] [year]\n"); |
| exits("usage"); |
| } |
| Binit(&bout, 1, OWRITE); |
| |
| /* |
| * no arg, print current month |
| */ |
| if(argc == 1) { |
| m = curmo(); |
| y = curyr(); |
| goto xshort; |
| } |
| |
| /* |
| * one arg |
| * if looks like a month, print month |
| * else print year |
| */ |
| if(argc == 2) { |
| y = number(argv[1]); |
| if(y < 0) |
| y = -y; |
| if(y >= 1 && y <= 12) { |
| m = y; |
| y = curyr(); |
| goto xshort; |
| } |
| goto xlong; |
| } |
| |
| /* |
| * two arg, month and year |
| */ |
| m = number(argv[1]); |
| if(m < 0) |
| m = -m; |
| y = number(argv[2]); |
| goto xshort; |
| |
| /* |
| * print out just month |
| */ |
| xshort: |
| if(m < 1 || m > 12) |
| goto badarg; |
| if(y < 1 || y > 9999) |
| goto badarg; |
| Bprint(&bout, " %s %ud\n", smon[m-1], y); |
| Bprint(&bout, "%s\n", dayw); |
| cal(m, y, string, 24); |
| for(i=0; i<6*24; i+=24) |
| pstr(string+i, 24); |
| exits(0); |
| |
| /* |
| * print out complete year |
| */ |
| xlong: |
| y = number(argv[1]); |
| if(y<1 || y>9999) |
| goto badarg; |
| Bprint(&bout, "\n\n\n"); |
| Bprint(&bout, " %ud\n", y); |
| Bprint(&bout, "\n"); |
| for(i=0; i<12; i+=3) { |
| for(j=0; j<6*72; j++) |
| string[j] = '\0'; |
| Bprint(&bout, " %.3s", smon[i]); |
| Bprint(&bout, " %.3s", smon[i+1]); |
| Bprint(&bout, " %.3s\n", smon[i+2]); |
| Bprint(&bout, "%s %s %s\n", dayw, dayw, dayw); |
| cal(i+1, y, string, 72); |
| cal(i+2, y, string+23, 72); |
| cal(i+3, y, string+46, 72); |
| for(j=0; j<6*72; j+=72) |
| pstr(string+j, 72); |
| } |
| Bprint(&bout, "\n\n\n"); |
| exits(0); |
| |
| badarg: |
| Bprint(&bout, "cal: bad argument\n"); |
| } |
| |
| struct |
| { |
| char* word; |
| int val; |
| } dict[] = |
| { |
| "jan", 1, |
| "january", 1, |
| "feb", 2, |
| "february", 2, |
| "mar", 3, |
| "march", 3, |
| "apr", 4, |
| "april", 4, |
| "may", 5, |
| "jun", 6, |
| "june", 6, |
| "jul", 7, |
| "july", 7, |
| "aug", 8, |
| "august", 8, |
| "sep", 9, |
| "sept", 9, |
| "september", 9, |
| "oct", 10, |
| "october", 10, |
| "nov", 11, |
| "november", 11, |
| "dec", 12, |
| "december", 12, |
| 0 |
| }; |
| |
| /* |
| * convert to a number. |
| * if its a dictionary word, |
| * return negative number |
| */ |
| int |
| number(char *str) |
| { |
| int n, c; |
| char *s; |
| |
| for(n=0; s=dict[n].word; n++) |
| if(strcmp(s, str) == 0) |
| return -dict[n].val; |
| n = 0; |
| s = str; |
| while(c = *s++) { |
| if(c<'0' || c>'9') |
| return 0; |
| n = n*10 + c-'0'; |
| } |
| return n; |
| } |
| |
| void |
| pstr(char *str, int n) |
| { |
| int i; |
| char *s; |
| |
| s = str; |
| i = n; |
| while(i--) |
| if(*s++ == '\0') |
| s[-1] = ' '; |
| i = n+1; |
| while(i--) |
| if(*--s != ' ') |
| break; |
| s[1] = '\0'; |
| Bprint(&bout, "%s\n", str); |
| } |
| |
| void |
| cal(int m, int y, char *p, int w) |
| { |
| int d, i; |
| char *s; |
| |
| s = p; |
| d = jan1(y); |
| mon[2] = 29; |
| mon[9] = 30; |
| |
| switch((jan1(y+1)+7-d)%7) { |
| |
| /* |
| * non-leap year |
| */ |
| case 1: |
| mon[2] = 28; |
| break; |
| |
| /* |
| * 1752 |
| */ |
| default: |
| mon[9] = 19; |
| break; |
| |
| /* |
| * leap year |
| */ |
| case 2: |
| ; |
| } |
| for(i=1; i<m; i++) |
| d += mon[i]; |
| d %= 7; |
| s += 3*d; |
| for(i=1; i<=mon[m]; i++) { |
| if(i==3 && mon[m]==19) { |
| i += 11; |
| mon[m] += 11; |
| } |
| if(i > 9) |
| *s = i/10+'0'; |
| s++; |
| *s++ = i%10+'0'; |
| s++; |
| if(++d == 7) { |
| d = 0; |
| s = p+w; |
| p = s; |
| } |
| } |
| } |
| |
| /* |
| * return day of the week |
| * of jan 1 of given year |
| */ |
| int |
| jan1(int yr) |
| { |
| int y, d; |
| |
| /* |
| * normal gregorian calendar |
| * one extra day per four years |
| */ |
| |
| y = yr; |
| d = 4+y+(y+3)/4; |
| |
| /* |
| * julian calendar |
| * regular gregorian |
| * less three days per 400 |
| */ |
| |
| if(y > 1800) { |
| d -= (y-1701)/100; |
| d += (y-1601)/400; |
| } |
| |
| /* |
| * great calendar changeover instant |
| */ |
| |
| if(y > 1752) |
| d += 3; |
| |
| return d%7; |
| } |
| |
| /* |
| * system dependent |
| * get current month and year |
| */ |
| int |
| curmo(void) |
| { |
| Tm *tm; |
| |
| tm = localtime(time(0)); |
| return tm->mon+1; |
| } |
| |
| int |
| curyr(void) |
| { |
| Tm *tm; |
| |
| tm = localtime(time(0)); |
| return tm->year+1900; |
| } |