commit 0f523ec9c6c36a768a36eba39db223617772179c
parent 7f88cf7021dc4d221b77bb9359422ae988f8e4ee
Author: Jesse Ogle <jesse.p.ogle@gmail.com>
Date: Wed, 19 Jun 2013 14:13:50 -0400
Added cal and updated Makefile
Signed-off-by: Christoph Lohmann <20h@r-36.net>
Diffstat:
M | Makefile | | | 1 | + |
A | cal.1 | | | 42 | ++++++++++++++++++++++++++++++++++++++++++ |
A | cal.c | | | 147 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3 files changed, 190 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -21,6 +21,7 @@ LIB = \
SRC = \
basename.c \
+ cal.c \
cat.c \
chgrp.c \
chmod.c \
diff --git a/cal.1 b/cal.1
@@ -0,0 +1,42 @@
+.TH CAL 1 sbase\-VERSION
+.SH NAME
+cal \- print calendar
+.SH SYNOPSIS
+.B cal
+.RB [ \-c
+.IR columns ]
+.RB [ \-m
+.IR month ]
+.RB [ \-n
+.IR number ]
+.RB [ \-y
+.IR year ]
+.SH DESCRIPTION
+Beginning with
+.IR month
+and
+.IR year
+print
+.IR number
+of calendars side by side. Each row of calendars contains at most
+.IR columns
+number of calendars.
+.SH OPTIONS
+.TP
+.BI \-c " columns"
+print
+.IR columns
+number of calendars in a row. default is 3
+.TP
+.BI \-m " month"
+starting month. default is obtained from
+.IR localtime (3)
+.TP
+.BI \-n " number"
+number of calendars to print. default is 1
+.TP
+.BI \-y " year"
+starting year. default is obtained from
+.IR localtime (3)
+.SH SEE ALSO
+.IR localtime (3)
diff --git a/cal.c b/cal.c
@@ -0,0 +1,147 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include "util.h"
+
+#define MONTHMAX 100
+
+static void drawcal(int, int, int, int, int);
+static int dayofweek(int, int, int);
+static bool isleap(int);
+static void usage(void);
+
+static void
+drawcal(int year, int month, int day, int ncols, int nmons)
+{
+ char str[21];
+ int count[MONTHMAX];
+ int d, i, r;
+ int moff, yoff, cur, last, ndays, day1;
+ char *smon[]= {
+ " January", " February", " March",
+ " April", " May", " June",
+ " July", " August", " September",
+ " October", " November", " December" };
+ int mdays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ int row = 0;
+
+ while (nmons > 0) {
+ last = MIN(nmons, ncols);
+ for (i = 0; i < last; i++) {
+ moff = month + ncols * row + i - 1;
+ cur = moff % 12;
+ yoff = year + moff / 12;
+
+ sprintf(str, "%s %d", smon[cur], yoff);
+ printf("%-20s ", str);
+ count[i] = 1;
+ }
+ printf("\n");
+
+ for (i = 0; i < last; i++)
+ printf("Su M Tu W Th F Sa ");
+ printf("\n");
+
+ for (r = 0; r < 6; r++) {
+ for (i = 0; i < last; i++) {
+ moff = month + ncols * row + i - 1;
+ cur = moff % 12;
+ yoff = year + moff / 12;
+
+ ndays = mdays[cur] + ((cur == 1) & isleap(yoff));
+ day1 = dayofweek(year, cur, 1);
+
+ for (d = 0; d < 7; d++)
+ if ((r || d >= day1) && count[i] <= ndays)
+ printf("%2d ", count[i]++);
+ else
+ printf(" ");
+ printf(" ");
+ }
+ printf("\n");
+ }
+ nmons -= ncols;
+ row++;
+ }
+}
+
+static void
+defaults(int *year, int *month, int *day, int *ncols, int *nmons)
+{
+ time_t now;
+ struct tm *ltime;
+
+ now = time(NULL);
+ ltime = localtime(&now);
+ *year = ltime->tm_year + 1900;
+ *month = ltime->tm_mon + 1;
+ *day = ltime->tm_mday;
+
+ *ncols = 3;
+ *nmons = 1;
+}
+
+static int
+dayofweek(int year, int month, int day)
+{
+ int a, y, m;
+
+ month++;
+ a = (14 - month) / 12;
+ y = year + 4800 - a;
+ m = month + 12 * a -3;
+ return (day + (153 * m + 2) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 32045 + 1) % 7;
+}
+
+static bool
+isleap(int year)
+{
+ bool leap = false;
+
+ if (year % 4 == 0) leap = true;
+ if (year % 100 == 0) leap = false;
+ if (year % 400 == 0) leap = true;
+ return leap;
+}
+
+
+static void
+usage(void)
+{
+ eprintf("usage: %s [-c columns] [-m month] [-n number] [-y year]\n", argv0);
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int year, month, day, ncols, nmons;
+
+ defaults(&year, &month, &day, &ncols, &nmons);
+
+ ARGBEGIN {
+ case 'c':
+ ncols = (int) estrtol(EARGF(usage()), 0);
+ break;
+ case 'm':
+ month = (int) estrtol(EARGF(usage()), 0);
+ break;
+ case 'n':
+ nmons = (int) estrtol(EARGF(usage()), 0);
+ break;
+ case 'y':
+ year = (int) estrtol(EARGF(usage()), 0);
+ break;
+ default:
+ usage();
+ } ARGEND;
+
+ if (ncols < 0 || ncols > MONTHMAX || month < 1 || month > 12 || nmons < 1 || year > 9999)
+ usage();
+
+ drawcal(year, month, day, ncols, nmons);
+ exit(0);
+}
+