aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/cal.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2003-11-23 18:04:47 +0000
committerrsc <devnull@localhost>2003-11-23 18:04:47 +0000
commitbc7cb1a15a67c859c8c71c4b52bb35fe9425a63d (patch)
tree8ca0fe4e2418e6aa18dc74a236c577a719f6c6ed /src/cmd/cal.c
parentf08fdedcee12c06e3ce9ac9bec363915978e8289 (diff)
downloadplan9port-bc7cb1a15a67c859c8c71c4b52bb35fe9425a63d.tar.gz
plan9port-bc7cb1a15a67c859c8c71c4b52bb35fe9425a63d.tar.bz2
plan9port-bc7cb1a15a67c859c8c71c4b52bb35fe9425a63d.zip
new utilities.
the .C files compile but are renamed to avoid building automatically.
Diffstat (limited to 'src/cmd/cal.c')
-rw-r--r--src/cmd/cal.c313
1 files changed, 313 insertions, 0 deletions
diff --git a/src/cmd/cal.c b/src/cmd/cal.c
new file mode 100644
index 00000000..113069b6
--- /dev/null
+++ b/src/cmd/cal.c
@@ -0,0 +1,313 @@
+#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;
+}